Compare commits

...

21 Commits

Author SHA1 Message Date
fb66044714 Add FreeBSD CI 2021-10-07 00:28:35 +02:00
a43394a759 Add Android CI 2021-10-07 00:04:08 +02:00
904c251f50 GIT_SILENT Upgrade ECM and KF version requirements for 5.87.0 release. 2021-10-02 12:18:49 +00:00
2f9e09f04a Add Gitlab CI configuration 2021-09-29 21:55:22 +13:00
6458c9ae52 avif: performance and quality improvements
Enable decoder to use more threads.
8bit YUV->RGB conversion is significantly faster
when AVIF_RGB_FORMAT_RGBA format is used,
because libavif can use libyuv to perform conversion quickly.
Prefer faster AVIF_CHROMA_UPSAMPLING_FASTEST when decoding animation.
Encoder speed changed from to 8 to 7.
Recent AV1 encoders got faster,
so it is OK to switch to better compression quality.
Remove obsolete image/avif-sequence mime-type
as it was merged with image/avif.
2021-09-22 11:53:46 +02:00
45cd128f73 GIT_SILENT Add CI configuration file 2021-09-05 14:03:42 +02:00
e89d21f12d GIT_SILENT Upgrade ECM and KF version requirements for 5.86.0 release. 2021-09-04 15:45:36 +00:00
1d2b51ddf1 Fix build with clang12 + libc++ 2021-08-30 20:29:23 +02:00
1080976abe GIT_SILENT: we can use std::as_const directly 2021-08-28 18:07:43 +02:00
abd550c60c GIT_SILENT: replace MacOSX with macOS 2021-08-25 14:56:21 +02:00
aade392da3 Clean up unneeded JSON parameter in kimageformats_add_plugin
The moc process already rebuilds the plugin when the JSON file changes, consequently the additional parameter is not needed.

Task: https://phabricator.kde.org/T14649
2021-08-24 12:06:06 +02:00
7642633551 SGIImage::writeImage: Properly fail if the image is too big 2021-08-19 17:29:44 +02:00
9f2c5061c8 exr: Port to std::log/pow
The Imath functions are marked as deprecated and they just call the
std::log/pow anyway
2021-08-18 21:51:53 +00:00
28099eed71 GIT_SILENT Upgrade Qt5 version requirement to 5.15.2. 2021-08-15 08:56:59 +00:00
f5d574b3ad clang-tidy: one declaration per line; braces around statements
clang-tidy checks:
readability-isolate-declaration and readability-braces-around-statements

KF task: https://phabricator.kde.org/T14729

GIT_SILENT
2021-08-13 15:13:21 +02:00
a8f92e5525 PCXHandler::write: Properly fail if the image is too big 2021-08-12 16:43:52 +02:00
fbeef559b7 exr: Repair compability with openexr2
BUGS: 440084
2021-07-21 00:04:45 +02:00
7f56d835f0 GIT_SILENT Upgrade ECM and KF version requirements for 5.85.0 release. 2021-07-14 22:32:29 +00:00
8f87ce4cb2 Fix typos found by codespell
GIT_SILENT
2021-07-14 00:08:38 +02:00
5aa03c12ad exr: Override the actual function signature
For gcc there's a typedef that makes it work, but seems clang in macos is
not so lucky

BUGS: 439767
2021-07-12 20:15:12 +02:00
3266a9c466 Fix build with older openEXR versions
Dynamic exception specification is not allowed in c++-17. The enforcement needs
to be relaxed for the kimg_exr plugin when using openEXR versions older than 2.3.0.
2021-07-08 12:56:30 +02:00
20 changed files with 229 additions and 104 deletions

View File

@ -1,2 +1,3 @@
#clang-format
#clang-format/tidy
1169859b07f25c865ee0bfc2a7dc97a431651776
eaca33bec8b19498c3621fc3a20a8c55a2812462

7
.gitlab-ci.yml Normal file
View File

@ -0,0 +1,7 @@
# SPDX-FileCopyrightText: 2020 Volker Krause <vkrause@kde.org>
# SPDX-License-Identifier: CC0-1.0
include:
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/linux.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

8
.kde-ci.yml Normal file
View File

@ -0,0 +1,8 @@
Dependencies:
- 'on': ['Linux', 'FreeBSD', 'macOS', 'Windows']
'require':
'frameworks/extra-cmake-modules': '@same'
'frameworks/karchive' : '@same'
Options:
test-before-installing: True

View File

