compare_images.cc (4225B)
1 // Copyright (c) the JPEG XL Project Authors. All rights reserved. 2 // 3 // Use of this source code is governed by a BSD-style 4 // license that can be found in the LICENSE file. 5 6 #include <stdlib.h> 7 8 #include <QApplication> 9 #include <QCommandLineOption> 10 #include <QCommandLineParser> 11 #include <QFlags> 12 #include <QImage> 13 #include <QMessageBox> 14 #include <QStringList> 15 16 #include "tools/comparison_viewer/image_loading.h" 17 #include "tools/comparison_viewer/split_image_view.h" 18 #include "tools/icc_detect/icc_detect.h" 19 20 namespace { 21 22 void displayLoadingError(const QString& path) { 23 QMessageBox message; 24 message.setIcon(QMessageBox::Critical); 25 message.setWindowTitle( 26 QCoreApplication::translate("SplitImageView", "Error")); 27 message.setText(QCoreApplication::translate("SplitImageView", 28 "Could not load image \"%1\".") 29 .arg(path)); 30 message.exec(); 31 } 32 33 } // namespace 34 35 int main(int argc, char** argv) { 36 QApplication application(argc, argv); 37 38 QCommandLineParser parser; 39 parser.setApplicationDescription( 40 QCoreApplication::translate("compare_images", "Image comparison tool")); 41 parser.addHelpOption(); 42 parser.addPositionalArgument( 43 "left-image", 44 QCoreApplication::translate("compare_images", 45 "The image to display on the left."), 46 "<left-image>"); 47 parser.addPositionalArgument( 48 "right-image", 49 QCoreApplication::translate("compare_images", 50 "The image to display on the right."), 51 "<right-image>"); 52 parser.addPositionalArgument( 53 "middle-image", 54 QCoreApplication::translate( 55 "compare_images", "The image to display in the middle (optional)."), 56 "[<middle-image>]"); 57 58 QCommandLineOption colorSpaceOption( 59 {"color-space", "color_space", "c"}, 60 QCoreApplication::translate( 61 "compare_images", 62 "The color space to use for untagged images (typically PNM)."), 63 QCoreApplication::translate("compare_images", "color-space")); 64 parser.addOption(colorSpaceOption); 65 66 QCommandLineOption intensityTargetOption( 67 {"intensity-target", "intensity_target", "i"}, 68 QCoreApplication::translate("compare_images", 69 "The peak luminance of the display."), 70 QCoreApplication::translate("compare_images", "nits"), 71 QString::number(jxl::kDefaultIntensityTarget)); 72 parser.addOption(intensityTargetOption); 73 74 parser.process(application); 75 76 const QString colorSpaceHint = parser.value(colorSpaceOption); 77 78 QStringList arguments = parser.positionalArguments(); 79 if (arguments.size() < 2 || arguments.size() > 3) { 80 parser.showHelp(EXIT_FAILURE); 81 } 82 83 bool ok; 84 const float intensityTarget = 85 parser.value(intensityTargetOption).toFloat(&ok); 86 if (!ok) { 87 parser.showHelp(EXIT_FAILURE); 88 } 89 90 jpegxl::tools::SplitImageView view; 91 92 const QByteArray monitorIccProfile = 93 jpegxl::tools::GetMonitorIccProfile(&view); 94 95 const QString leftImagePath = arguments.takeFirst(); 96 QImage leftImage = jpegxl::tools::loadImage(leftImagePath, monitorIccProfile, 97 intensityTarget, colorSpaceHint); 98 if (leftImage.isNull()) { 99 displayLoadingError(leftImagePath); 100 return EXIT_FAILURE; 101 } 102 view.setLeftImage(std::move(leftImage)); 103 104 const QString rightImagePath = arguments.takeFirst(); 105 QImage rightImage = jpegxl::tools::loadImage( 106 rightImagePath, monitorIccProfile, intensityTarget, colorSpaceHint); 107 if (rightImage.isNull()) { 108 displayLoadingError(rightImagePath); 109 return EXIT_FAILURE; 110 } 111 view.setRightImage(std::move(rightImage)); 112 113 if (!arguments.empty()) { 114 const QString middleImagePath = arguments.takeFirst(); 115 QImage middleImage = jpegxl::tools::loadImage( 116 middleImagePath, monitorIccProfile, intensityTarget, colorSpaceHint); 117 if (middleImage.isNull()) { 118 displayLoadingError(middleImagePath); 119 return EXIT_FAILURE; 120 } 121 view.setMiddleImage(std::move(middleImage)); 122 } 123 124 view.setWindowFlags(view.windowFlags() | Qt::Window); 125 view.setWindowState(Qt::WindowMaximized); 126 view.show(); 127 128 return application.exec(); 129 }