Bug Summary

File:libs/dimg/filters/bw/mixersettings.cpp
Warning:line 550, column 9
File position of the stream might be 'indeterminate' after a failed operation. Can cause undefined behavior

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name mixersettings.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/home/gilles/devel/8.x/build.scan/core/libs/dimg -fcoverage-compilation-dir=/home/gilles/devel/8.x/build.scan/core/libs/dimg -resource-dir /usr/lib/llvm-19/lib/clang/19 -D BUILDING_XMPCOMPAREANDMERGE_AS_STATIC=1 -D BUILDING_XMPCOMPAREANDMERGE_LIB=1 -D BanAllEntityUsage=1 -D CMS_NO_REGISTER_KEYWORD=1 -D EnablePluginManager=0 -D HAVE_FFMPEG_VERSION5 -D KF_DEPRECATED_WARNINGS_SINCE=0x70000 -D KF_DISABLE_DEPRECATED_BEFORE_AND_AT=0x61100 -D LIBPGF_DISABLE_OPENMP -D LINKING_XMPCORE_LIB=1 -D MAGICKCORE_HDRI_ENABLE=0 -D MAGICKCORE_QUANTUM_DEPTH=16 -D QT_DEPRECATED_WARNINGS -D QT_NO_CAST_FROM_ASCII -D QT_NO_CAST_FROM_BYTEARRAY -D QT_NO_CAST_TO_ASCII -D QT_NO_FOREACH -D QT_NO_KEYWORDS -D QT_NO_NARROWING_CONVERSIONS_IN_CONNECT -D QT_NO_URL_CAST_FROM_STRING -D QT_STRICT_ITERATORS -D QT_USE_QSTRINGBUILDER -D TRANSLATION_DOMAIN="digikam" -D UNIX_ENV=1 -D USE_JASPER -D USE_JPEG -D USE_JPEG8 -D XMP_COMPONENT_INT_NAMESPACE=AdobeXMPCompareAndMerge_Int -D XMP_StaticBuild=1 -D _GNU_SOURCE -D _LARGEFILE64_SOURCE -D digikamcore_EXPORTS -D qDNGDebug=0 -D qDNGLittleEndian=1 -D qDNGThreadSafe=1 -D qDNGUseLibJPEG=1 -D qDNGUseStdInt=1 -D qDNGUseXMP=1 -D qDNGValidateTarget=1 -D qDNGXMPDocOps=0 -D qDNGXMPFiles=0 -D qLinux=1 -D qMacOS=0 -D qWinOS=0 -I /home/gilles/devel/8.x/build.scan/core/libs/dimg -I /home/gilles/devel/8.x/core/libs/dimg -I /home/gilles/devel/8.x/build.scan/core/libs/dimg/core_dimg_obj_autogen/include -I /home/gilles/devel/8.x/core/libs/video/player/qtmm -I /home/gilles/devel/8.x/core/libs/aitoolspipeline -I /home/gilles/devel/8.x/core/libs/album/engine -I /home/gilles/devel/8.x/core/libs/album/manager -I /home/gilles/devel/8.x/core/libs/album/treeview -I /home/gilles/devel/8.x/core/libs/album/widgets -I /home/gilles/devel/8.x/core/libs/autorotator -I /home/gilles/devel/8.x/core/libs/database/collection -I /home/gilles/devel/8.x/core/libs/database/coredb -I /home/gilles/devel/8.x/core/libs/database/dbjobs -I /home/gilles/devel/8.x/core/libs/database/engine -I /home/gilles/devel/8.x/core/libs/database/haar -I /home/gilles/devel/8.x/core/libs/database/history -I /home/gilles/devel/8.x/core/libs/database/item/containers -I /home/gilles/devel/8.x/core/libs/database/item/lister -I /home/gilles/devel/8.x/core/libs/database/item/query -I /home/gilles/devel/8.x/core/libs/database/item/scanner -I /home/gilles/devel/8.x/core/libs/database/models -I /home/gilles/devel/8.x/core/libs/database/server -I /home/gilles/devel/8.x/core/libs/database/similaritydb -I /home/gilles/devel/8.x/core/libs/database/tags -I /home/gilles/devel/8.x/core/libs/database/thumbsdb -I /home/gilles/devel/8.x/core/libs/database/utils/ifaces -I /home/gilles/devel/8.x/core/libs/database/utils/scan -I /home/gilles/devel/8.x/core/libs/database/utils/widgets -I /home/gilles/devel/8.x/core/libs/dialogs -I /home/gilles/devel/8.x/core/libs/dimg/color -I /home/gilles/devel/8.x/core/libs/dimg/filters/auto -I /home/gilles/devel/8.x/core/libs/dimg/filters/bcg -I /home/gilles/devel/8.x/core/libs/dimg/filters/bw -I /home/gilles/devel/8.x/core/libs/dimg/filters/cb -I /home/gilles/devel/8.x/core/libs/dimg/filters/curves -I /home/gilles/devel/8.x/core/libs/dimg/filters/decorate -I /home/gilles/devel/8.x/core/libs/dimg/filters -I /home/gilles/devel/8.x/core/libs/dimg/filters/film -I /home/gilles/devel/8.x/core/libs/dimg/filters/fx -I /home/gilles/devel/8.x/core/libs/dimg/filters/greycstoration/cimg -I /home/gilles/devel/8.x/core/libs/dimg/filters/greycstoration -I /home/gilles/devel/8.x/core/libs/dimg/filters/hotpixels -I /home/gilles/devel/8.x/core/libs/dimg/filters/hsl -I /home/gilles/devel/8.x/core/libs/dimg/filters/icc -I /home/gilles/devel/8.x/core/libs/dimg/filters/lc -I /home/gilles/devel/8.x/core/libs/dimg/filters/lens -I /home/gilles/devel/8.x/core/libs/dimg/filters/levels -I /home/gilles/devel/8.x/core/libs/dimg/filters/nr -I /home/gilles/devel/8.x/core/libs/dimg/filters/raw -I /home/gilles/devel/8.x/core/libs/dimg/filters/redeye -I /home/gilles/devel/8.x/core/libs/dimg/filters/sharp -I /home/gilles/devel/8.x/core/libs/dimg/filters/transform -I /home/gilles/devel/8.x/core/libs/dimg/filters/wb -I /home/gilles/devel/8.x/core/libs/dimg/history -I /home/gilles/devel/8.x/core/libs/dimg/loaders -I /home/gilles/devel/8.x/core/libs/dngwriter -I /home/gilles/devel/8.x/core/libs/dnnmodelmanager -I /home/gilles/devel/8.x/core/libs/dplugins/core -I /home/gilles/devel/8.x/core/libs/dplugins/iface -I /home/gilles/devel/8.x/core/libs/dplugins/setup -I /home/gilles/devel/8.x/core/libs/dplugins/webservices -I /home/gilles/devel/8.x/core/libs/dplugins/widgets -I /home/gilles/devel/8.x/core/libs/dragdrop -I /home/gilles/devel/8.x/core/libs/dtrash -I /home/gilles/devel/8.x/core/libs/facesengine/common -I /home/gilles/devel/8.x/core/libs/facesengine/detection -I /home/gilles/devel/8.x/core/libs/facesengine/detection/opencv-dnn -I /home/gilles/devel/8.x/core/libs/facesengine/facedb -I /home/gilles/devel/8.x/core/libs/facesengine/recognition -I /home/gilles/devel/8.x/core/libs/facesengine/recognition/opencv-dnn -I /home/gilles/devel/8.x/core/libs/facesengine/widgets -I /home/gilles/devel/8.x/core/libs/fileactionmanager -I /home/gilles/devel/8.x/core/libs/filters -I /home/gilles/devel/8.x/core/libs/imgqsort/detectors -I /home/gilles/devel/8.x/core/libs/imgqsort -I /home/gilles/devel/8.x/core/libs/iojobs -I /home/gilles/devel/8.x/core/libs/jpegutils -I /home/gilles/devel/8.x/core/libs/metadataengine/containers -I /home/gilles/devel/8.x/core/libs/metadataengine/dmetadata -I /home/gilles/devel/8.x/core/libs/metadataengine/engine -I /home/gilles/devel/8.x/core/libs/metadataengine/exiftool -I /home/gilles/devel/8.x/core/libs/metadataengine/focuspoint -I /home/gilles/devel/8.x/core/libs/mlfoundation -I /home/gilles/devel/8.x/core/libs/models -I /home/gilles/devel/8.x/core/libs/networkmanager -I /home/gilles/devel/8.x/core/libs/notificationmanager -I /home/gilles/devel/8.x/core/libs/onlineversion -I /home/gilles/devel/8.x/core/libs/pgfutils -I /home/gilles/devel/8.x/core/libs/progressmanager -I /home/gilles/devel/8.x/core/libs/properties/captions -I /home/gilles/devel/8.x/core/libs/properties/geolocation -I /home/gilles/devel/8.x/core/libs/properties/history -I /home/gilles/devel/8.x/core/libs/properties/import -I /home/gilles/devel/8.x/core/libs/properties -I /home/gilles/devel/8.x/core/libs/qtopencvimg -I /home/gilles/devel/8.x/core/libs/rawengine -I /home/gilles/devel/8.x/core/libs/settings -I /home/gilles/devel/8.x/core/libs/tags/autoassignment -I /home/gilles/devel/8.x/core/libs/tags/autoassignment/classifiers -I /home/gilles/devel/8.x/core/libs/tags/autoassignment/classifiers/minmax -I /home/gilles/devel/8.x/core/libs/tags/autoassignment/classifiers/multiclassyolo -I /home/gilles/devel/8.x/core/libs/tags/autoassignment/classifiers/softmax -I /home/gilles/devel/8.x/core/libs/tags/autoassignment/pipelines -I /home/gilles/devel/8.x/core/libs/tags/autoassignment/pipelines/object -I /home/gilles/devel/8.x/core/libs/tags/engine -I /home/gilles/devel/8.x/core/libs/tags/manager/models -I /home/gilles/devel/8.x/core/libs/tags/manager -I /home/gilles/devel/8.x/core/libs/tags/widgets -I /home/gilles/devel/8.x/core/libs/template -I /home/gilles/devel/8.x/core/libs/threadimageio/engine -I /home/gilles/devel/8.x/core/libs/threadimageio/fileio -I /home/gilles/devel/8.x/core/libs/threadimageio/preview -I /home/gilles/devel/8.x/core/libs/threadimageio/thumb -I /home/gilles/devel/8.x/core/libs/threadimageio/video -I /home/gilles/devel/8.x/core/libs/threads -I /home/gilles/devel/8.x/core/libs/timeadjust -I /home/gilles/devel/8.x/core/libs/transitionmngr -I /home/gilles/devel/8.x/core/libs/versionmanager -I /home/gilles/devel/8.x/core/libs/video -I /home/gilles/devel/8.x/core/libs/video/manager -I /home/gilles/devel/8.x/core/libs/video/osd -I /home/gilles/devel/8.x/core/libs/video/player -I /home/gilles/devel/8.x/core/libs/widgets/colors -I /home/gilles/devel/8.x/core/libs/widgets/combo -I /home/gilles/devel/8.x/core/libs/widgets/files -I /home/gilles/devel/8.x/core/libs/widgets/fonts -I /home/gilles/devel/8.x/core/libs/widgets/graphicsview -I /home/gilles/devel/8.x/core/libs/widgets/history -I /home/gilles/devel/8.x/core/libs/widgets/iccprofiles -I /home/gilles/devel/8.x/core/libs/widgets/itemview -I /home/gilles/devel/8.x/core/libs/widgets/layout -I /home/gilles/devel/8.x/core/libs/widgets/mainview -I /home/gilles/devel/8.x/core/libs/widgets/metadata/config -I /home/gilles/devel/8.x/core/libs/widgets/metadata/exiftool -I /home/gilles/devel/8.x/core/libs/widgets/metadata/exiv2 -I /home/gilles/devel/8.x/core/libs/widgets/metadata/labels -I /home/gilles/devel/8.x/core/libs/widgets/metadata/utils -I /home/gilles/devel/8.x/core/libs/widgets/range -I /home/gilles/devel/8.x/core/libs/widgets/text -I /home/gilles/devel/8.x/core/libs/jpegutils/libjpeg/84 -I /home/gilles/devel/8.x/core/app/utils -I /home/gilles/devel/8.x/build.scan/core/app/utils -I /home/gilles/devel/8.x/core/utilities/advancedrename -I /home/gilles/devel/8.x/core/utilities/advancedrename/common -I /home/gilles/devel/8.x/core/utilities/advancedrename/parser -I /home/gilles/devel/8.x/core/utilities/advancedrename/parser/modifiers -I /home/gilles/devel/8.x/core/utilities/advancedrename/parser/options -I /home/gilles/devel/8.x/core/utilities/advancedrename/parser/options/database -I /home/gilles/devel/8.x/core/utilities/advancedrename/parser/options/database/keys -I /home/gilles/devel/8.x/core/utilities/extrasupport/addressbook -I /home/gilles/devel/8.x/core/utilities/extrasupport/filesindexer -I /home/gilles/devel/8.x/core/utilities/facemanagement/backgroundprocesses -I /home/gilles/devel/8.x/core/utilities/facemanagement/bench -I /home/gilles/devel/8.x/core/utilities/facemanagement/database -I /home/gilles/devel/8.x/core/utilities/facemanagement/dialogs -I /home/gilles/devel/8.x/core/utilities/facemanagement/items -I /home/gilles/devel/8.x/core/utilities/facemanagement/pipelines/detectrecognize -I /home/gilles/devel/8.x/core/utilities/facemanagement/pipelines/edit -I /home/gilles/devel/8.x/core/utilities/facemanagement/pipelines -I /home/gilles/devel/8.x/core/utilities/facemanagement/pipelines/recognize -I /home/gilles/devel/8.x/core/utilities/facemanagement/pipelines/reset -I /home/gilles/devel/8.x/core/utilities/facemanagement/pipelines/retrain -I /home/gilles/devel/8.x/core/utilities/facemanagement/widgets -I /home/gilles/devel/8.x/core/utilities/firstrun -I /home/gilles/devel/8.x/core/utilities/focuspointmanagement -I /home/gilles/devel/8.x/core/utilities/fuzzysearch -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/astro -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/blendings -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/core -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/geodata/data -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/geodata/graphicsitem -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/geodata/handlers/dgml -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/geodata/handlers/kml -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/geodata/parser -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/geodata/scene -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/geodata/writer -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/geodata/writers/dgml -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/geodata/writers/kml -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/graphicsview -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/layers -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/models -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/osm -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/plugins -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/plugins/render/atmosphere -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/plugins/render/compass -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/plugins/render/crosshairs -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/plugins/render/graticule -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/plugins/render/mapscale -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/plugins/render/measure -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/plugins/render/navigation -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/plugins/render/overviewmap -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/plugins/render/progress -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/plugins/runner/cache -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/plugins/runner/gpsbabel -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/plugins/runner/gpx -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/plugins/runner/gpx/handlers -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/plugins/runner/json -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/plugins/runner/kml -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/plugins/runner/nominatim-reversegeocoding -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/plugins/runner/osm -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/plugins/runner/osm/o5mreader -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/plugins/runner/osm/translators -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/plugins/runner/osm/writers -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/plugins/runner/pn2 -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/plugins/runner/pnt -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/projections -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/runners -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/settings -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/storage -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/tile -I /home/gilles/devel/8.x/core/utilities/geolocation/geoiface/backends -I /home/gilles/devel/8.x/core/utilities/geolocation/geoiface/bookmark -I /home/gilles/devel/8.x/core/utilities/geolocation/geoiface/core -I /home/gilles/devel/8.x/core/utilities/geolocation/geoiface/correlator -I /home/gilles/devel/8.x/core/utilities/geolocation/geoiface/dragdrop -I /home/gilles/devel/8.x/core/utilities/geolocation/geoiface/items -I /home/gilles/devel/8.x/core/utilities/geolocation/geoiface/lookup -I /home/gilles/devel/8.x/core/utilities/geolocation/geoiface/reversegeocoding -I /home/gilles/devel/8.x/core/utilities/geolocation/geoiface/tiles -I /home/gilles/devel/8.x/core/utilities/geolocation/geoiface/tracks -I /home/gilles/devel/8.x/core/utilities/geolocation/geoiface/widgets -I /home/gilles/devel/8.x/core/utilities/geolocation/geomapwrapper -I /home/gilles/devel/8.x/core/utilities/geolocation/mapsearches -I /home/gilles/devel/8.x/core/utilities/imageeditor/core -I /home/gilles/devel/8.x/core/utilities/imageeditor/dialogs -I /home/gilles/devel/8.x/core/utilities/imageeditor/editor -I /home/gilles/devel/8.x/core/utilities/imageeditor/main -I /home/gilles/devel/8.x/core/utilities/imageeditor/widgets -I /home/gilles/devel/8.x/core/utilities/import/backend -I /home/gilles/devel/8.x/core/utilities/import/dialogs -I /home/gilles/devel/8.x/core/utilities/import/items -I /home/gilles/devel/8.x/core/utilities/import/main -I /home/gilles/devel/8.x/core/utilities/import/models -I /home/gilles/devel/8.x/core/utilities/import/views -I /home/gilles/devel/8.x/core/utilities/import/widgets -I /home/gilles/devel/8.x/core/utilities/lighttable -I /home/gilles/devel/8.x/core/utilities/maintenance/main -I /home/gilles/devel/8.x/core/utilities/maintenance/manager -I /home/gilles/devel/8.x/core/utilities/maintenance/tools/dbcleaner -I /home/gilles/devel/8.x/core/utilities/maintenance/tools/dbscan -I /home/gilles/devel/8.x/core/utilities/maintenance/tools/duplicates -I /home/gilles/devel/8.x/core/utilities/maintenance/tools/facesmanagement -I /home/gilles/devel/8.x/core/utilities/maintenance/tools/fingerprints -I /home/gilles/devel/8.x/core/utilities/maintenance/tools/imgqsort -I /home/gilles/devel/8.x/core/utilities/maintenance/tools/metaremover -I /home/gilles/devel/8.x/core/utilities/maintenance/tools/metasync -I /home/gilles/devel/8.x/core/utilities/maintenance/tools/thumbs -I /home/gilles/devel/8.x/core/utilities/maintenance/utils -I /home/gilles/devel/8.x/core/utilities/queuemanager/dplugins -I /home/gilles/devel/8.x/core/utilities/queuemanager/main -I /home/gilles/devel/8.x/core/utilities/queuemanager/manager -I /home/gilles/devel/8.x/core/utilities/queuemanager/views -I /home/gilles/devel/8.x/core/utilities/searchwindow -I /home/gilles/devel/8.x/core/utilities/setup/album -I /home/gilles/devel/8.x/core/utilities/setup/camera -I /home/gilles/devel/8.x/core/utilities/setup/collections -I /home/gilles/devel/8.x/core/utilities/setup/downloader -I /home/gilles/devel/8.x/core/utilities/setup/editor -I /home/gilles/devel/8.x/core/utilities/setup/metadata -I /home/gilles/devel/8.x/core/utilities/setup/misc -I /home/gilles/devel/8.x/core/utilities/setup -I /home/gilles/devel/8.x/core/app/main -I /home/gilles/devel/8.x/core/app/date -I /home/gilles/devel/8.x/core/app/dragdrop -I /home/gilles/devel/8.x/core/app/views/stack -I /home/gilles/devel/8.x/core/app/views/utils -I /home/gilles/devel/8.x/core/app/items/utils -I /home/gilles/devel/8.x/core/app/items/delegate -I /home/gilles/devel/8.x/core/app/views/sidebar -I /home/gilles/devel/8.x/core/libs/dimg/filters/transform/lqr -I /opt/qt6/include/opencv4 -I /usr/include/ImageMagick-6 -I /usr/include/x86_64-linux-gnu/ImageMagick-6 -I /opt/qt6/include/QtMultimedia -I /opt/qt6/include -I /opt/qt6/include/QtCore -I /opt/qt6/mkspecs/linux-g++ -I /opt/qt6/include/QtGui -I /opt/qt6/include/QtNetwork -I /opt/qt6/include/QtMultimediaWidgets -I /opt/qt6/include/QtWidgets -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/lensfun -I /usr/include/eigen3 -I /opt/qt6/include/QtConcurrent -I /opt/qt6/include/QtXml -I /opt/qt6/include/KF6/KCoreAddons -I /opt/qt6/include/KF6/KConfig -I /opt/qt6/include/KF6/KConfigCore -I /opt/qt6/include/KF6/KI18n -I /opt/qt6/include/KF6/KWidgetsAddons -I /opt/qt6/include/QtGui/6.9.2 -I /opt/qt6/include/QtGui/6.9.2/QtGui -I /opt/qt6/include/QtCore/6.9.2 -I /opt/qt6/include/QtCore/6.9.2/QtCore -I /opt/qt6/include/QtDBus/6.9.2 -I /opt/qt6/include/QtDBus/6.9.2/QtDBus -I /opt/qt6/include/QtDBus -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/x86_64-linux-gnu/c++/13 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/backward -internal-isystem /usr/lib/llvm-19/lib/clang/19/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/13/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-long-long -Wno-deprecated-copy -std=c++20 -fdeprecated-macro -ferror-limit 19 -fvisibility=hidden -fvisibility-inlines-hidden -fno-operator-names -fopenmp -fgnuc-version=4.2.1 -fno-implicit-modules -fskip-odr-check-in-gmf -fcxx-exceptions -fexceptions -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/gilles/devel/8.x/project/reports/report.scan/2025-09-05-111736-844906-1 -x c++ /home/gilles/devel/8.x/core/libs/dimg/filters/bw/mixersettings.cpp
1/* ============================================================
2 *
3 * This file is a part of digiKam project
4 * https://www.digikam.org
5 *
6 * Date : 2009-02-18
7 * Description : Channel mixer settings view.
8 *
9 * SPDX-FileCopyrightText: 2010-2025 by Gilles Caulier <caulier dot gilles at gmail dot com>
10 *
11 * SPDX-License-Identifier: GPL-2.0-or-later
12 *
13 * ============================================================ */
14
15#include "mixersettings.h"
16
17// Qt includes
18
19#include <QGridLayout>
20#include <QLabel>
21#include <QString>
22#include <QFile>
23#include <QTextStream>
24#include <QCheckBox>
25#include <QPushButton>
26#include <QStandardPaths>
27#include <QApplication>
28#include <QStyle>
29#include <QComboBox>
30#include <QMessageBox>
31#include <QUrl>
32#include <QFontDatabase>
33
34// KDE includes
35
36#include <kconfiggroup.h>
37#include <klocalizedstring.h>
38
39// Local includes
40
41#include "dnuminput.h"
42#include "dfiledialog.h"
43#include "dexpanderbox.h"
44#include "digikam_debug.h"
45#include "digikam_config.h"
46
47namespace Digikam
48{
49
50class Q_DECL_HIDDEN__attribute__((visibility("hidden"))) MixerSettings::Private
51{
52public:
53
54 Private() = default;
55
56public:
57
58 const QString configMonochromeEntry = QLatin1String("Monochrome");
59 const QString configPreserveLuminosityEntry = QLatin1String("PreserveLuminosity");
60 const QString configRedRedGainEntry = QLatin1String("RedRedGain");
61 const QString configRedGreenGainEntry = QLatin1String("RedGreenGain");
62 const QString configRedBlueGainEntry = QLatin1String("RedBlueGain");
63 const QString configGreenRedGainEntry = QLatin1String("GreenRedGain");
64 const QString configGreenGreenGainEntry = QLatin1String("GreenGreenGain");
65 const QString configGreenBlueGainEntry = QLatin1String("GreenBlueGain");
66 const QString configBlueRedGainEntry = QLatin1String("BlueRedGain");
67 const QString configBlueGreenGainEntry = QLatin1String("BlueGreenGain");
68 const QString configBlueBlueGainEntry = QLatin1String("BlueBlueGain");
69 const QString configBlackRedGainEntry = QLatin1String("BlackRedGain");
70 const QString configBlackGreenGainEntry = QLatin1String("BlackGreenGain");
71 const QString configBlackBlueGainEntry = QLatin1String("BlackBlueGain");
72
73 int currentChannel = RedChannel;
74
75 QLabel* monochromeTips = nullptr;
76 QLabel* totalPercents = nullptr;
77 QLabel* outChannelLabel = nullptr;
78
79 QPushButton* resetButton = nullptr;
80
81 QCheckBox* preserveLuminosity = nullptr;
82 QCheckBox* monochrome = nullptr;
83
84 QComboBox* outChannelCB = nullptr;
85
86 MixerContainer mixerSettings;
87
88 DDoubleNumInput* redGain = nullptr;
89 DDoubleNumInput* greenGain = nullptr;
90 DDoubleNumInput* blueGain = nullptr;
91};
92
93// --------------------------------------------------------
94
95MixerSettings::MixerSettings(QWidget* const parent)
96 : QWidget(parent),
97 d (new Private)
98{
99 const int spacing = layoutSpacing();
100 QGridLayout* const grid = new QGridLayout(this);
101
102 d->outChannelLabel = new QLabel(i18nc("@label", "Output Channel:")i18ndc("digikam", "@label", "Output Channel:"));
103 d->outChannelCB = new QComboBox;
104 d->outChannelCB->addItem(i18nc("@item: color", "Red")i18ndc("digikam", "@item: color", "Red"), QVariant(RedChannel));
105 d->outChannelCB->addItem(i18nc("@item: color", "Green")i18ndc("digikam", "@item: color", "Green"), QVariant(GreenChannel));
106 d->outChannelCB->addItem(i18nc("@item: color", "Blue")i18ndc("digikam", "@item: color", "Blue"), QVariant(BlueChannel));
107
108 QLabel* const redLabel = new QLabel(i18nc("@label: color", "Red (%):")i18ndc("digikam", "@label: color", "Red (%):"));
109 d->redGain = new DDoubleNumInput;
110 d->redGain->setDecimals(1);
111 d->redGain->setRange(-200.0, 200.0, 1);
112 d->redGain->setDefaultValue(0);
113 d->redGain->setWhatsThis(i18nc("@info", "Select the red color gain, as a percentage, "i18ndc("digikam", "@info", "Select the red color gain, as a percentage, "
"for the current channel.")
114 "for the current channel.")i18ndc("digikam", "@info", "Select the red color gain, as a percentage, "
"for the current channel.")
);
115
116 QLabel* const greenLabel = new QLabel(i18nc("@label: color", "Green (%):")i18ndc("digikam", "@label: color", "Green (%):"));
117 d->greenGain = new DDoubleNumInput;
118 d->greenGain->setDecimals(1);
119 d->greenGain->setRange(-200.0, 200.0, 1);
120 d->greenGain->setDefaultValue(0);
121 d->greenGain->setWhatsThis(i18nc("@info", "Select the green color gain, as a percentage, "i18ndc("digikam", "@info", "Select the green color gain, as a percentage, "
"for the current channel.")
122 "for the current channel.")i18ndc("digikam", "@info", "Select the green color gain, as a percentage, "
"for the current channel.")
);
123
124 QLabel* const blueLabel = new QLabel(i18nc("@label: color", "Blue (%):")i18ndc("digikam", "@label: color", "Blue (%):"));
125 d->blueGain = new DDoubleNumInput;
126 d->blueGain->setDecimals(1);
127 d->blueGain->setRange(-200.0, 200.0, 1);
128 d->blueGain->setDefaultValue(0);
129 d->blueGain->setWhatsThis(i18nc("@info", "Select the blue color gain, as a percentage, "i18ndc("digikam", "@info", "Select the blue color gain, as a percentage, "
"for the current channel.")
130 "for the current channel.")i18ndc("digikam", "@info", "Select the blue color gain, as a percentage, "
"for the current channel.")
);
131
132 // -------------------------------------------------------------
133
134 d->resetButton = new QPushButton(i18nc("@option", "&Reset")i18ndc("digikam", "@option", "&Reset"));
135 d->resetButton->setIcon(QIcon::fromTheme(QLatin1String("document-revert")));
136 d->resetButton->setWhatsThis(i18nc("@info", "Reset color channels' gains settings from "i18ndc("digikam", "@info", "Reset color channels' gains settings from "
"the currently selected channel.")
137 "the currently selected channel.")i18ndc("digikam", "@info", "Reset color channels' gains settings from "
"the currently selected channel.")
);
138
139 d->totalPercents = new QLabel();
140 d->totalPercents->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
141
142 // -------------------------------------------------------------
143
144 d->preserveLuminosity = new QCheckBox(i18nc("@option", "Preserve luminosity")i18ndc("digikam", "@option", "Preserve luminosity"));
145 d->preserveLuminosity->setWhatsThis(i18nc("@info", "Enable this option if you want preserve "i18ndc("digikam", "@info", "Enable this option if you want preserve "
"the image luminosity.")
146 "the image luminosity.")i18ndc("digikam", "@info", "Enable this option if you want preserve "
"the image luminosity.")
);
147
148 // -------------------------------------------------------------
149
150 d->monochrome = new QCheckBox(i18nc("@option: color", "Monochrome")i18ndc("digikam", "@option: color", "Monochrome"));
151 d->monochromeTips = new QLabel(i18nc("@info: help",i18ndc("digikam", "@info: help", "Use \"Monochrome\" mode to convert color picture to Black and White:\n"
"The \"red channel\" modifies the contrast of photograph.\n"
"The \"green channel\" enhances or reduces the details level of photograph.\n"
"The \"blue channel\" affects the noise of photograph.\n" "Note: in this mode, the histogram will display only luminosity values."
)
152 "Use \"Monochrome\" mode to convert color picture to Black and White:\n"i18ndc("digikam", "@info: help", "Use \"Monochrome\" mode to convert color picture to Black and White:\n"
"The \"red channel\" modifies the contrast of photograph.\n"
"The \"green channel\" enhances or reduces the details level of photograph.\n"
"The \"blue channel\" affects the noise of photograph.\n" "Note: in this mode, the histogram will display only luminosity values."
)
153 "The \"red channel\" modifies the contrast of photograph.\n"i18ndc("digikam", "@info: help", "Use \"Monochrome\" mode to convert color picture to Black and White:\n"
"The \"red channel\" modifies the contrast of photograph.\n"
"The \"green channel\" enhances or reduces the details level of photograph.\n"
"The \"blue channel\" affects the noise of photograph.\n" "Note: in this mode, the histogram will display only luminosity values."
)
154 "The \"green channel\" enhances or reduces the details level of photograph.\n"i18ndc("digikam", "@info: help", "Use \"Monochrome\" mode to convert color picture to Black and White:\n"
"The \"red channel\" modifies the contrast of photograph.\n"
"The \"green channel\" enhances or reduces the details level of photograph.\n"
"The \"blue channel\" affects the noise of photograph.\n" "Note: in this mode, the histogram will display only luminosity values."
)
155 "The \"blue channel\" affects the noise of photograph.\n"i18ndc("digikam", "@info: help", "Use \"Monochrome\" mode to convert color picture to Black and White:\n"
"The \"red channel\" modifies the contrast of photograph.\n"
"The \"green channel\" enhances or reduces the details level of photograph.\n"
"The \"blue channel\" affects the noise of photograph.\n" "Note: in this mode, the histogram will display only luminosity values."
)
156 "Note: in this mode, the histogram will display only luminosity values.")i18ndc("digikam", "@info: help", "Use \"Monochrome\" mode to convert color picture to Black and White:\n"
"The \"red channel\" modifies the contrast of photograph.\n"
"The \"green channel\" enhances or reduces the details level of photograph.\n"
"The \"blue channel\" affects the noise of photograph.\n" "Note: in this mode, the histogram will display only luminosity values."
)
);
157
158 d->monochromeTips->setEnabled(false);
159 d->monochromeTips->setFont(QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont));
160 d->monochromeTips->setWordWrap(true);
161 d->monochromeTips->setOpenExternalLinks(true);
162 d->monochromeTips->setFrameStyle(QFrame::StyledPanel | QFrame::Raised);
163 d->monochromeTips->setLineWidth(1);
164
165 // -------------------------------------------------------------
166
167 grid->addWidget(d->outChannelLabel, 0, 0, 1, 1);
168 grid->addWidget(d->outChannelCB, 0, 3, 1, 2);
169 grid->addWidget(redLabel, 1, 0, 1, 1);
170 grid->addWidget(d->redGain, 1, 1, 1, 4);
171 grid->addWidget(greenLabel, 2, 0, 1, 1);
172 grid->addWidget(d->greenGain, 2, 1, 1, 4);
173 grid->addWidget(blueLabel, 3, 0, 1, 1);
174 grid->addWidget(d->blueGain, 3, 1, 1, 4);
175 grid->addWidget(d->resetButton, 4, 0, 1, 2);
176 grid->addWidget(d->totalPercents, 4, 3, 1, 1);
177 grid->addWidget(d->preserveLuminosity, 5, 0, 1, 5);
178 grid->addWidget(d->monochrome, 6, 0, 1, 5);
179 grid->addWidget(d->monochromeTips, 7, 0, 1, 5);
180 grid->setRowStretch(8, 10);
181 grid->setColumnStretch(2, 10);
182 grid->setContentsMargins(spacing, spacing, spacing, spacing);
183 grid->setSpacing(spacing);
184
185 // -------------------------------------------------------------
186
187 connect(d->redGain, SIGNAL(valueChanged(double))qFlagLocation("2" "valueChanged(double)" "\0" "/home/gilles/devel/8.x/core/libs/dimg/filters/bw/mixersettings.cpp"
":" "187")
,
188 this, SLOT(slotGainsChanged())qFlagLocation("1" "slotGainsChanged()" "\0" "/home/gilles/devel/8.x/core/libs/dimg/filters/bw/mixersettings.cpp"
":" "188")
);
189
190 connect(d->greenGain, SIGNAL(valueChanged(double))qFlagLocation("2" "valueChanged(double)" "\0" "/home/gilles/devel/8.x/core/libs/dimg/filters/bw/mixersettings.cpp"
":" "190")
,
191 this, SLOT(slotGainsChanged())qFlagLocation("1" "slotGainsChanged()" "\0" "/home/gilles/devel/8.x/core/libs/dimg/filters/bw/mixersettings.cpp"
":" "191")
);
192
193 connect(d->blueGain, SIGNAL(valueChanged(double))qFlagLocation("2" "valueChanged(double)" "\0" "/home/gilles/devel/8.x/core/libs/dimg/filters/bw/mixersettings.cpp"
":" "193")
,
194 this, SLOT(slotGainsChanged())qFlagLocation("1" "slotGainsChanged()" "\0" "/home/gilles/devel/8.x/core/libs/dimg/filters/bw/mixersettings.cpp"
":" "194")
);
195
196 connect(d->resetButton, SIGNAL(clicked())qFlagLocation("2" "clicked()" "\0" "/home/gilles/devel/8.x/core/libs/dimg/filters/bw/mixersettings.cpp"
":" "196")
,
197 this, SLOT(slotResetCurrentChannel())qFlagLocation("1" "slotResetCurrentChannel()" "\0" "/home/gilles/devel/8.x/core/libs/dimg/filters/bw/mixersettings.cpp"
":" "197")
);
198
199 connect(d->monochrome, SIGNAL(toggled(bool))qFlagLocation("2" "toggled(bool)" "\0" "/home/gilles/devel/8.x/core/libs/dimg/filters/bw/mixersettings.cpp"
":" "199")
,
200 this, SLOT(slotMonochromeActived(bool))qFlagLocation("1" "slotMonochromeActived(bool)" "\0" "/home/gilles/devel/8.x/core/libs/dimg/filters/bw/mixersettings.cpp"
":" "200")
);
201
202 connect(d->preserveLuminosity, SIGNAL(toggled(bool))qFlagLocation("2" "toggled(bool)" "\0" "/home/gilles/devel/8.x/core/libs/dimg/filters/bw/mixersettings.cpp"
":" "202")
,
203 this, SLOT(slotLuminosityChanged(bool))qFlagLocation("1" "slotLuminosityChanged(bool)" "\0" "/home/gilles/devel/8.x/core/libs/dimg/filters/bw/mixersettings.cpp"
":" "203")
);
204
205 connect(d->outChannelCB, SIGNAL(activated(int))qFlagLocation("2" "activated(int)" "\0" "/home/gilles/devel/8.x/core/libs/dimg/filters/bw/mixersettings.cpp"
":" "205")
,
206 this, SLOT(slotOutChannelChanged())qFlagLocation("1" "slotOutChannelChanged()" "\0" "/home/gilles/devel/8.x/core/libs/dimg/filters/bw/mixersettings.cpp"
":" "206")
);
207}
208
209MixerSettings::~MixerSettings()
210{
211 delete d;
212}
213
214void MixerSettings::setMonochromeTipsVisible(bool b)
215{
216 b ? d->monochromeTips->show()
217 : d->monochromeTips->hide();
218}
219
220void MixerSettings::slotOutChannelChanged()
221{
222 int index = d->outChannelCB->currentIndex();
223 d->currentChannel = (ChannelType)(d->outChannelCB->itemData(index).toInt());
224 updateSettingsWidgets();
225 Q_EMIT signalOutChannelChanged();
226}
227
228int MixerSettings::currentChannel() const
229{
230 return d->currentChannel;
231}
232
233void MixerSettings::slotResetCurrentChannel()
234{
235 switch (d->currentChannel)
236 {
237 case GreenChannel:
238 {
239 d->mixerSettings.greenRedGain = 0.0;
240 d->mixerSettings.greenGreenGain = 1.0;
241 d->mixerSettings.greenBlueGain = 0.0;
242 break;
243 }
244
245 case BlueChannel:
246 {
247 d->mixerSettings.blueRedGain = 0.0;
248 d->mixerSettings.blueGreenGain = 0.0;
249 d->mixerSettings.blueBlueGain = 1.0;
250 break;
251 }
252
253 default: // Red or monochrome.
254 {
255 if (d->monochrome->isChecked())
256 {
257 d->mixerSettings.blackRedGain = 1.0;
258 d->mixerSettings.blackGreenGain = 0.0;
259 d->mixerSettings.blackBlueGain = 0.0;
260 }
261 else
262 {
263 d->mixerSettings.redRedGain = 1.0;
264 d->mixerSettings.redGreenGain = 0.0;
265 d->mixerSettings.redBlueGain = 0.0;
266 }
267
268 break;
269 }
270 }
271
272 updateSettingsWidgets();
273
274 Q_EMIT signalSettingsChanged();
275}
276
277void MixerSettings::slotGainsChanged()
278{
279 switch (d->currentChannel)
280 {
281 case GreenChannel:
282 {
283 d->mixerSettings.greenRedGain = d->redGain->value() / 100.0;
284 d->mixerSettings.greenGreenGain = d->greenGain->value() / 100.0;
285 d->mixerSettings.greenBlueGain = d->blueGain->value() / 100.0;
286 break;
287 }
288
289 case BlueChannel:
290 {
291 d->mixerSettings.blueRedGain = d->redGain->value() / 100.0;
292 d->mixerSettings.blueGreenGain = d->greenGain->value() / 100.0;
293 d->mixerSettings.blueBlueGain = d->blueGain->value() / 100.0;
294 break;
295 }
296
297 default: // Red or monochrome.
298 {
299 if (d->monochrome->isChecked())
300 {
301 d->mixerSettings.blackRedGain = d->redGain->value() / 100.0;
302 d->mixerSettings.blackGreenGain = d->greenGain->value() / 100.0;
303 d->mixerSettings.blackBlueGain = d->blueGain->value() / 100.0;
304 }
305 else
306 {
307 d->mixerSettings.redRedGain = d->redGain->value() / 100.0;
308 d->mixerSettings.redGreenGain = d->greenGain->value() / 100.0;
309 d->mixerSettings.redBlueGain = d->blueGain->value() / 100.0;
310 }
311
312 break;
313 }
314 }
315
316 updateTotalPercents();
317
318 Q_EMIT signalSettingsChanged();
319}
320
321void MixerSettings::updateTotalPercents()
322{
323 double total = d->redGain->value() + d->greenGain->value() + d->blueGain->value();
324 QString str;
325 d->totalPercents->setText(i18nc("@info: progress", "Total: %1 (%)", str.asprintf("%3.1f", total))i18ndc("digikam", "@info: progress", "Total: %1 (%)", str.asprintf
("%3.1f", total))
);
326}
327
328void MixerSettings::updateSettingsWidgets()
329{
330 d->monochrome->blockSignals(true);
331 d->preserveLuminosity->blockSignals(true);
332 d->redGain->blockSignals(true);
333 d->greenGain->blockSignals(true);
334 d->blueGain->blockSignals(true);
335
336 switch (d->currentChannel)
337 {
338 case GreenChannel:
339 {
340 d->redGain->setDefaultValue(0);
341 d->greenGain->setDefaultValue(100);
342 d->blueGain->setDefaultValue(0);
343 d->redGain->setValue(d->mixerSettings.greenRedGain * 100.0);
344 d->greenGain->setValue(d->mixerSettings.greenGreenGain * 100.0);
345 d->blueGain->setValue(d->mixerSettings.greenBlueGain * 100.0);
346 break;
347 }
348
349 case BlueChannel:
350 {
351 d->redGain->setDefaultValue(0);
352 d->greenGain->setDefaultValue(0);
353 d->blueGain->setDefaultValue(100);
354 d->redGain->setValue(d->mixerSettings.blueRedGain * 100.0);
355 d->greenGain->setValue(d->mixerSettings.blueGreenGain * 100.0);
356 d->blueGain->setValue(d->mixerSettings.blueBlueGain * 100.0);
357 break;
358 }
359
360 default: // Red or monochrome.
361 {
362 if (d->monochrome->isChecked())
363 {
364 d->redGain->setDefaultValue(100);
365 d->greenGain->setDefaultValue(0);
366 d->blueGain->setDefaultValue(0);
367 d->redGain->setValue(d->mixerSettings.blackRedGain * 100.0);
368 d->greenGain->setValue(d->mixerSettings.blackGreenGain * 100.0);
369 d->blueGain->setValue(d->mixerSettings.blackBlueGain * 100.0);
370 }
371 else
372 {
373 d->redGain->setDefaultValue(100);
374 d->greenGain->setDefaultValue(0);
375 d->blueGain->setDefaultValue(0);
376 d->redGain->setValue(d->mixerSettings.redRedGain * 100.0);
377 d->greenGain->setValue(d->mixerSettings.redGreenGain * 100.0);
378 d->blueGain->setValue(d->mixerSettings.redBlueGain * 100.0);
379 }
380
381 break;
382 }
383 }
384
385 d->monochrome->setChecked(d->mixerSettings.bMonochrome);
386 d->preserveLuminosity->setChecked(d->mixerSettings.bPreserveLum);
387 updateTotalPercents();
388
389 d->monochrome->blockSignals(false);
390 d->preserveLuminosity->blockSignals(false);
391 d->redGain->blockSignals(false);
392 d->greenGain->blockSignals(false);
393 d->blueGain->blockSignals(false);
394}
395
396void MixerSettings::slotMonochromeActived(bool mono)
397{
398 d->mixerSettings.bMonochrome = mono;
399 d->monochromeTips->setEnabled(mono);
400
401 d->outChannelLabel->setEnabled(!mono);
402 d->outChannelCB->setEnabled(!mono);
403 int id = d->outChannelCB->findData(QVariant(RedChannel));
404 d->outChannelCB->setCurrentIndex(id);
405 slotOutChannelChanged();
406
407 Q_EMIT signalMonochromeActived(mono);
408 Q_EMIT signalSettingsChanged();
409}
410
411void MixerSettings::slotLuminosityChanged(bool lum)
412{
413 d->mixerSettings.bPreserveLum = lum;
414
415 Q_EMIT signalSettingsChanged();
416}
417
418MixerContainer MixerSettings::settings() const
419{
420 return d->mixerSettings;
421}
422
423void MixerSettings::setSettings(const MixerContainer& settings)
424{
425 blockSignals(true);
426 d->mixerSettings = settings;
427 updateSettingsWidgets();
428 slotMonochromeActived(d->mixerSettings.bMonochrome);
429 blockSignals(false);
430}
431
432void MixerSettings::resetToDefault()
433{
434 setSettings(defaultSettings());
435}
436
437MixerContainer MixerSettings::defaultSettings() const
438{
439 MixerContainer prm;
440
441 prm.bMonochrome = false;
442 prm.bPreserveLum = true;
443
444 prm.redRedGain = 1.0;
445 prm.redGreenGain = 0.0;
446 prm.redBlueGain = 0.0;
447
448 prm.greenRedGain = 0.0;
449 prm.greenGreenGain = 1.0;
450 prm.greenBlueGain = 0.0;
451
452 prm.blueRedGain = 0.0;
453 prm.blueGreenGain = 0.0;
454 prm.blueBlueGain = 1.0;
455
456 prm.blackRedGain = 1.0;
457 prm.blackGreenGain = 0.0;
458 prm.blackBlueGain = 0.0;
459
460 return prm;
461}
462
463void MixerSettings::readSettings(const KConfigGroup& group)
464{
465 MixerContainer prm;
466 MixerContainer defaultPrm = defaultSettings();
467
468 prm.bMonochrome = group.readEntry(d->configMonochromeEntry, defaultPrm.bMonochrome);
469 prm.bPreserveLum = group.readEntry(d->configPreserveLuminosityEntry, defaultPrm.bPreserveLum);
470
471 prm.redRedGain = group.readEntry(d->configRedRedGainEntry, defaultPrm.redRedGain);
472 prm.redGreenGain = group.readEntry(d->configRedGreenGainEntry, defaultPrm.redGreenGain);
473 prm.redBlueGain = group.readEntry(d->configRedBlueGainEntry, defaultPrm.redBlueGain);
474
475 prm.greenRedGain = group.readEntry(d->configGreenRedGainEntry, defaultPrm.greenRedGain);
476 prm.greenGreenGain = group.readEntry(d->configGreenGreenGainEntry, defaultPrm.greenGreenGain);
477 prm.greenBlueGain = group.readEntry(d->configGreenBlueGainEntry, defaultPrm.greenBlueGain);
478
479 prm.blueRedGain = group.readEntry(d->configBlueRedGainEntry, defaultPrm.blueRedGain);
480 prm.blueGreenGain = group.readEntry(d->configBlueGreenGainEntry, defaultPrm.blueGreenGain);
481 prm.blueBlueGain = group.readEntry(d->configBlueBlueGainEntry, defaultPrm.blueBlueGain);
482
483 prm.blackRedGain = group.readEntry(d->configBlackRedGainEntry, defaultPrm.blackRedGain);
484 prm.blackGreenGain = group.readEntry(d->configBlackGreenGainEntry, defaultPrm.blackGreenGain);
485 prm.blackBlueGain = group.readEntry(d->configBlackBlueGainEntry, defaultPrm.blackBlueGain);
486
487 setSettings(prm);
488}
489
490void MixerSettings::writeSettings(KConfigGroup& group)
491{
492 MixerContainer prm = settings();
493
494 group.writeEntry(d->configMonochromeEntry, prm.bMonochrome);
495 group.writeEntry(d->configPreserveLuminosityEntry, prm.bPreserveLum);
496
497 group.writeEntry(d->configRedRedGainEntry, prm.redRedGain);
498 group.writeEntry(d->configRedGreenGainEntry, prm.redGreenGain);
499 group.writeEntry(d->configRedBlueGainEntry, prm.redBlueGain);
500
501 group.writeEntry(d->configGreenRedGainEntry, prm.greenRedGain);
502 group.writeEntry(d->configGreenGreenGainEntry, prm.greenGreenGain);
503 group.writeEntry(d->configGreenBlueGainEntry, prm.greenBlueGain);
504
505 group.writeEntry(d->configBlueRedGainEntry, prm.blueRedGain);
506 group.writeEntry(d->configBlueGreenGainEntry, prm.blueGreenGain);
507 group.writeEntry(d->configBlueBlueGainEntry, prm.blueBlueGain);
508
509 group.writeEntry(d->configBlackRedGainEntry, prm.blackRedGain);
510 group.writeEntry(d->configBlackGreenGainEntry, prm.blackGreenGain);
511 group.writeEntry(d->configBlackBlueGainEntry, prm.blackBlueGain);
512}
513
514void MixerSettings::loadSettings()
515{
516 QUrl loadGainsFileUrl;
517 FILE* fp = nullptr;
518 MixerContainer settings;
519
520 loadGainsFileUrl = DFileDialog::getOpenFileUrl(qApp(static_cast<QApplication *>(QCoreApplication::instance
()))
->activeWindow(),
521 i18nc("@title:window", "Select Gimp Gains Mixer File to Load")i18ndc("digikam", "@title:window", "Select Gimp Gains Mixer File to Load"
)
,
522 QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation)),
523 QLatin1String("*"));
524
525 if (loadGainsFileUrl.isEmpty())
1
Assuming the condition is false
2
Taking false branch
526 {
527 return;
528 }
529
530#ifdef Q_OS_WIN
531
532 fp = _wfopen((const wchar_t*)loadGainsFileUrl.toLocalFile().utf16(), L"r");
533
534#else
535
536 fp = fopen(loadGainsFileUrl.toLocalFile().toUtf8().constData(), "r");
537
538#endif
539
540 if (fp
2.1
'fp' is non-null
)
3
Taking true branch
541 {
542 char buf1[1024] = { 0 };
543 char buf2[1024] = { 0 };
544 char buf3[1024] = { 0 };
545
546 buf1[0] = '\0';
547
548 fgets(buf1, 1023, fp);
4
Assuming this stream operation fails
549
550 fscanf(fp, "%*s %256s", buf1);
5
File position of the stream might be 'indeterminate' after a failed operation. Can cause undefined behavior
551 fscanf(fp, "%*s %256s", buf1); // preview flag, preserved for compatibility
552 fscanf(fp, "%*s %256s", buf1);
553
554 if (strcmp(buf1, "true") == 0)
555 {
556 settings.bMonochrome = true;
557 }
558 else
559 {
560 settings.bMonochrome = false;
561 }
562
563 fscanf(fp, "%*s %256s", buf1);
564
565 if (strcmp(buf1, "true") == 0)
566 {
567 settings.bPreserveLum = true;
568 }
569 else
570 {
571 settings.bPreserveLum = false;
572 }
573
574 fscanf(fp, "%*s %256s %256s %256s", buf1, buf2, buf3);
575 settings.redRedGain = atof(buf1);
576 settings.redGreenGain = atof(buf2);
577 settings.redBlueGain = atof(buf3);
578
579 fscanf(fp, "%*s %256s %256s %256s", buf1, buf2, buf3);
580 settings.greenRedGain = atof(buf1);
581 settings.greenGreenGain = atof(buf2);
582 settings.greenBlueGain = atof(buf3);
583
584 fscanf(fp, "%*s %256s %256s %256s", buf1, buf2, buf3);
585 settings.blueRedGain = atof(buf1);
586 settings.blueGreenGain = atof(buf2);
587 settings.blueBlueGain = atof(buf3);
588
589 fscanf(fp, "%*s %256s %256s %256s", buf1, buf2, buf3);
590 settings.blackRedGain = atof(buf1);
591 settings.blackGreenGain = atof(buf2);
592 settings.blackBlueGain = atof(buf3);
593
594 fclose(fp);
595
596 setSettings(settings);
597 }
598 else
599 {
600 QMessageBox::critical(qApp(static_cast<QApplication *>(QCoreApplication::instance
()))
->activeWindow(), qApp(static_cast<QApplication *>(QCoreApplication::instance
()))
->applicationName(),
601 i18nc("@info", "Cannot load settings from the Gains Mixer text file.")i18ndc("digikam", "@info", "Cannot load settings from the Gains Mixer text file."
)
);
602 return;
603 }
604}
605
606void MixerSettings::saveAsSettings()
607{
608 QUrl saveGainsFileUrl;
609 FILE* fp = nullptr;
610
611 saveGainsFileUrl = DFileDialog::getSaveFileUrl(qApp(static_cast<QApplication *>(QCoreApplication::instance
()))
->activeWindow(), i18nc("@title:window", "Gimp Gains Mixer File to Save")i18ndc("digikam", "@title:window", "Gimp Gains Mixer File to Save"
)
,
612 QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation)),
613 QLatin1String("*"));
614
615 if (saveGainsFileUrl.isEmpty())
616 {
617 return;
618 }
619
620#ifdef Q_OS_WIN
621
622 fp = _wfopen((const wchar_t*)saveGainsFileUrl.toLocalFile().utf16(), L"w");
623
624#else
625
626 fp = fopen(saveGainsFileUrl.toLocalFile().toUtf8().constData(), "w");
627
628#endif
629
630 if (fp)
631 {
632 const char* str = nullptr;
633 char buf1[256];
634 char buf2[256];
635 char buf3[256];
636
637 switch (d->currentChannel)
638 {
639 case RedChannel:
640 str = "RED";
641 break;
642
643 case GreenChannel:
644 str = "GREEN";
645 break;
646
647 case BlueChannel:
648 str = "BLUE";
649 break;
650
651 default:
652 qCWarning(DIGIKAM_DIMG_LOG)for (QLoggingCategoryMacroHolder<QtWarningMsg> qt_category
((DIGIKAM_DIMG_LOG)()); qt_category; qt_category.control = false
) QMessageLogger(static_cast<const char *>("/home/gilles/devel/8.x/core/libs/dimg/filters/bw/mixersettings.cpp"
), 652, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).warning()
<< "Unknown Color channel gains";
653 break;
654 }
655
656 fprintf(fp, "# Channel Mixer Configuration File\n");
657
658 fprintf(fp, "CHANNEL: %s\n", str);
659 fprintf(fp, "PREVIEW: %s\n", "true"); // preserved for compatibility
660 fprintf(fp, "MONOCHROME: %s\n",
661 d->mixerSettings.bMonochrome ? "true" : "false");
662 fprintf(fp, "PRESERVE_LUMINOSITY: %s\n",
663 d->mixerSettings.bPreserveLum ? "true" : "false");
664
665 snprintf(buf1, sizeof(buf1), "%5.3f", d->mixerSettings.redRedGain);
666 snprintf(buf2, sizeof(buf2), "%5.3f", d->mixerSettings.redGreenGain);
667 snprintf(buf3, sizeof(buf3), "%5.3f", d->mixerSettings.redBlueGain);
668 fprintf(fp, "RED: %s %s %s\n", buf1, buf2, buf3);
669
670 snprintf(buf1, sizeof(buf1), "%5.3f", d->mixerSettings.greenRedGain);
671 snprintf(buf2, sizeof(buf2), "%5.3f", d->mixerSettings.greenGreenGain);
672 snprintf(buf3, sizeof(buf3), "%5.3f", d->mixerSettings.greenBlueGain);
673 fprintf(fp, "GREEN: %s %s %s\n", buf1, buf2, buf3);
674
675 snprintf(buf1, sizeof(buf1), "%5.3f", d->mixerSettings.blueRedGain);
676 snprintf(buf2, sizeof(buf2), "%5.3f", d->mixerSettings.blueGreenGain);
677 snprintf(buf3, sizeof(buf3), "%5.3f", d->mixerSettings.blueBlueGain);
678 fprintf(fp, "BLUE: %s %s %s\n", buf1, buf2, buf3);
679
680 snprintf(buf1, sizeof(buf1), "%5.3f", d->mixerSettings.blackRedGain);
681 snprintf(buf2, sizeof(buf2), "%5.3f", d->mixerSettings.blackGreenGain);
682 snprintf(buf3, sizeof(buf3), "%5.3f", d->mixerSettings.blackBlueGain);
683 fprintf(fp, "BLACK: %s %s %s\n", buf1, buf2, buf3);
684
685 fclose(fp);
686 }
687 else
688 {
689 QMessageBox::critical(qApp(static_cast<QApplication *>(QCoreApplication::instance
()))
->activeWindow(), qApp(static_cast<QApplication *>(QCoreApplication::instance
()))
->applicationName(),
690 i18nc("@info", "Cannot save settings to the Gains Mixer text file.")i18ndc("digikam", "@info", "Cannot save settings to the Gains Mixer text file."
)
);
691 return;
692 }
693}
694
695} // namespace Digikam
696
697#include "moc_mixersettings.cpp"