@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.16)
project(KImageFormats)
include(FeatureSummary)
find_package(ECM 5.84.0 NO_MODULE)
find_package(ECM 5.87.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)
@ -18,7 +18,7 @@ include(KDEGitCommitHooks)
include(CheckIncludeFiles)
set(REQUIRED_QT_VERSION 5.15.0)
set(REQUIRED_QT_VERSION 5.15.2)
find_package(Qt5Gui ${REQUIRED_QT_VERSION} REQUIRED NO_MODULE)
find_package(KF5Archive)
@ -65,7 +65,7 @@ add_feature_info(LibHeif LibHeif_FOUND "required for the QImage plugin for HEIF/
# 050d00 (5.13) triggers a BIC in qimageiohandler.h, in Qt 5.13, so do not enable that until we can require 5.14
# https://codereview.qt-project.org/c/qt/qtbase/+/279215
add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0x050f00)
add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0x050f02)
add_definitions(-DKF_DISABLE_DEPRECATED_BEFORE_AND_AT=0x055100)
add_subdirectory(src)
if (BUILD_TESTING)

View File

@ -44,11 +44,13 @@ static bool fuzzyeq(const QImage &im1, const QImage &im2, uchar fuzziness)
const Trait *line2 = reinterpret_cast<const Trait *>(im2.scanLine(i));
for (int j = 0; j < width; ++j) {
if (line1[j] > line2[j]) {
if (line1[j] - line2[j] > fuzziness)
if (line1[j] - line2[j] > fuzziness) {
return false;
}
} else {
if (line2[j] - line1[j] > fuzziness)
if (line2[j] - line1[j] > fuzziness) {
return false;
}
}
}
}

View File

@ -5,7 +5,7 @@ type: functional
platforms:
- name: Linux
- name: FreeBSD
- name: MacOSX
- name: macOS
- name: Windows
note: No EPS support on Windows
- name: Android

View File

@ -4,19 +4,13 @@
function(kimageformats_add_plugin plugin)
set(options)
set(oneValueArgs JSON)
set(multiValueArgs SOURCES)
cmake_parse_arguments(KIF_ADD_PLUGIN "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
if(NOT KIF_ADD_PLUGIN_SOURCES)
message(FATAL_ERROR "kimageformats_add_plugin called without SOURCES parameter")
endif()
get_filename_component(json "${KIF_ADD_PLUGIN_JSON}" REALPATH)
if(NOT KIF_ADD_PLUGIN_JSON OR NOT EXISTS ${json})
message(FATAL_ERROR "JSON file doesn't exist: ${json}")
endif()
add_library(${plugin} MODULE ${KIF_ADD_PLUGIN_SOURCES})
set_property(TARGET ${plugin} APPEND PROPERTY AUTOGEN_TARGET_DEPENDS ${json})
set_target_properties(${plugin} PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/imageformats")
target_link_libraries(${plugin} Qt5::Gui)
install(TARGETS ${plugin} DESTINATION ${KDE_INSTALL_QTPLUGINDIR}/imageformats)
@ -24,13 +18,13 @@ endfunction()
##################################
kimageformats_add_plugin(kimg_ani JSON "ani.json" SOURCES ani.cpp)
kimageformats_add_plugin(kimg_ani SOURCES ani.cpp)
install(FILES ani.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR}/qimageioplugins/)
##################################
if (TARGET avif)
kimageformats_add_plugin(kimg_avif JSON "avif.json" SOURCES "avif.cpp")
kimageformats_add_plugin(kimg_avif SOURCES "avif.cpp")
target_link_libraries(kimg_avif "avif")
install(FILES avif.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR}/qimageioplugins/)
endif()
@ -43,7 +37,7 @@ install(FILES dds-qt.desktop RENAME dds.desktop DESTINATION ${KDE_INSTALL_KSERVI
if (BUILD_EPS_PLUGIN)
if (Qt5PrintSupport_FOUND)
kimageformats_add_plugin(kimg_eps JSON "eps.json" SOURCES eps.cpp)
kimageformats_add_plugin(kimg_eps SOURCES eps.cpp)
target_link_libraries(kimg_eps Qt5::PrintSupport)
install(FILES eps.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR}/qimageioplugins/)
endif()
@ -57,10 +51,15 @@ install(FILES jp2.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR}/qimageioplugi
##################################
if(OpenEXR_FOUND)
kimageformats_add_plugin(kimg_exr JSON "exr.json" SOURCES exr.cpp)
kimageformats_add_plugin(kimg_exr SOURCES exr.cpp)
if(TARGET OpenEXR::OpenEXR)
target_link_libraries(kimg_exr OpenEXR::OpenEXR)
else()
if(OpenEXR_VERSION_STRING VERSION_LESS 2.3.0)
# Older OpenEXR versions use dynamic exception specifications, so
# cannot use C++17 with them
set_target_properties(kimg_exr PROPERTIES CXX_STANDARD 14)
endif()
target_link_libraries(kimg_exr OpenEXR::IlmImf)
endif()
kde_target_enable_exceptions(kimg_exr PRIVATE)
@ -70,13 +69,13 @@ endif()
##################################
kimageformats_add_plugin(kimg_hdr JSON "hdr.json" SOURCES hdr.cpp)
kimageformats_add_plugin(kimg_hdr SOURCES hdr.cpp)
install(FILES hdr.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR}/qimageioplugins/)
##################################
if (LibHeif_FOUND)
kimageformats_add_plugin(kimg_heif JSON "heif.json" SOURCES heif.cpp)
kimageformats_add_plugin(kimg_heif SOURCES heif.cpp)
target_link_libraries(kimg_heif PkgConfig::LibHeif)
kde_target_enable_exceptions(kimg_heif PRIVATE)
install(FILES heif.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR}/qimageioplugins/)
@ -84,48 +83,48 @@ endif()
##################################
kimageformats_add_plugin(kimg_pcx JSON "pcx.json" SOURCES pcx.cpp)
kimageformats_add_plugin(kimg_pcx SOURCES pcx.cpp)
install(FILES pcx.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR}/qimageioplugins/)
##################################
kimageformats_add_plugin(kimg_pic JSON "pic.json" SOURCES pic.cpp)
kimageformats_add_plugin(kimg_pic SOURCES pic.cpp)
install(FILES pic.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR}/qimageioplugins/)
##################################
kimageformats_add_plugin(kimg_psd JSON "psd.json" SOURCES psd.cpp)
kimageformats_add_plugin(kimg_psd SOURCES psd.cpp)
install(FILES psd.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR}/qimageioplugins/)
##################################
kimageformats_add_plugin(kimg_ras JSON "ras.json" SOURCES ras.cpp)
kimageformats_add_plugin(kimg_ras SOURCES ras.cpp)
install(FILES ras.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR}/qimageioplugins/)
##################################
kimageformats_add_plugin(kimg_rgb JSON "rgb.json" SOURCES rgb.cpp)
kimageformats_add_plugin(kimg_rgb SOURCES rgb.cpp)
install(FILES rgb.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR}/qimageioplugins/)
##################################
kimageformats_add_plugin(kimg_tga JSON "tga.json" SOURCES tga.cpp)
kimageformats_add_plugin(kimg_tga SOURCES tga.cpp)
install(FILES tga.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR}/qimageioplugins/)
##################################
kimageformats_add_plugin(kimg_xcf JSON "xcf.json" SOURCES xcf.cpp)
kimageformats_add_plugin(kimg_xcf SOURCES xcf.cpp)
install(FILES xcf.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR}/qimageioplugins/)
##################################
if (KF5Archive_FOUND)
kimageformats_add_plugin(kimg_kra JSON "kra.json" SOURCES kra.cpp)
kimageformats_add_plugin(kimg_kra SOURCES kra.cpp)
target_link_libraries(kimg_kra KF5::Archive)
install(FILES kra.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR}/qimageioplugins/)
kimageformats_add_plugin(kimg_ora JSON "ora.json" SOURCES ora.cpp)
kimageformats_add_plugin(kimg_ora SOURCES ora.cpp)
target_link_libraries(kimg_ora KF5::Archive)
install(FILES ora.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR}/qimageioplugins/)

