From 19b8eaa50d465c5a2b2c7f02c94b088fdd715ff6 Mon Sep 17 00:00:00 2001 From: Sergey Fedorov Date: Fri, 7 Aug 2026 01:21:15 +0000 Subject: [PATCH] Support Qt4 Guard the remaining Qt5-only APIs (QT += widgets/concurrent, QComboBox::currentData(), QWheelEvent::angleDelta(), QGuiApplication:: setApplicationDisplayName()) behind QT_VERSION checks instead of replacing them unconditionally, and link against the QtMimeTypes backport (e.g. MacPorts port:qt4-mimetypes) on Qt4. Add a QFileDevice compat typedef (Qt4's QFile carries the permission flags/setPermissions() that Qt5 moved onto the new QFileDevice base class) and the missing QUrl include in imageview.cpp, both needed for a clean Qt4 build. Fix color corruption on big-endian PPC: FXX generated all in-memory previews/thumbnails as BMP before handing them to QImage::fromData(). Qt's BMP reader decodes the raw DIB pixel array with host-endian assumptions that break on big-endian systems. Switch to PNG, which (like the TIFF format used by the pre-refactor 1.0.0 codebase) is explicitly byte-order-defined and already a hard dependency of Cyan (see tst_cyan.cpp's hasPNG() check). --- cyan.pro | 9 ++++++++- src/FXX.cpp | 8 ++++---- src/compat.h | 21 +++++++++++++++++++++ src/cyan.cpp | 7 ++++++- src/cyan.h | 1 + src/helpdialog.h | 1 + src/imageview.cpp | 13 ++++++++++++- src/imageview.h | 1 + src/main.cpp | 2 ++ src/openlayerdialog.h | 1 + src/profiledialog.h | 1 + 11 files changed, 58 insertions(+), 7 deletions(-) create mode 100644 src/compat.h diff --git a/cyan.pro b/cyan.pro index 218755a..dec532f 100644 --- a/cyan.pro +++ b/cyan.pro @@ -56,7 +56,8 @@ OBJECTS_DIR = $${DESTDIR}/.obj MOC_DIR = $${DESTDIR}/.moc RCC_DIR = $${DESTDIR}/.qrc -QT += widgets concurrent +QT += core gui +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets concurrent TEMPLATE = app CONFIG += c++11 @@ -78,6 +79,12 @@ isEmpty(PREFIX): PREFIX = /usr/local isEmpty(DOCDIR): DOCDIR = $$PREFIX/share/doc isEmpty(MANDIR): MANDIR = $$PREFIX/share/man +lessThan(QT_MAJOR_VERSION, 5) { + # requires the QtMimeTypes backport library (e.g. MacPorts port:qt4-mimetypes) + QMAKE_CXXFLAGS += -I$${PREFIX}/include/QtMimeTypes + LIBS += -lQtMimeTypes +} + DEFINES += CYAN_VERSION=\"\\\"$${VERSION}$${VERSION_TYPE}\\\"\" DEFINES += CYAN_GIT=\"\\\"$${GIT}\\\"\" QMAKE_TARGET_COMPANY = "$${TARGET}" diff --git a/src/FXX.cpp b/src/FXX.cpp index 87c6448..b3e0ab8 100644 --- a/src/FXX.cpp +++ b/src/FXX.cpp @@ -119,7 +119,7 @@ FXX::Image FXX::readImage(const std::string &file, // make a preview if (image.depth()>8) { image.depth(8); } - image.magick("BMP"); + image.magick("PNG"); image.write(&preview); unsigned char *preBuffer = reinterpret_cast(const_cast(preview.data())); std::vector preData(preBuffer, preBuffer + preview.length()); @@ -202,7 +202,7 @@ FXX::Image FXX::readImage(Magick::Image image, FXX::Image failsafe, bool getInfo // make a preview if (image.depth()>8) { image.depth(8); } - image.magick("BMP"); + image.magick("PNG"); image.write(&preview); unsigned char *preBuffer = reinterpret_cast(const_cast(preview.data())); std::vector preData(preBuffer, preBuffer + preview.length()); @@ -227,7 +227,7 @@ std::vector FXX::generateThumb(Magick::Image image, int width, in try { image.scale(Magick::Geometry(width, height)); if (image.depth()>8) { image.depth(8); } - image.magick("BMP"); + image.magick("PNG"); Magick::Blob preview; image.write(&preview); unsigned char *preBuffer = reinterpret_cast(const_cast(preview.data())); @@ -326,7 +326,7 @@ FXX::Image FXX::convertImage(FXX::Image input, bool getInfo) image.profile("ICC", monitorProfile); } if (image.depth()>8) { image.depth(8); } - image.magick("BMP"); + image.magick("PNG"); image.write(&preview); unsigned char *preBuffer = reinterpret_cast(const_cast(preview.data())); std::vector preData(preBuffer, preBuffer + preview.length()); diff --git a/src/compat.h b/src/compat.h new file mode 100644 index 0000000..9d9a671 --- /dev/null +++ b/src/compat.h @@ -0,0 +1,21 @@ +#ifndef COMPAT_H +#define COMPAT_H + +#include + +#if QT_VERSION < 0x050000 +// Qt4's QFile carries the permission flags/setPermissions() that Qt5 moved +// onto the new QFileDevice base class. +typedef QFile QFileDevice; +#endif + +#ifndef Q_NULLPTR + #if __cplusplus >= 201103L + #define Q_NULLPTR nullptr + #else + // not NULL to stay consistent with Qt’s convention + #define Q_NULLPTR 0 + #endif +#endif + +#endif // COMPAT_H diff --git a/src/cyan.cpp b/src/cyan.cpp index e6d8d1a..3bdc4e0 100644 --- a/src/cyan.cpp +++ b/src/cyan.cpp @@ -51,8 +51,13 @@ #include #include #include +#if QT_VERSION < 0x050000 +#include +#include +#else #include #include +#endif #include #include @@ -1570,7 +1575,7 @@ void Cyan::handleReadWatcher() getConvertProfiles(); QFileInfo fileinfo(QString::fromStdString(image.filename)); setWindowTitle(fileinfo.fileName()); - if (!monitorProfile->currentData().toString().isEmpty()) { updateImage(); } + if (!monitorProfile->itemData(monitorProfile->currentIndex()).toString().isEmpty()) { updateImage(); } } else { QMessageBox::warning(this, tr("Image error"), QString::fromStdString(image.error)); diff --git a/src/cyan.h b/src/cyan.h index e2af39d..11a21e0 100644 --- a/src/cyan.h +++ b/src/cyan.h @@ -60,6 +60,7 @@ #include "imageview.h" #include "profiledialog.h" #include "FXX.h" +#include "compat.h" #define RESOURCE_BYTE 1050000000 diff --git a/src/helpdialog.h b/src/helpdialog.h index 733044f..e754e8d 100644 --- a/src/helpdialog.h +++ b/src/helpdialog.h @@ -36,6 +36,7 @@ #include #include #include +#include "compat.h" class HelpDialog : public QDialog { diff --git a/src/imageview.cpp b/src/imageview.cpp index 75c5cee..359591e 100644 --- a/src/imageview.cpp +++ b/src/imageview.cpp @@ -32,8 +32,14 @@ #include "imageview.h" #include +#include +#if QT_VERSION < 0x050000 +#include +#include +#else #include #include +#endif #include ImageView::ImageView(QWidget* parent) : QGraphicsView(parent) @@ -54,7 +60,12 @@ ImageView::ImageView(QWidget* parent) : QGraphicsView(parent) void ImageView::wheelEvent(QWheelEvent* event) { setTransformationAnchor(QGraphicsView::AnchorUnderMouse); double scaleFactor = 1.15; - if(event->angleDelta().y() > 0) { // up +#if QT_VERSION < 0x050000 + int delta = event->delta(); +#else + int delta = event->angleDelta().y(); +#endif + if(delta > 0) { // up fit = false; scale(scaleFactor, scaleFactor); emit myZoom(scaleFactor, scaleFactor); diff --git a/src/imageview.h b/src/imageview.h index 29a62aa..1666cd8 100644 --- a/src/imageview.h +++ b/src/imageview.h @@ -40,6 +40,7 @@ #include #include #include +#include "compat.h" class ImageView : public QGraphicsView { diff --git a/src/main.cpp b/src/main.cpp index 480d2b8..4776961 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -43,7 +43,9 @@ int main(int argc, char *argv[]) QApplication a(argc, argv); QCoreApplication::setApplicationName("Cyan"); QCoreApplication::setOrganizationName("Cyan"); +#if QT_VERSION >= 0x050000 QGuiApplication::setApplicationDisplayName("Cyan"); +#endif QCoreApplication::setOrganizationDomain("net.fxarena"); QCoreApplication::setApplicationVersion(CYAN_VERSION); Cyan w; diff --git a/src/openlayerdialog.h b/src/openlayerdialog.h index c9cda39..c3d9a05 100644 --- a/src/openlayerdialog.h +++ b/src/openlayerdialog.h @@ -40,6 +40,7 @@ #include #include #include "FXX.h" +#include "compat.h" class OpenLayerDialog : public QDialog { diff --git a/src/profiledialog.h b/src/profiledialog.h index 3ec91c9..2b2348b 100644 --- a/src/profiledialog.h +++ b/src/profiledialog.h @@ -38,6 +38,7 @@ #include #include #include "FXX.h" +#include "compat.h" class ProfileDialog : public QDialog { -- 2.43.0