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
22 changed files with 495 additions and 732 deletions

View File

@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.16)
project(KImageFormats)
include(FeatureSummary)
find_package(ECM 5.106.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")
feature_summary(WHAT REQUIRED_PACKAGES_NOT_FOUND FATAL_ON_MISSING_REQUIRED_PACKAGES)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 983 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 189 KiB

After

Width:  |  Height:  |  Size: 189 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 114 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.

View File

@ -159,22 +159,17 @@ int main(int argc, char **argv)
QTextStream(stdout) << "* Run on RANDOM ACCESS device\n";
}
for (const QFileInfo &fi : lstImgDir) {
if (!fi.suffix().compare("png", Qt::CaseInsensitive) || !fi.suffix().compare("tif", Qt::CaseInsensitive)) {
if (!fi.suffix().compare("png", Qt::CaseInsensitive)) {
continue;
}
int suffixPos = fi.filePath().count() - suffix.count();
QString inputfile = fi.filePath();
QString fmt = QStringLiteral("png");
QString expfile = fi.filePath().replace(suffixPos, suffix.count(), fmt);
if (!QFile::exists(expfile)) { // try with tiff
fmt = QStringLiteral("tif");
expfile = fi.filePath().replace(suffixPos, suffix.count(), fmt);
}
QString expfile = fi.filePath().replace(suffixPos, suffix.count(), QStringLiteral("png"));
QString expfilename = QFileInfo(expfile).fileName();
std::unique_ptr<QIODevice> inputDevice(seq ? new SequentialFile(inputfile) : new QFile(inputfile));
QImageReader inputReader(inputDevice.get(), format);
QImageReader expReader(expfile, fmt.toLatin1());
QImageReader expReader(expfile, "png");
QImage inputImage;
QImage expImage;

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)
kimageformats_add_plugin(kimg_heif SOURCES heif.cpp)
target_link_libraries(kimg_heif PkgConfig::LibHeif)
kde_target_enable_exceptions(kimg_heif PRIVATE)
if (QT_MAJOR_VERSION STREQUAL "5")
install(FILES heif.desktop DESTINATION ${KDE_INSTALL_KSERVICESDIR}/qimageioplugins/)

View File

@ -63,7 +63,7 @@ bool QAVIFHandler::canRead(QIODevice *device)
}
avifROData input;
input.data = reinterpret_cast<const uint8_t *>(header.constData());
input.data = (const uint8_t *)header.constData();
input.size = header.size();
if (avifPeekCompatibleFileType(&input)) {
@ -116,7 +116,7 @@ bool QAVIFHandler::ensureDecoder()
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();
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
{
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") {
Capabilities format_cap;
if (isAvifDecoderAvailable) {
format_cap |= CanRead;
}
if (isAvifEncoderAvailable) {
format_cap |= CanWrite;
}
return format_cap;
return Capabilities(CanRead | CanWrite);
}
if (format == "avifs") {
Capabilities format_cap;
if (isAvifDecoderAvailable) {
format_cap |= CanRead;
}
return format_cap;
return Capabilities(CanRead);
}
if (!format.isEmpty()) {
@ -1087,10 +1073,10 @@ QImageIOPlugin::Capabilities QAVIFPlugin::capabilities(QIODevice *device, const
}
Capabilities cap;
if (device->isReadable() && QAVIFHandler::canRead(device) && isAvifDecoderAvailable) {
if (device->isReadable() && QAVIFHandler::canRead(device)) {
cap |= CanRead;
}
if (device->isWritable() && isAvifEncoderAvailable) {
if (device->isWritable()) {
cap |= CanWrite;
}
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,14 +3,14 @@
SPDX-FileCopyrightText: 2003 Ignacio Castaño <castano@ludicon.com>
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
*/
/*
* The early version of this code was based on Thacher Ulrich PSD loading code
* released into the public domain. See: http://tulrich.com/geekstuff/
* This code is based on Thacher Ulrich PSD loading code released
* into the public domain. See: http://tulrich.com/geekstuff/
*/
/*
@ -21,6 +21,7 @@
/*
* Limitations of the current code:
* - 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
* color spaces other than RGB (and Grayscale). Where possible, a conversion
* to RGB is done:
@ -32,7 +33,6 @@
* color management engine (e.g. LittleCMS).
*/
#include "fastmath_p.h"
#include "psd_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
* 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.
*
* 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.
static bool IsSupported(const PSDHeader &header)
{
if (!IsValid(header)) {
return false;
}
if (header.version != 1 && header.version != 2) {
return false;
}
@ -663,15 +660,10 @@ static bool IsSupported(const PSDHeader &header)
header.color_mode != CM_INDEXED &&
header.color_mode != CM_DUOTONE &&
header.color_mode != CM_CMYK &&
header.color_mode != CM_MULTICHANNEL &&
header.color_mode != CM_LABCOLOR &&
header.color_mode != CM_BITMAP) {
return false;
}
if (header.color_mode == CM_MULTICHANNEL &&
header.channel_count < 4) {
return false;
}
return true;
}
@ -733,18 +725,17 @@ static QImage::Format imageFormat(const PSDHeader &header, bool alpha)
switch(header.color_mode) {
case CM_RGB:
if (header.depth == 16 || header.depth == 32)
format = header.channel_count < 4 || !alpha ? QImage::Format_RGBX64 : QImage::Format_RGBA64_Premultiplied;
format = header.channel_count < 4 || !alpha ? QImage::Format_RGBX64 : QImage::Format_RGBA64;
else
format = header.channel_count < 4 || !alpha ? QImage::Format_RGB888 : QImage::Format_RGBA8888_Premultiplied;
format = header.channel_count < 4 || !alpha ? QImage::Format_RGB888 : QImage::Format_RGBA8888;
break;
case CM_MULTICHANNEL: // Treat MCH as CMYK (number of channel check is done in IsSupported())
case CM_CMYK: // Photoshop supports CMYK/MCH 8-bits and 16-bits only
case CM_CMYK: // Photoshop supports CMYK 8-bits and 16-bits only
if (header.depth == 16)
format = header.channel_count < 5 || !alpha ? QImage::Format_RGBX64 : QImage::Format_RGBA64;
else if (header.depth == 8)
format = header.channel_count < 5 || !alpha ? QImage::Format_RGB888 : QImage::Format_RGBA8888;
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)
format = header.channel_count < 4 || !alpha ? QImage::Format_RGBX64 : QImage::Format_RGBA64;
else if (header.depth == 8)
@ -814,7 +805,7 @@ inline void planarToChunchy(uchar *target, const char *source, qint32 width, qin
auto s = reinterpret_cast<const T*>(source);
auto t = reinterpret_cast<T*>(target);
for (qint32 x = 0; x < width; ++x) {
t[x * cn + c] = xchg(s[x]);
t[x*cn+c] = xchg(s[x]);
}
}
@ -826,44 +817,7 @@ inline void planarToChunchyFloat(uchar *target, const char *source, qint32 width
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())));
}
}
enum class PremulConversion {
PS2P, // Photoshop premul to qimage premul (required by RGB)
PS2A, // Photoshop premul to unassociated alpha (required by RGB, CMYK and L* components of LAB)
PSLab2A // Photoshop premul to unassociated alpha (required by a* and b* components of LAB)
};
template<class T>
inline void premulConversion(char *stride, qint32 width, qint32 ac, qint32 cn, const PremulConversion &conv)
{
auto s = reinterpret_cast<T *>(stride);
auto max = qint64(std::numeric_limits<T>::max());
for (qint32 c = 0; c < ac; ++c) {
if (conv == PremulConversion::PS2P) {
for (qint32 x = 0; x < width; ++x) {
auto xcn = x * cn;
auto alpha = *(s + xcn + ac);
*(s + xcn + c) = *(s + xcn + c) + alpha - max;
}
} else if (conv == PremulConversion::PS2A || (conv == PremulConversion::PSLab2A && c == 0)) {
for (qint32 x = 0; x < width; ++x) {
auto xcn = x * cn;
auto alpha = *(s + xcn + ac);
if (alpha > 0)
*(s + xcn + c) = ((*(s + xcn + c) + alpha - max) * max + alpha / 2) / alpha;
}
} else if (conv == PremulConversion::PSLab2A) {
for (qint32 x = 0; x < width; ++x) {
auto xcn = x * cn;
auto alpha = *(s + xcn + ac);
if (alpha > 0)
*(s + xcn + c) = ((*(s + xcn + c) + (alpha - max + 1) / 2) * max + alpha / 2) / alpha;
}
}
t[x*cn+c] = quint16(std::min(ftmp * std::numeric_limits<quint16>::max() + 0.5, double(std::numeric_limits<quint16>::max())));
}
}
@ -876,25 +830,12 @@ inline void monoInvert(uchar *target, const char* source, qint32 bytes)
}
}
template<class T>
inline void rawChannelsCopy(uchar *target, qint32 targetChannels, const char *source, qint32 sourceChannels, qint32 width)
{
auto s = reinterpret_cast<const T *>(source);
auto t = reinterpret_cast<T *>(target);
for (qint32 c = 0, cs = std::min(targetChannels, sourceChannels); c < cs; ++c) {
for (qint32 x = 0; x < width; ++x) {
t[x * targetChannels + c] = s[x * sourceChannels + c];
}
}
}
template<class T>
inline void cmykToRgb(uchar *target, qint32 targetChannels, const char *source, qint32 sourceChannels, qint32 width, bool alpha = false)
{
auto s = reinterpret_cast<const T*>(source);
auto t = reinterpret_cast<T*>(target);
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!";
@ -903,10 +844,10 @@ inline void cmykToRgb(uchar *target, qint32 targetChannels, const char *source,
for (qint32 w = 0; w < width; ++w) {
auto ps = s + sourceChannels * w;
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 C = 1 - *(ps + 0) / max;
auto M = 1 - *(ps + 1) / max;
auto Y = 1 - *(ps + 2) / max;
auto K = 1 - *(ps + 3) / max;
auto pt = t + targetChannels * w;
*(pt + 0) = T(std::min(max - (C * (1 - K) + K) * max + 0.5, max));
@ -931,9 +872,8 @@ inline double gammaCorrection(double linear)
#ifdef PSD_FAST_LAB_CONVERSION
return linear;
#else
// Replacing fastPow with std::pow the conversion time is 2/3 times longer: using fastPow
// there are minimal differences in the conversion that are not visually noticeable.
return (linear > 0.0031308 ? 1.055 * fastPow(linear, 1.0 / 2.4) - 0.055 : 12.92 * linear);
// NOTE: pow() slow down the performance by a 4 factor :(
return (linear > 0.0031308 ? 1.055 * std::pow(linear, 1.0 / 2.4) - 0.055 : 12.92 * linear);
#endif
}
@ -943,7 +883,6 @@ inline void labToRgb(uchar *target, qint32 targetChannels, const char *source, q
auto s = reinterpret_cast<const T*>(source);
auto t = reinterpret_cast<T*>(target);
auto max = double(std::numeric_limits<T>::max());
auto invmax = 1.0 / max;
if (sourceChannels < 3) {
qDebug() << "labToRgb: image is not a valid LAB!";
@ -952,14 +891,14 @@ inline void labToRgb(uchar *target, qint32 targetChannels, const char *source, q
for (qint32 w = 0; w < width; ++w) {
auto ps = s + sourceChannels * w;
auto L = (*(ps + 0) * invmax) * 100.0;
auto A = (*(ps + 1) * invmax) * 255.0 - 128.0;
auto B = (*(ps + 2) * invmax) * 255.0 - 128.0;
auto L = (*(ps + 0) / max) * 100.0;
auto A = (*(ps + 1) / max) * 255.0 - 128.0;
auto B = (*(ps + 2) / max) * 255.0 - 128.0;
// converting LAB to XYZ (D65 illuminant)
auto Y = (L + 16.0) * (1.0 / 116.0);
auto X = A * (1.0 / 500.0) + Y;
auto Z = Y - B * (1.0 / 200.0);
auto Y = (L + 16.0) / 116.0;
auto X = A / 500.0 + Y;
auto Z = Y - B / 200.0;
// NOTE: use the constants of the illuminant of the target RGB color space
X = finv(X) * 0.9504; // D50: * 0.9642
@ -1109,15 +1048,7 @@ static bool LoadPSD(QDataStream &stream, const PSDHeader &header, QImage &img)
QByteArray rawStride;
rawStride.resize(raw_count);
// clang-format off
// checks the need of color conversion (that requires random access to the image)
auto randomAccess = (header.color_mode == CM_CMYK) ||
(header.color_mode == CM_LABCOLOR) ||
(header.color_mode == CM_MULTICHANNEL) ||
(header.color_mode != CM_INDEXED && img.hasAlphaChannel());
// clang-format on
if (randomAccess) {
if (header.color_mode == CM_CMYK || header.color_mode == CM_LABCOLOR || header.color_mode == CM_MULTICHANNEL) {
// In order to make a colorspace transformation, we need all channels of a scanline
QByteArray psdScanline;
psdScanline.resize(qsizetype(header.width * std::min(header.depth, quint16(16)) * header.channel_count + 7) / 8);
@ -1137,56 +1068,31 @@ static bool LoadPSD(QDataStream &stream, const PSDHeader &header, QImage &img)
auto scanLine = reinterpret_cast<unsigned char*>(psdScanline.data());
if (header.depth == 8) {
planarToChunchy<quint8>(scanLine, rawStride.data(), header.width, c, header.channel_count);
} else if (header.depth == 16) {
}
else if (header.depth == 16) {
planarToChunchy<quint16>(scanLine, rawStride.data(), header.width, c, header.channel_count);
} else if (header.depth == 32) {
}
else if (header.depth == 32) { // Not currently used
planarToChunchyFloat<quint32>(scanLine, rawStride.data(), header.width, c, header.channel_count);
}
}
// Convert premultiplied data to unassociated data
if (img.hasAlphaChannel()) {
if (header.color_mode == CM_CMYK) {
if (header.depth == 8)
premulConversion<quint8>(psdScanline.data(), header.width, 4, header.channel_count, PremulConversion::PS2A);
else if (header.depth == 16)
premulConversion<quint16>(psdScanline.data(), header.width, 4, header.channel_count, PremulConversion::PS2A);
}
if (header.color_mode == CM_LABCOLOR) {
if (header.depth == 8)
premulConversion<quint8>(psdScanline.data(), header.width, 3, header.channel_count, PremulConversion::PSLab2A);
else if (header.depth == 16)
premulConversion<quint16>(psdScanline.data(), header.width, 3, header.channel_count, PremulConversion::PSLab2A);
}
if (header.color_mode == CM_RGB) {
if (header.depth == 8)
premulConversion<quint8>(psdScanline.data(), header.width, 3, header.channel_count, PremulConversion::PS2P);
else if (header.depth == 16 || header.depth == 32)
premulConversion<quint16>(psdScanline.data(), header.width, 3, header.channel_count, PremulConversion::PS2P);
}
}
// Conversion to RGB
if (header.color_mode == CM_CMYK || header.color_mode == CM_MULTICHANNEL) {
if (header.color_mode == CM_CMYK) {
if (header.depth == 8)
cmykToRgb<quint8>(img.scanLine(y), imgChannels, psdScanline.data(), header.channel_count, header.width, alpha);
else if (header.depth == 16)
else
cmykToRgb<quint16>(img.scanLine(y), imgChannels, psdScanline.data(), header.channel_count, header.width, alpha);
}
if (header.color_mode == CM_LABCOLOR) {
if (header.depth == 8)
labToRgb<quint8>(img.scanLine(y), imgChannels, psdScanline.data(), header.channel_count, header.width, alpha);
else if (header.depth == 16)
else
labToRgb<quint16>(img.scanLine(y), imgChannels, psdScanline.data(), header.channel_count, header.width, alpha);
}
if (header.color_mode == CM_RGB) {
if (header.depth == 8)
rawChannelsCopy<quint8>(img.scanLine(y), imgChannels, psdScanline.data(), header.channel_count, header.width);
else if (header.depth == 16 || header.depth == 32)
rawChannelsCopy<quint16>(img.scanLine(y), imgChannels, psdScanline.data(), header.channel_count, header.width);
}
}
} else {
}
else {
// Linear read (no position jumps): optimized code usable only for the colorspaces supported by QImage
for (qint32 c = 0; c < channel_num; ++c) {
for (qint32 y = 0, h = header.height; y < h; ++y) {
@ -1197,13 +1103,16 @@ static bool LoadPSD(QDataStream &stream, const PSDHeader &header, QImage &img)
}
auto scanLine = img.scanLine(y);
if (header.depth == 1) { // Bitmap
if (header.depth == 1) { // Bitmap
monoInvert(scanLine, rawStride.data(), std::min(rawStride.size(), img.bytesPerLine()));
} else if (header.depth == 8) { // 8-bits images: Indexed, Grayscale, RGB/RGBA
}
else if (header.depth == 8) { // 8-bits images: Indexed, Grayscale, RGB/RGBA
planarToChunchy<quint8>(scanLine, rawStride.data(), header.width, c, imgChannels);
} else if (header.depth == 16) { // 16-bits integer images: Grayscale, RGB/RGBA
}
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)
}
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);
}
}
@ -1346,12 +1255,9 @@ bool PSDHandler::canRead(QIODevice *device)
if (header.color_mode == CM_CMYK || header.color_mode == CM_LABCOLOR || header.color_mode == CM_MULTICHANNEL) {
return false;
}
if (header.color_mode == CM_RGB && header.channel_count > 3) {
return false; // supposing extra channel as alpha
}
}
return IsSupported(header);
return IsValid(header);
}
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",
"eip", "erf",
"fff",
"hdr",
"iiq",
"k25", "kc2", "kdc",
"mdc", "mef", "mfw", "mos", "mrw",
@ -110,20 +111,10 @@ public:
}
virtual int read(void *ptr, size_t sz, size_t nmemb) override
{
qint64 read = 0;
if (sz == 0) {
auto read = m_device->read(reinterpret_cast<char *>(ptr), sz * nmemb);
if (read < 1) {
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;
}
virtual int eof() override
@ -140,7 +131,7 @@ public:
if (whence == SEEK_END) {
pos = size + o;
}
if (pos < 0 || m_device->isSequential()) {
if (pos < 0 || pos > size || m_device->isSequential()) {
return -1;
}
return m_device->seek(pos) ? 0 : -1;
@ -675,9 +666,6 @@ bool LoadRAW(QImageIOHandler *handler, QImage &img)
if (params.output_color == 4) {
img.setColorSpace(QColorSpace(QColorSpace::ProPhotoRgb));
}
if (params.output_color == 7) {
img.setColorSpace(QColorSpace(QColorSpace::DisplayP3));
}
}
// *** Set the metadata

View File

@ -7,6 +7,7 @@
"dcs", "dc2", "dcr", "dng", "drf", "dxo",
"eip", "erf",
"fff",
"hdr",
"iiq",
"k25", "kdc", "kc2",
"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-epson-eip", "image/x-epson-erf",
"image/x-fff",
"image/x-hdr",
"image/x-iiq",
"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",

View File

@ -430,9 +430,6 @@ bool TGAHandler::write(const QImage &image)
const QImage &img = image;
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++) {
s << targaMagic[i];
}
@ -441,7 +438,7 @@ bool TGAHandler::write(const QImage &image)
s << quint16(img.width()); // width
s << quint16(img.height()); // height
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 x = 0; x < img.width(); x++) {