View File

@ -97,6 +97,10 @@ bool QAVIFHandler::ensureDecoder()
m_decoder = avifDecoderCreate();
#if AVIF_VERSION >= 80400
m_decoder->maxThreads = qBound(1, QThread::idealThreadCount(), 64);
#endif
#if AVIF_VERSION >= 90100
m_decoder->strictFlags = AVIF_STRICT_DISABLED;
#endif
@ -184,7 +188,7 @@ bool QAVIFHandler::decode_one_frame()
if (loadalpha) {
resultformat = QImage::Format_RGBA8888;
} else {
resultformat = QImage::Format_RGB888;
resultformat = QImage::Format_RGBX8888;
}
}
QImage result(m_decoder->image->width, m_decoder->image->height, resultformat);
@ -276,20 +280,24 @@ bool QAVIFHandler::decode_one_frame()
rgb.format = AVIF_RGB_FORMAT_RGBA;
if (!loadalpha) {
rgb.ignoreAlpha = AVIF_TRUE;
result.fill(Qt::black);
if (m_decoder->image->yuvFormat == AVIF_PIXEL_FORMAT_YUV400) {
resultformat = QImage::Format_Grayscale16;
}
}
} else {
rgb.depth = 8;
rgb.format = AVIF_RGB_FORMAT_RGBA;
#if AVIF_VERSION >= 80400
if (m_decoder->imageCount > 1) {
/* accelerate animated AVIF */
rgb.chromaUpsampling = AVIF_CHROMA_UPSAMPLING_FASTEST;
}
#endif
if (loadalpha) {
rgb.format = AVIF_RGB_FORMAT_RGBA;
resultformat = QImage::Format_ARGB32;
} else {
rgb.format = AVIF_RGB_FORMAT_RGB;
if (m_decoder->image->yuvFormat == AVIF_PIXEL_FORMAT_YUV400) {
resultformat = QImage::Format_Grayscale8;
} else {
@ -710,7 +718,7 @@ bool QAVIFHandler::write(const QImage &image)
encoder->maxQuantizerAlpha = maxQuantizerAlpha;
}
encoder->speed = 8;
encoder->speed = 7;
res = avifEncoderWrite(encoder, avif, &raw);
avifEncoderDestroy(encoder);
@ -814,7 +822,7 @@ bool QAVIFHandler::jumpToNextImage()
return true;
}
if (m_decoder->imageIndex >= m_decoder->imageCount - 1) { // start from begining
if (m_decoder->imageIndex >= m_decoder->imageCount - 1) { // start from beginning
avifDecoderReset(m_decoder);
}

View File

@ -1,4 +1,4 @@
{
"Keys": [ "avif", "avifs" ],
"MimeTypes": [ "image/avif", "image/avif-sequence" ]
"MimeTypes": [ "image/avif", "image/avif" ]
}

View File

@ -94,7 +94,10 @@ static bool bbox(QIODevice *io, int *x1, int *y1, int *x2, int *y2)
if (strncmp(buf, BBOX, BBOX_LEN) == 0) {
// Some EPS files have non-integer values for the bbox
// We don't support that currently, but at least we parse it
float _x1, _y1, _x2, _y2;
float _x1;
float _y1;
float _x2;
float _y2;
if (sscanf(buf, "%*s %f %f %f %f", &_x1, &_y1, &_x2, &_y2) == 4) {
qCDebug(EPSPLUGIN) << "BBOX: " << _x1 << " " << _y1 << " " << _x2 << " " << _y2;
*x1 = int(_x1);
@ -127,14 +130,18 @@ bool EPSHandler::read(QImage *image)
{
qCDebug(EPSPLUGIN) << "starting...";
int x1, y1, x2, y2;
int x1;
int y1;
int x2;
int y2;
#ifdef EPS_PERFORMANCE_DEBUG
QTime dt;
dt.start();
#endif
QIODevice *io = device();
qint64 ps_offset, ps_size;
qint64 ps_offset;
qint64 ps_size;
// find start of PostScript code
if (!seekToCodeStart(io, ps_offset, ps_size)) {

View File

@ -44,8 +44,13 @@ public:
}
bool read(char c[], int n) override;
#if OPENEXR_VERSION_MAJOR > 2
uint64_t tellg() override;
void seekg(uint64_t pos) override;
#else
Imf::Int64 tellg() override;
void seekg(Imf::Int64 pos) override;
#endif
void clear() override;
private:
@ -65,12 +70,20 @@ bool K_IStream::read(char c[], int n)
return false;
}
#if OPENEXR_VERSION_MAJOR > 2
uint64_t K_IStream::tellg()
#else
Imf::Int64 K_IStream::tellg()
#endif
{
return m_dev->pos();
}
#if OPENEXR_VERSION_MAJOR > 2
void K_IStream::seekg(uint64_t pos)
#else
void K_IStream::seekg(Imf::Int64 pos)
#endif
{
m_dev->seek(pos);
}
@ -86,7 +99,10 @@ void K_IStream::clear()
*/
QRgb RgbaToQrgba(struct Imf::Rgba &imagePixel)
{
float r, g, b, a;
float r;
float g;
float b;
float a;
// 1) Compensate for fogging by subtracting defog
// from the raw pixel values.
@ -119,24 +135,24 @@ QRgb RgbaToQrgba(struct Imf::Rgba &imagePixel)
// maximum intensity).
// Response: kneeLow = 0.0 (2^0.0 => 1); kneeHigh = 5.0 (2^5 =>32)
if (r > 1.0) {
r = 1.0 + Imath::Math<float>::log((r - 1.0) * 0.184874 + 1) / 0.184874;
r = 1.0 + std::log((r - 1.0) * 0.184874 + 1) / 0.184874;
}
if (g > 1.0) {
g = 1.0 + Imath::Math<float>::log((g - 1.0) * 0.184874 + 1) / 0.184874;
g = 1.0 + std::log((g - 1.0) * 0.184874 + 1) / 0.184874;
}
if (b > 1.0) {
b = 1.0 + Imath::Math<float>::log((b - 1.0) * 0.184874 + 1) / 0.184874;
b = 1.0 + std::log((b - 1.0) * 0.184874 + 1) / 0.184874;
}
if (a > 1.0) {
a = 1.0 + Imath::Math<float>::log((a - 1.0) * 0.184874 + 1) / 0.184874;
a = 1.0 + std::log((a - 1.0) * 0.184874 + 1) / 0.184874;
}
//
// 5) Gamma-correct the pixel values, assuming that the
// screen's gamma is 0.4545 (or 1/2.2).
r = Imath::Math<float>::pow(r, 0.4545);
g = Imath::Math<float>::pow(g, 0.4545);
b = Imath::Math<float>::pow(b, 0.4545);
a = Imath::Math<float>::pow(a, 0.4545);
r = std::pow(r, 0.4545);
g = std::pow(g, 0.4545);
b = std::pow(b, 0.4545);
a = std::pow(a, 0.4545);
// 6) Scale the values such that pixels middle gray
// pixels are mapped to 84.66 (or 3.5 f-stops below
@ -165,7 +181,8 @@ bool EXRHandler::canRead() const
bool EXRHandler::read(QImage *outImage)
{
try {
int width, height;
int width;
int height;
K_IStream istr(device(), QByteArray());
Imf::RgbaInputFile file(istr);

View File

@ -89,7 +89,8 @@ static void RGBE_To_QRgbLine(uchar *image, QRgb *scanline, int width)
// Load the HDR image.
static bool LoadHDR(QDataStream &s, const int width, const int height, QImage &img)
{
uchar val, code;
uchar val;
uchar code;
// Create dst image.
img = QImage(width, height, QImage::Format_RGB32);

View File

@ -35,12 +35,14 @@ bool KraHandler::canRead() const
bool KraHandler::read(QImage *image)
{
KZip zip(device());
if (!zip.open(QIODevice::ReadOnly))
if (!zip.open(QIODevice::ReadOnly)) {
return false;
}
const KArchiveEntry *entry = zip.directory()->entry(QStringLiteral("mergedimage.png"));
if (!entry || !entry->isFile())
if (!entry || !entry->isFile()) {
return false;
}
const KZipFileEntry *fileZipEntry = static_cast<const KZipFileEntry *>(entry);
@ -57,8 +59,9 @@ bool KraHandler::canRead(QIODevice *device)
}
char buff[57];
if (device->peek(buff, sizeof(buff)) == sizeof(buff))
if (device->peek(buff, sizeof(buff)) == sizeof(buff)) {
return memcmp(buff + 0x26, s_magic, s_magic_size) == 0;
}
return false;
}

View File

@ -34,12 +34,14 @@ bool OraHandler::canRead() const
bool OraHandler::read(QImage *image)
{
KZip zip(device());
if (!zip.open(QIODevice::ReadOnly))
if (!zip.open(QIODevice::ReadOnly)) {
return false;
}
const KArchiveEntry *entry = zip.directory()->entry(QStringLiteral("mergedimage.png"));
if (!entry || !entry->isFile())
if (!entry || !entry->isFile()) {
return false;
}
const KZipFileEntry *fileZipEntry = static_cast<const KZipFileEntry *>(entry);
@ -56,8 +58,9 @@ bool OraHandler::canRead(QIODevice *device)
}
char buff[54];
if (device->peek(buff, sizeof(buff)) == sizeof(buff))
if (device->peek(buff, sizeof(buff)) == sizeof(buff)) {
return memcmp(buff + 0x26, s_magic, s_magic_size) == 0;
}
return false;
}

View File

@ -105,7 +105,9 @@ public:
static QDataStream &operator>>(QDataStream &s, RGB &rgb)
{
quint8 r, g, b;
quint8 r;
quint8 g;
quint8 b;
s >> r >> g >> b;
rgb.r = r;
@ -126,24 +128,32 @@ static QDataStream &operator>>(QDataStream &s, Palette &pal)
static QDataStream &operator>>(QDataStream &s, PCXHEADER &ph)
{
quint8 m, ver, enc, bpp;
quint8 m;
quint8 ver;
quint8 enc;
quint8 bpp;
s >> m >> ver >> enc >> bpp;
ph.Manufacturer = m;
ph.Version = ver;
ph.Encoding = enc;
ph.Bpp = bpp;
quint16 xmin, ymin, xmax, ymax;
quint16 xmin;
quint16 ymin;
quint16 xmax;
quint16 ymax;
s >> xmin >> ymin >> xmax >> ymax;
ph.XMin = xmin;
ph.YMin = ymin;
ph.XMax = xmax;
ph.YMax = ymax;
quint16 hdpi, ydpi;
quint16 hdpi;
quint16 ydpi;
s >> hdpi >> ydpi;
ph.HDpi = hdpi;
ph.YDpi = ydpi;
Palette colorMap;
quint8 res, np;
quint8 res;
quint8 np;
s >> colorMap >> res >> np;
ph.ColorMap = colorMap;
ph.Reserved = res;
@ -154,7 +164,8 @@ static QDataStream &operator>>(QDataStream &s, PCXHEADER &ph)
quint16 paletteinfo;
s >> paletteinfo;
ph.PaletteInfo = paletteinfo;
quint16 hscreensize, vscreensize;
quint16 hscreensize;
quint16 vscreensize;
s >> hscreensize;
ph.HScreenSize = hscreensize;
s >> vscreensize;
@ -222,7 +233,8 @@ static void readLine(QDataStream &s, QByteArray &buf, const PCXHEADER &header)
{
quint32 i = 0;
quint32 size = buf.size();
quint8 byte, count;
quint8 byte;
quint8 count;
if (header.isCompressed()) {
// Uncompress the image data
@ -300,10 +312,11 @@ static void readImage4(QImage &img, QDataStream &s, const PCXHEADER &header)
for (int i = 0; i < 4; i++) {
quint32 offset = i * header.BytesPerLine;
for (int x = 0; x < header.width(); ++x)
for (int x = 0; x < header.width(); ++x) {
if (buf[offset + (x / 8)] & (128 >> (x % 8))) {
pixbuf[x] = (int)(pixbuf[x]) + (1 << i);
}
}
}
uchar *p = img.scanLine(y);
@ -343,8 +356,9 @@ static void readImage8(QImage &img, QDataStream &s, const PCXHEADER &header)
uchar *p = img.scanLine(y);
if (!p)
if (!p) {
return;
}
unsigned int bpl = qMin(header.BytesPerLine, (quint16)header.width());
for (unsigned int x = 0; x < bpl; ++x) {
@ -358,7 +372,9 @@ static void readImage8(QImage &img, QDataStream &s, const PCXHEADER &header)
if (flag == 12 && (header.Version == 5 || header.Version == 2)) {
// Read the palette
quint8 r, g, b;
quint8 r;
quint8 g;
quint8 b;
for (int i = 0; i < 256; ++i) {
s >> r >> g >> b;
img.setColor(i, qRgb(r, g, b));
@ -400,7 +416,8 @@ static void writeLine(QDataStream &s, QByteArray &buf)
{
quint32 i = 0;
quint32 size = buf.size();
quint8 count, data;
quint8 count;
quint8 data;
char byte;
while (i < size) {
@ -473,10 +490,11 @@ static void writeImage4(QImage &img, QDataStream &s, PCXHEADER &header)
}
for (int x = 0; x < header.width(); ++x) {
for (int i = 0; i < 4; ++i)
for (int i = 0; i < 4; ++i) {
if (*(p + x) & (1 << i)) {
buf[i][x / 8] = (int)(buf[i][x / 8]) | 1 << (7 - x % 8);
}
}
}
for (int i = 0; i < 4; ++i) {
@ -618,8 +636,12 @@ bool PCXHandler::write(const QImage &image)
QImage img = image;
int w = img.width();
int h = img.height();
const int w = img.width();
const int h = img.height();
if (w > 65536 || h > 65536) {
return false;
}
// qDebug() << "Width: " << w;
// qDebug() << "Height: " << h;

View File

@ -24,6 +24,7 @@
#include <algorithm>
#include <functional>
#include <qendian.h>
#include <utility>
/**
* Reads a PIC file header from a data stream.
@ -225,7 +226,7 @@ bool SoftimagePICHandler::read(QImage *image)
}
QImage::Format fmt = QImage::Format_RGB32;
for (const PicChannel &channel : qAsConst(m_channels)) {
for (const PicChannel &channel : std::as_const(m_channels)) {
if (channel.size != 8) {
// we cannot read images that do not come in bytes
qDebug() << "Channel size was" << channel.size;
@ -404,7 +405,7 @@ QVariant SoftimagePICHandler::option(ImageOption option) const
return QString();
case ImageFormat:
if (const_cast<SoftimagePICHandler *>(this)->readChannels()) {
for (const PicChannel &channel : qAsConst(m_channels)) {
for (const PicChannel &channel : std::as_const(m_channels)) {
if (channel.code & ALPHA) {
return QImage::Format_ARGB32;
}

View File

@ -154,13 +154,16 @@ static bool LoadRAS(QDataStream &s, const RasHeader &ras, QImage &img)
// Allocate image
img = QImage(ras.Width, ras.Height, QImage::Format_ARGB32);
if (img.isNull())
if (img.isNull()) {
return false;
}
// Reconstruct image from RGB palette if we have a palette
// TODO: make generic so it works with 24bit or 32bit palettes
if (ras.ColorMapType == 1 && ras.Depth == 8) {
quint8 red, green, blue;
quint8 red;
quint8 green;
quint8 blue;
for (quint32 y = 0; y < ras.Height; y++) {
for (quint32 x = 0; x < ras.Width; x++) {
red = palette.value((int)input[y * ras.Width + x]);
@ -172,7 +175,9 @@ static bool LoadRAS(QDataStream &s, const RasHeader &ras, QImage &img)
}
if (ras.ColorMapType == 0 && ras.Depth == 24 && (ras.Type == 1 || ras.Type == 2)) {
quint8 red, green, blue;
quint8 red;
quint8 green;
quint8 blue;
for (quint32 y = 0; y < ras.Height; y++) {
for (quint32 x = 0; x < ras.Width; x++) {
red = input[y * 3 * ras.Width + x * 3 + 2];
@ -184,7 +189,9 @@ static bool LoadRAS(QDataStream &s, const RasHeader &ras, QImage &img)
}
if (ras.ColorMapType == 0 && ras.Depth == 24 && ras.Type == 3) {
quint8 red, green, blue;
quint8 red;
quint8 green;
quint8 blue;
for (quint32 y = 0; y < ras.Height; y++) {
for (quint32 x = 0; x < ras.Width; x++) {
red = input[y * 3 * ras.Width + x * 3];
@ -196,7 +203,9 @@ static bool LoadRAS(QDataStream &s, const RasHeader &ras, QImage &img)
}
if (ras.ColorMapType == 0 && ras.Depth == 32 && (ras.Type == 1 || ras.Type == 2)) {
quint8 red, green, blue;
quint8 red;
quint8 green;
quint8 blue;
for (quint32 y = 0; y < ras.Height; y++) {
for (quint32 x = 0; x < ras.Width; x++) {
red = input[y * 4 * ras.Width + x * 4 + 3];
@ -208,7 +217,9 @@ static bool LoadRAS(QDataStream &s, const RasHeader &ras, QImage &img)
}
if (ras.ColorMapType == 0 && ras.Depth == 32 && ras.Type == 3) {
quint8 red, green, blue;
quint8 red;
quint8 green;
quint8 blue;
for (quint32 y = 0; y < ras.Height; y++) {
for (quint32 x = 0; x < ras.Width; x++) {
red = input[y * 4 * ras.Width + x * 4 + 1];
@ -274,8 +285,9 @@ bool RASHandler::read(QImage *outImage)
RasHeader ras;
s >> ras;
if (ras.ColorMapLength > std::numeric_limits<int>::max())
if (ras.ColorMapLength > std::numeric_limits<int>::max()) {
return false;
}
// TODO: add support for old versions of RAS where Length may be zero in header
s.device()->seek(RasHeader::SIZE + ras.Length + ras.ColorMapLength);

View File

@ -138,7 +138,8 @@ SGIImage::~SGIImage()
bool SGIImage::getRow(uchar *dest)
{
int n, i;
int n;
int i;
if (!_rle) {
for (i = 0; i < _xsize; i++) {
if (_pos >= _data.end()) {
@ -184,7 +185,8 @@ bool SGIImage::readData(QImage &img)
quint32 *start = _starttab;
QByteArray lguard(_xsize, 0);
uchar *line = (uchar *)lguard.data();
unsigned x, y;
unsigned x;
unsigned y;
if (!_rle) {
_pos = _data.begin();
@ -279,9 +281,9 @@ bool SGIImage::readImage(QImage &img)
// bytes per channel
_stream >> _bpc;
// qDebug() << "bytes per channel: " << int(_bpc);
if (_bpc == 1)
if (_bpc == 1) {
;
else if (_bpc == 2) {
} else if (_bpc == 2) {
// qDebug() << "dropping least significant byte";
} else {
return false;
@ -328,8 +330,9 @@ bool SGIImage::readImage(QImage &img)
return false;
}
if (_zsize == 0)
if (_zsize == 0) {
return false;
}
if (_zsize == 2 || _zsize == 4) {
img = img.convertToFormat(QImage::Format_ARGB32);
@ -337,8 +340,9 @@ bool SGIImage::readImage(QImage &img)
// qDebug() << "using first 4 of " << _zsize << " channels";
// Only let this continue if it won't cause a int overflow later
// this is most likely a broken file anyway
if (_ysize > std::numeric_limits<int>::max() / _zsize)
if (_ysize > std::numeric_limits<int>::max() / _zsize) {
return false;
}
}
_numrows = _ysize * _zsize;
@ -363,13 +367,15 @@ bool SGIImage::readImage(QImage &img)
_data = _dev->readAll();
// sanity check
if (_rle)
for (uint o = 0; o < _numrows; o++)
if (_rle) {
for (uint o = 0; o < _numrows; o++) {
// don't change to greater-or-equal!
if (_starttab[o] + _lengthtab[o] > (uint)_data.size()) {
// qDebug() << "image corrupt (sanity check failed)";
return false;
}
}
}
if (!readData(img)) {
// qDebug() << "image corrupt (incomplete scanline)";
@ -390,7 +396,8 @@ void RLEData::write(QDataStream &s)
bool RLEData::operator<(const RLEData &b) const
{
uchar ac, bc;
uchar ac;
uchar bc;
for (int i = 0; i < qMin(size(), b.size()); i++) {
ac = at(i);
bc = b[i];
@ -436,8 +443,13 @@ uchar SGIImage::intensity(uchar c)
uint SGIImage::compact(uchar *d, uchar *s)
{
uchar *dest = d, *src = s, patt, *t, *end = s + _xsize;
int i, n;
uchar *dest = d;
uchar *src = s;
uchar patt;
uchar *t;
uchar *end = s + _xsize;
int i;
int n;
while (src < end) {
for (n = 0, t = src; t + 2 < end && !(*t == t[1] && *t == t[2]); t++) {
n++;
@ -480,7 +492,8 @@ bool SGIImage::scanData(const QImage &img)
uchar *line = (uchar *)lineguard.data();
uchar *buf = (uchar *)bufguard.data();
const QRgb *c;
unsigned x, y;
unsigned x;
unsigned y;
uint len;
for (y = 0; y < _ysize; y++) {
@ -606,7 +619,8 @@ void SGIImage::writeVerbatim(const QImage &img)
writeHeader();
const QRgb *c;
unsigned x, y;
unsigned x;
unsigned y;
for (y = 0; y < _ysize; y++) {
c = reinterpret_cast<const QRgb *>(img.scanLine(_ysize - y - 1));
@ -667,9 +681,16 @@ bool SGIImage::writeImage(const QImage &image)
return false;
}
const int w = img.width();
const int h = img.height();
if (w > 65536 || h > 65536) {
return false;
}
_bpc = 1;
_xsize = img.width();
_ysize = img.height();
_xsize = w;
_ysize = h;
_pixmin = ~0u;
_pixmax = 0;
_colormap = NORMAL;

View File

@ -311,7 +311,9 @@ static bool LoadTGA(QDataStream &s, const TgaHeader &tga, QImage &img)
}
// Convert image to internal format.
int y_start, y_step, y_end;
int y_start;
int y_step;
int y_end;
if (tga.flags & TGA_ORIGIN_UPPER) {
y_start = 0;
y_step = 1;
@ -437,7 +439,7 @@ bool TGAHandler::write(const QImage &image)
s << quint8(hasAlpha ? 32 : 24); // depth (24 bit RGB + 8 bit alpha)
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++) {
const QRgb color = img.pixel(x, y);
s << quint8(qBlue(color));
@ -447,6 +449,7 @@ bool TGAHandler::write(const QImage &image)
s << quint8(qAlpha(color));
}
}
}
return true;
}

View File

@ -747,7 +747,9 @@ bool XCFImageFormat::loadImageProperties(QDataStream &xcf_io, XCFImage &xcf_imag
xcf_image.palette.reserve(xcf_image.num_colors);
for (int i = 0; i < xcf_image.num_colors; i++) {
uchar r, g, b;
uchar r;
uchar g;
uchar b;
property >> r >> g >> b;
xcf_image.palette.push_back(qRgb(r, g, b));
}
@ -1951,11 +1953,13 @@ bool XCFImageFormat::initializeImage(XCFImage &xcf_image)
if (xcf_image.x_resolution > 0 && xcf_image.y_resolution > 0) {
const float dpmx = xcf_image.x_resolution * INCHESPERMETER;
if (dpmx > std::numeric_limits<int>::max())
if (dpmx > std::numeric_limits<int>::max()) {
return false;
}
const float dpmy = xcf_image.y_resolution * INCHESPERMETER;
if (dpmy > std::numeric_limits<int>::max())
if (dpmy > std::numeric_limits<int>::max()) {
return false;
}
image.setDotsPerMeterX((int)dpmx);
image.setDotsPerMeterY((int)dpmy);
}
@ -2639,7 +2643,8 @@ void XCFImageFormat::mergeRGBToRGB(const Layer &layer, uint i, uint j, int k, in
src_a = qMin(src_a, dst_a);
} break;
case GIMP_LAYER_MODE_SOFTLIGHT_LEGACY: {
uint tmpS, tmpM;
uint tmpS;
uint tmpM;
tmpM = INT_MULT(dst_r, src_r);
tmpS = 255 - INT_MULT((255 - dst_r), (255 - src_r));
@ -2707,7 +2712,10 @@ void XCFImageFormat::mergeRGBToRGB(const Layer &layer, uint i, uint j, int k, in
src_a = INT_MULT(src_a, layer.mask_tiles[j][i].pixelIndex(k, l));
}
uchar new_r, new_g, new_b, new_a;
uchar new_r;
uchar new_g;
uchar new_b;
uchar new_a;
new_a = dst_a + INT_MULT(OPAQUE_OPACITY - dst_a, src_a);
const float src_ratio = new_a == 0 ? 1.0 : (float)src_a / new_a;
@ -2813,7 +2821,8 @@ void XCFImageFormat::mergeGrayAToGray(const Layer &layer, uint i, uint j, int k,
}
} break;
case SOFTLIGHT_MODE: {
uint tmpS, tmpM;
uint tmpS;
uint tmpM;
tmpM = INT_MULT(dst, src);
tmpS = 255 - INT_MULT((255 - dst), (255 - src));
@ -2965,7 +2974,8 @@ void XCFImageFormat::mergeGrayAToRGB(const Layer &layer, uint i, uint j, int k,
src_a = qMin(src_a, dst_a);
} break;
case SOFTLIGHT_MODE: {
uint tmpS, tmpM;
uint tmpS;
uint tmpM;
tmpM = INT_MULT(dst, src);
tmpS = 255 - INT_MULT((255 - dst), (255 - src));