Bug Summary

File:/home/gilles/Devel/8.x/core/libs/dimg/filters/lc/localcontrastfilter.cpp
Warning:line 206, column 48
The left operand of '*' is a garbage value

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple aarch64-unknown-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name localcontrastfilter.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=non-leaf -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu generic -target-feature +v8a -target-feature +fp-armv8 -target-feature +neon -target-abi aapcs -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-18/lib/clang/18 -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 LIBPGF_DISABLE_OPENMP -D LINKING_XMPCORE_LIB=1 -D MAGICKCORE_HDRI_ENABLE=0 -D MAGICKCORE_QUANTUM_DEPTH=16 -D QT_DEPRECATED_WARNINGS -D QT_DEPRECATED_WARNINGS_SINCE=0x060000 -D QT_DISABLE_DEPRECATED_BEFORE=0x050E00 -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/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/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/preprocessing -I /home/gilles/Devel/8.x/core/libs/facesengine/preprocessing/recognition -I /home/gilles/Devel/8.x/core/libs/facesengine/preprocessing/shape-predictor -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/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/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/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/model -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/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/threads -I /home/gilles/Devel/8.x/core/utilities/facemanagement/widgets -I /home/gilles/Devel/8.x/core/utilities/facemanagement/workers -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/autotags -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 /usr/include/opencv4 -I /usr/include/ImageMagick-6 -I /usr/include/aarch64-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/aarch64-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.8.0 -I /opt/qt6/include/QtGui/6.8.0/QtGui -I /opt/qt6/include/QtCore/6.8.0 -I /opt/qt6/include/QtCore/6.8.0/QtCore -I /opt/qt6/include/QtDBus/6.8.0 -I /opt/qt6/include/QtDBus/6.8.0/QtDBus -internal-isystem /usr/lib/gcc/aarch64-linux-gnu/13/../../../../include/c++/13 -internal-isystem /usr/lib/gcc/aarch64-linux-gnu/13/../../../../include/aarch64-linux-gnu/c++/13 -internal-isystem /usr/lib/gcc/aarch64-linux-gnu/13/../../../../include/c++/13/backward -internal-isystem /usr/lib/llvm-18/lib/clang/18/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/aarch64-linux-gnu/13/../../../../aarch64-linux-gnu/include -internal-externc-isystem /usr/include/aarch64-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 -fno-signed-char -fgnuc-version=4.2.1 -fno-implicit-modules -fskip-odr-check-in-gmf -fcxx-exceptions -fexceptions -analyzer-output=html -target-feature +outline-atomics -target-feature -fmv -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /mnt/data/Devel/8.x/project/reports/report.scan/2024-11-03-085830-479945-1 -x c++ /home/gilles/Devel/8.x/core/libs/dimg/filters/lc/localcontrastfilter.cpp

/home/gilles/Devel/8.x/core/libs/dimg/filters/lc/localcontrastfilter.cpp

1/* ============================================================
2 *
3 * This file is a part of digiKam project
4 * https://www.digikam.org
5 *
6 * Date : 2009-08-09
7 * Description : Enhance image with local contrasts (as human eye does).
8 * LDR ToneMapper <zynaddsubfx.sourceforge.net/other/tonemapping>
9 *
10 * SPDX-FileCopyrightText: 2009 by Nasca Octavian Paul <zynaddsubfx at yahoo dot com>
11 * SPDX-FileCopyrightText: 2009 by Julien Pontabry <julien dot pontabry at gmail dot com>
12 * SPDX-FileCopyrightText: 2009-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
13 * SPDX-FileCopyrightText: 2010 by Martin Klapetek <martin dot klapetek at gmail dot com>
14 *
15 * SPDX-License-Identifier: GPL-2.0-or-later
16 *
17 * ============================================================ */
18
19#include "localcontrastfilter.h"
20
21// Qt includes
22
23#include <QtMath>
24#include <QtConcurrent> // krazy:exclude=includes
25
26// Local includes
27
28#include "digikam_debug.h"
29#include "randomnumbergenerator.h"
30#include "digikam_globals_p.h" // For KF6::Ki18n deprecated
31
32namespace Digikam
33{
34
35class Q_DECL_HIDDEN__attribute__((visibility("hidden"))) LocalContrastFilter::Private
36{
37public:
38
39 Private() = default;
40
41 /// preprocessed values
42 float current_process_power_value = 20.0F;
43
44 LocalContrastContainer par;
45
46 RandomNumberGenerator generator;
47};
48
49LocalContrastFilter::LocalContrastFilter(QObject* const parent)
50 : DImgThreadedFilter(parent),
51 d (new Private)
52{
53 initFilter();
54}
55
56LocalContrastFilter::LocalContrastFilter(DImg* const image, QObject* const parent, const LocalContrastContainer& par)
57 : DImgThreadedFilter(image, parent, QLatin1String("LocalContrast")),
58 d (new Private)
59{
60 d->par = par;
61 d->generator.seedByTime();
62 initFilter();
63}
64
65LocalContrastFilter::~LocalContrastFilter()
66{
67 cancelFilter();
68
69 delete d;
70}
71
72QString LocalContrastFilter::DisplayableName()
73{
74 return QString::fromUtf8(I18N_NOOP("Local Contrast Filter")kli18n("Local Contrast Filter").untranslatedText());
75}
76
77void LocalContrastFilter::filterImage()
78{
79 if (!m_orgImage.isNull())
1
Assuming the condition is true
2
Taking true branch
80 {
81 int size = m_orgImage.width() * m_orgImage.height() * 3;
82 int i, j;
83
84 d->generator.reseed();
85
86 if (m_orgImage.sixteenBit())
3
Assuming the condition is true
4
Taking true branch
87 {
88 // sixteen bit image
89
90 QScopedArrayPointer<unsigned short> data(new unsigned short[size] {});
91 unsigned short* dataImg = reinterpret_cast<unsigned short*>(m_orgImage.bits());
92
93 for (i = 0, j = 0 ; runningFlag() && (i < size) ; i += 3, j += 4)
5
Assuming the condition is false
94 {
95 data[i] = dataImg[j];
96 data[i + 1] = dataImg[j + 1];
97 data[i + 2] = dataImg[j + 2];
98 }
99
100 postProgress(10);
101
102 process16bitRgbImage(data.data(), m_orgImage.width(), m_orgImage.height());
6
Calling 'LocalContrastFilter::process16bitRgbImage'
103
104 for (uint x = 0 ; runningFlag() && (x < m_orgImage.width()) ; ++x)
105 {
106 for (uint y = 0 ; runningFlag() && (y < m_orgImage.height()) ; ++y)
107 {
108 i = (m_orgImage.width() * y + x) * 3;
109 m_destImage.setPixelColor(x, y, DColor((unsigned short)data[i + 2],
110 (unsigned short)data[i + 1],
111 (unsigned short)data[i],
112 65535, true));
113 }
114 }
115
116 postProgress(90);
117 }
118 else
119 {
120 // eight bit image
121
122 QScopedArrayPointer<uchar> data(new uchar[size] {});
123
124 for (i = 0, j = 0 ; runningFlag() && (i < size) ; i += 3, j += 4)
125 {
126 data[i] = m_orgImage.bits()[j];
127 data[i + 1] = m_orgImage.bits()[j + 1];
128 data[i + 2] = m_orgImage.bits()[j + 2];
129 }
130
131 postProgress(10);
132
133 process8bitRgbImage(data.data(), m_orgImage.width(), m_orgImage.height());
134
135 for (uint x = 0 ; runningFlag() && (x < m_orgImage.width()) ; ++x)
136 {
137 for (uint y = 0 ; runningFlag() && (y < m_orgImage.height()) ; ++y)
138 {
139 i = (m_orgImage.width() * y + x) * 3;
140 m_destImage.setPixelColor(x, y, DColor(data[i + 2], data[i + 1], data[i], 255, false));
141 }
142 }
143
144 postProgress(90);
145 }
146 }
147
148 postProgress(100);
149}
150
151void LocalContrastFilter::process8bitRgbImage(unsigned char* const img, int sizex, int sizey)
152{
153 int size = sizex * sizey;
154 QScopedArrayPointer<float> tmpimage(new float[size * 3] {});
155
156 for (int i = 0 ; runningFlag() && (i < size * 3) ; ++i)
157 {
158 // convert to floating point
159
160 tmpimage[i] = (float)(img[i] / 255.0);
161 }
162
163 postProgress(20);
164
165 processRgbImage(tmpimage.data(), sizex, sizey);
166
167 // convert back to 8 bits (with dithering)
168
169 int pos = 0;
170
171 for (int i = 0 ; runningFlag() && (i < size) ; ++i)
172 {
173 float dither = d->generator.number(0.0, 1.0);
174 img[pos] = (int)(tmpimage[pos] * 255.0 + dither);
175 img[pos + 1] = (int)(tmpimage[pos + 1] * 255.0 + dither);
176 img[pos + 2] = (int)(tmpimage[pos + 2] * 255.0 + dither);
177 pos += 3;
178 }
179
180 postProgress(80);
181}
182
183void LocalContrastFilter::process16bitRgbImage(unsigned short* const img, int sizex, int sizey)
184{
185 int size = sizex * sizey;
186 QScopedArrayPointer<float> tmpimage(new float[size * 3]);
7
Storing uninitialized value
8
Calling constructor for 'QScopedArrayPointer<float, QScopedPointerArrayDeleter<float>>'
11
Returning from constructor for 'QScopedArrayPointer<float, QScopedPointerArrayDeleter<float>>'
187
188 for (int i = 0 ; runningFlag() && (i < size * 3) ; ++i)
12
Assuming the condition is false
189 {
190 // convert to floating point
191
192 tmpimage[i] = (float)(img[i] / 65535.0);
193 }
194
195 postProgress(20);
196
197 processRgbImage(tmpimage.data(), sizex, sizey);
13
Calling 'LocalContrastFilter::processRgbImage'
23
Returning from 'LocalContrastFilter::processRgbImage'
198
199 // convert back to 16 bits (with dithering)
200
201 int pos = 0;
24
'pos' initialized to 0
202
203 for (int i = 0 ; runningFlag() && (i < size) ; ++i)
25
Assuming the condition is true
26
Assuming 'i' is < 'size'
27
Loop condition is true. Entering loop body
204 {
205 float dither = d->generator.number(0.0, 1.0);
206 img[pos] = (int)(tmpimage[pos] * 65535.0 + dither);
28
Passing the value 0 via 1st parameter 'i'
29
The left operand of '*' is a garbage value
207 img[pos + 1] = (int)(tmpimage[pos + 1] * 65535.0 + dither);
208 img[pos + 2] = (int)(tmpimage[pos + 2] * 65535.0 + dither);
209 pos += 3;
210 }
211
212 postProgress(80);
213}
214
215float LocalContrastFilter::func(float x1, float x2)
216{
217 float result = 0.5;
218 float p;
219
220 switch (d->par.functionId)
221 {
222 case 0: // power function
223 {
224 p = (float)(qPow((double)10.0, (double)qFabs((x2 * 2.0 - 1.0)) * d->current_process_power_value * 0.02));
225
226 if (x2 >= 0.5)
227 {
228 result = qPow(x1, p);
229 }
230 else
231 {
232 result = (float)(1.0 - qPow((double)1.0 - x1, (double)p));
233 }
234
235 break;
236 }
237
238 case 1: // linear function
239 {
240 p = (float)(1.0 / (1 + qExp(-(x2 * 2.0 - 1.0) * d->current_process_power_value * 0.04)));
241 result = (x1 < p) ? (float)(x1 * (1.0 - p) / p) : (float)((1.0 - p) + (x1 - p) * p / (1.0 - p));
242 break;
243 }
244 }
245
246 return result;
247}
248
249void LocalContrastFilter::blurMultithreaded(uint start, uint stop, float* const img, float* const blurimage)
250{
251 uint pos = start * 3;
252
253 for (uint i = start ; runningFlag() && (i < stop) ; ++i)
254 {
255 float src_r = img[pos];
256 float src_g = img[pos + 1];
257 float src_b = img[pos + 2];
258
259 float blur = blurimage[i];
260
261 float dest_r = func(src_r, blur);
262 float dest_g = func(src_g, blur);
263 float dest_b = func(src_b, blur);
264
265 img[pos] = dest_r;
266 img[pos + 1] = dest_g;
267 img[pos + 2] = dest_b;
268
269 pos += 3;
270 }
271}
272
273void LocalContrastFilter::saturationMultithreaded(uint start, uint stop, float* const img, float* const srcimg)
274{
275 float src_h, src_s, src_v;
276 float dest_h, dest_s, dest_v;
277 float destSaturation, s1;
278
279 uint pos = start * 3;
280 int highSaturationValue = 100 - d->par.highSaturation;
281 int lowSaturationValue = 100 - d->par.lowSaturation;
282
283 for (uint i = start ; runningFlag() && (i < stop) ; ++i)
284 {
285 rgb2hsv(srcimg[pos], srcimg[pos + 1], srcimg[pos + 2], src_h, src_s, src_v);
286 rgb2hsv(img[pos], img[pos + 1], img[pos + 2], dest_h, dest_s, dest_v);
287
288 destSaturation = (float)((src_s * highSaturationValue + dest_s * (100.0 - highSaturationValue)) * 0.01);
289
290 if (dest_v > src_v)
291 {
292 s1 = (float)(destSaturation * src_v / (dest_v + 1.0 / 255.0));
293 destSaturation = (float)((lowSaturationValue * s1 + d->par.lowSaturation * destSaturation) * 0.01);
294 }
295
296 hsv2rgb(dest_h, destSaturation, dest_v, img[pos], img[pos + 1], img[pos + 2]);
297
298 pos += 3;
299 }
300}
301
302void LocalContrastFilter::processRgbImage(float* const img, int sizex, int sizey)
303{
304 int size = sizex * sizey;
305 QScopedArrayPointer<float> blurimage(new float[size]);
306 QScopedArrayPointer<float> srcimg(new float[size * 3]);
307
308 for (int i = 0 ; i < (size * 3) ; ++i)
14
Assuming the condition is false
15
Loop condition is false. Execution continues on line 313
309 {
310 srcimg[i] = img[i];
311 }
312
313 postProgress(30);
314
315 if (d->par.stretchContrast)
16
Assuming field 'stretchContrast' is false
17
Taking false branch
316 {
317 stretchContrast(img, size * 3);
318 }
319
320 postProgress(40);
321
322 QList<int> vals = multithreadedSteps(size);
323 int pos = 0;
324
325 for (int nstage = 0 ; runningFlag() && (nstage < TONEMAPPING_MAX_STAGES4) ; ++nstage)
18
Assuming the condition is false
326 {
327 if (d->par.stage[nstage].enabled)
328 {
329 // compute the desatured image
330
331 pos = 0;
332
333 for (int i = 0 ; runningFlag() && (i < size) ; ++i)
334 {
335 blurimage[i] = (float)((img[pos] + img[pos + 1] + img[pos + 2]) / 3.0);
336 pos += 3;
337 }
338
339 d->current_process_power_value = d->par.getPower(nstage);
340
341 // blur
342
343 inplaceBlur(blurimage.data(), sizex, sizey, d->par.getBlur(nstage));
344
345 QList <QFuture<void> > tasks;
346
347 for (int j = 0 ; runningFlag() && (j < vals.count()-1) ; ++j)
348 {
349 tasks.append(QtConcurrent::run(
350
351#if (QT_VERSION((6<<16)|(8<<8)|(0)) >= QT_VERSION_CHECK(6, 0, 0)((6<<16)|(0<<8)|(0)))
352
353 &LocalContrastFilter::blurMultithreaded, this,
354
355#else
356
357 this, &LocalContrastFilter::blurMultithreaded,
358
359#endif
360
361 vals[j],
362 vals[j+1],
363 img,
364 blurimage.data()
365 )
366 );
367 }
368
369 for (QFuture<void> t : std::as_const(tasks))
370 {
371 t.waitForFinished();
372 }
373 }
374
375 postProgress(50 + nstage * 5);
376 }
377
378 if ((d->par.highSaturation != 100) || (d->par.lowSaturation != 100))
19
Assuming field 'highSaturation' is equal to 100
20
Assuming field 'lowSaturation' is equal to 100
21
Taking false branch
379 {
380 qCDebug(DIGIKAM_DIMG_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> 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/lc/localcontrastfilter.cpp"
), 380, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "highSaturation : " << d->par.highSaturation;
381 qCDebug(DIGIKAM_DIMG_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> 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/lc/localcontrastfilter.cpp"
), 381, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "lowSaturation : " << d->par.lowSaturation;
382
383 QList <QFuture<void> > tasks;
384
385 for (int j = 0 ; runningFlag() && (j < vals.count()-1) ; ++j)
386 {
387 tasks.append(QtConcurrent::run(
388
389#if (QT_VERSION((6<<16)|(8<<8)|(0)) >= QT_VERSION_CHECK(6, 0, 0)((6<<16)|(0<<8)|(0)))
390
391 &LocalContrastFilter::saturationMultithreaded, this,
392
393#else
394
395 this, &LocalContrastFilter::saturationMultithreaded,
396
397#endif
398
399 vals[j],
400 vals[j+1],
401 img,
402 srcimg.data()
403 )
404 );
405 }
406
407 for (QFuture<void> t : std::as_const(tasks))
408 {
409 t.waitForFinished();
410 }
411 }
412
413 postProgress(70);
414}
22
Returning without writing to '*img'
415
416void LocalContrastFilter::inplaceBlurYMultithreaded(const Args& prm)
417{
418 for (uint y = prm.start ; runningFlag() && (y < prm.stop) ; ++y)
419 {
420 uint pos = y * prm.sizex;
421 float old = prm.data[pos];
422 ++pos;
423
424 for (int x = 1 ; runningFlag() && (x < prm.sizex) ; ++x)
425 {
426 old = (prm.data[pos] * (1 - prm.a) + old * prm.a) + prm.denormal_remove;
427 prm.data[pos] = old;
428 ++pos;
429 }
430
431 pos = y * prm.sizex + prm.sizex - 1;
432
433 for (int x = 1 ; runningFlag() && (x < prm.sizex) ; ++x)
434 {
435 old = (prm.data[pos] * (1 - prm.a) + old * prm.a) + prm.denormal_remove;
436 prm.data[pos] = old;
437 pos--;
438 }
439 }
440}
441
442void LocalContrastFilter::inplaceBlurXMultithreaded(const Args& prm)
443{
444 for (uint x = prm.start ; runningFlag() && (x < prm.stop) ; ++x)
445 {
446 uint pos = x;
447 float old = prm.data[pos];
448
449 for (int y = 1 ; runningFlag() && (y < prm.sizey) ; ++y)
450 {
451 old = (prm.data[pos] * (1 - prm.a) + old * prm.a) + prm.denormal_remove;
452 prm.data[pos] = old;
453 pos += prm.sizex;
454 }
455
456 pos = x + prm.sizex * (prm.sizey - 1);
457
458 for (int y = 1 ; runningFlag() && (y < prm.sizey) ; ++y)
459 {
460 old = (prm.data[pos] * (1 - prm.a) + old * prm.a) + prm.denormal_remove;
461 prm.data[pos] = old;
462 pos -= prm.sizex;
463 }
464 }
465}
466
467void LocalContrastFilter::inplaceBlur(float* const data, int sizex, int sizey, float blur)
468{
469 if (blur < 0.3)
470 {
471 return;
472 }
473
474 Args prm;
475
476 prm.a = (float)(qExp(log(0.25) / blur));
477
478 if ((prm.a <= 0.0) || (prm.a >= 1.0))
479 {
480 return;
481 }
482
483 prm.a *= prm.a;
484 prm.data = data;
485 prm.sizex = sizex;
486 prm.sizey = sizey;
487 prm.blur = blur;
488 prm.denormal_remove = (float)(1e-15);
489
490 QList<int> valsx = multithreadedSteps(prm.sizex);
491 QList<int> valsy = multithreadedSteps(prm.sizey);
492
493 for (uint stage = 0 ; runningFlag() && (stage < 2) ; ++stage)
494 {
495 QList <QFuture<void> > tasks;
496
497 for (int j = 0 ; runningFlag() && (j < valsy.count()-1) ; ++j)
498 {
499 prm.start = valsy[j];
500 prm.stop = valsy[j+1];
501
502 tasks.append(QtConcurrent::run(
503
504#if (QT_VERSION((6<<16)|(8<<8)|(0)) >= QT_VERSION_CHECK(6, 0, 0)((6<<16)|(0<<8)|(0)))
505
506 &LocalContrastFilter::inplaceBlurYMultithreaded, this,
507
508#else
509
510 this, &LocalContrastFilter::inplaceBlurYMultithreaded,
511
512#endif
513
514 prm
515 )
516 );
517 }
518
519 for (QFuture<void> t : std::as_const(tasks))
520 {
521 t.waitForFinished();
522 }
523
524 tasks.clear();
525
526 for (int j = 0 ; runningFlag() && (j < valsx.count()-1) ; ++j)
527 {
528 prm.start = valsx[j];
529 prm.stop = valsx[j+1];
530
531 tasks.append(QtConcurrent::run(
532
533#if (QT_VERSION((6<<16)|(8<<8)|(0)) >= QT_VERSION_CHECK(6, 0, 0)((6<<16)|(0<<8)|(0)))
534
535 &LocalContrastFilter::inplaceBlurXMultithreaded, this,
536
537#else
538
539 this, &LocalContrastFilter::inplaceBlurXMultithreaded,
540
541#endif
542
543 prm
544 )
545 );
546 }
547
548 for (QFuture<void> t : std::as_const(tasks))
549 {
550 t.waitForFinished();
551 }
552 }
553}
554
555void LocalContrastFilter::stretchContrast(float* const data, int datasize)
556{
557 // stretch the contrast
558
559 const unsigned int histogram_size = 256;
560
561 // first, we compute the histogram
562
563 unsigned int histogram[histogram_size] = { 0 };
564
565 for (unsigned int i = 0 ; runningFlag() && (i < (unsigned int)datasize) ; ++i)
566 {
567 int m = (int)(data[i] * (histogram_size - 1));
568
569 if (m < 0)
570 {
571 m = 0;
572 }
573
574 if (m > (int)(histogram_size - 1))
575 {
576 m = histogram_size - 1;
577 }
578
579 histogram[m]++;
580 }
581
582 // I want to strip the lowest and upper 0.1 percents (in the histogram) of the pixels
583 int min = 0;
584 int max = 255;
585 unsigned int desired_sum = datasize / 1000;
586 unsigned int sum_min = 0;
587 unsigned int sum_max = 0;
588
589 for (unsigned int i = 0 ; runningFlag() && (i < histogram_size) ; ++i)
590 {
591 sum_min += histogram[i];
592
593 if (sum_min > desired_sum)
594 {
595 min = i;
596 break;
597 }
598 }
599
600 for (int i = histogram_size - 1 ; runningFlag() && (i >= 0) ; --i)
601 {
602 sum_max += histogram[i];
603
604 if (sum_max > desired_sum)
605 {
606 max = i;
607 break;
608 }
609 }
610
611 if (min >= max)
612 {
613 min = 0;
614 max = 255;
615 }
616
617 float min_src_val = (float)(min / 255.0);
618 float max_src_val = (float)(max / 255.0);
619
620 for (int i = 0 ; runningFlag() && (i < datasize) ; ++i)
621 {
622 // stretch the contrast
623
624 float x = data[i];
625 x = (x - min_src_val) / (max_src_val - min_src_val);
626
627 if (x < 0.0)
628 {
629 x = 0.0;
630 }
631
632 if (x > 1.0)
633 {
634 x = 1.0;
635 }
636
637 data[i] = x;
638 }
639}
640
641void LocalContrastFilter::rgb2hsv(const float& r, const float& g, const float& b, float& h, float& s, float& v)
642{
643 float maxrg = (r > g) ? r : g;
644 float max = (maxrg > b) ? maxrg : b;
645 float minrg = (r < g) ? r : g;
646 float min = (minrg < b) ? minrg : b;
647 float delta = max - min;
648
649 // hue
650
651 if (min == max)
652 {
653 h = 0.0;
654 }
655 else
656 {
657 if (max == r)
658 {
659 h = (float)(fmod(60.0 * (g - b) / delta + 360.0, 360.0));
660 }
661 else
662 {
663 if (max == g)
664 {
665 h = (float)(60.0 * (b - r) / delta + 120.0);
666 }
667 else
668 {
669 // max==b
670 h = (float)(60.0 * (r - g) / delta + 240.0);
671 }
672 }
673 }
674
675 // saturation
676
677 if (max < 1e-6)
678 {
679 s = 0;
680 }
681 else
682 {
683 s = (float)(1.0 - min / max);
684 }
685
686 // value
687
688 v = max;
689}
690
691void LocalContrastFilter::hsv2rgb(const float& h, const float& s, const float& v, float& r, float& g, float& b)
692{
693 float hfi = (float)(floor(h / 60.0));
694 float f = (float)((h / 60.0) - hfi);
695 int hi = ((int)hfi) % 6;
696 float p = (float)(v * (1.0 - s));
697 float q = (float)(v * (1.0 - f * s));
698 float t = (float)(v * (1.0 - (1.0 - f) * s));
699
700 switch (hi)
701 {
702 case 0:
703 {
704 r = v;
705 g = t;
706 b = p;
707 break;
708 }
709
710 case 1:
711 {
712 r = q;
713 g = v;
714 b = p;
715 break;
716 }
717
718 case 2:
719 {
720 r = p;
721 g = v;
722 b = t;
723 break;
724 }
725
726 case 3:
727 {
728 r = p;
729 g = q;
730 b = v;
731 break;
732 }
733
734 case 4:
735 {
736 r = t;
737 g = p;
738 b = v;
739 break;
740 }
741
742 case 5:
743 {
744 r = v;
745 g = p;
746 b = q;
747 break;
748 }
749 }
750}
751
752FilterAction LocalContrastFilter::filterAction()
753{
754 FilterAction action(FilterIdentifier(), CurrentVersion());
755 action.setDisplayableName(DisplayableName());
756
757 action.addParameter(QLatin1String("functionId"), d->par.functionId);
758 action.addParameter(QLatin1String("highSaturation"), d->par.highSaturation);
759 action.addParameter(QLatin1String("lowSaturation"), d->par.lowSaturation);
760 action.addParameter(QLatin1String("stretchContrast"), d->par.stretchContrast);
761
762 for (int nstage = 0 ; nstage < TONEMAPPING_MAX_STAGES4 ; ++nstage)
763 {
764 QString stage = QString::fromLatin1("stage[%1]:").arg(nstage);
765 action.addParameter(stage + QLatin1String("enabled"), d->par.stage[nstage].enabled);
766
767 if (d->par.stage[nstage].enabled)
768 {
769 action.addParameter(stage + QLatin1String("power"), d->par.stage[nstage].power);
770 action.addParameter(stage + QLatin1String("blur"), d->par.stage[nstage].blur);
771 }
772 }
773
774 action.addParameter(QLatin1String("randomSeed"), d->generator.currentSeed());
775
776 return action;
777}
778
779void LocalContrastFilter::readParameters(const FilterAction& action)
780{
781 d->par.functionId = action.parameter(QLatin1String("functionId")).toInt();
782 d->par.highSaturation = action.parameter(QLatin1String("highSaturation")).toInt();
783 d->par.lowSaturation = action.parameter(QLatin1String("lowSaturation")).toInt();
784 d->par.stretchContrast = action.parameter(QLatin1String("stretchContrast")).toBool();
785
786 for (int nstage = 0 ; nstage < TONEMAPPING_MAX_STAGES4 ; ++nstage)
787 {
788 QString stage = QString::fromLatin1("stage[%1]:").arg(nstage);
789 d->par.stage[nstage].enabled = action.parameter(stage + QLatin1String("enabled")).toBool();
790
791 if (d->par.stage[nstage].enabled)
792 {
793 d->par.stage[nstage].power = action.parameter(stage + QLatin1String("power")).toFloat();
794 d->par.stage[nstage].blur = action.parameter(stage + QLatin1String("blur")).toFloat();
795 }
796 }
797
798 d->generator.seed(action.parameter(QLatin1String("randomSeed")).toUInt());
799}
800
801} // namespace Digikam
802
803#include "moc_localcontrastfilter.cpp"

/opt/qt6/include/QtCore/qscopedpointer.h

1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QSCOPEDPOINTER_H
5#define QSCOPEDPOINTER_H
6
7#include <QtCore/qglobal.h>
8
9#include <stdlib.h>
10
11QT_BEGIN_NAMESPACE
12
13template <typename T>
14struct QScopedPointerDeleter
15{
16 static inline void cleanup(T *pointer) noexcept
17 {
18 // Enforce a complete type.
19 // If you get a compile error here, read the section on forward declared
20 // classes in the QScopedPointer documentation.
21 typedef char IsIncompleteType[ sizeof(T) ? 1 : -1 ];
22 (void) sizeof(IsIncompleteType);
23
24 delete pointer;
25 }
26 void operator()(T *pointer) const noexcept
27 {
28 cleanup(pointer);
29 }
30};
31
32template <typename T>
33struct QScopedPointerArrayDeleter
34{
35 static inline void cleanup(T *pointer) noexcept
36 {
37 // Enforce a complete type.
38 // If you get a compile error here, read the section on forward declared
39 // classes in the QScopedPointer documentation.
40 typedef char IsIncompleteType[ sizeof(T) ? 1 : -1 ];
41 (void) sizeof(IsIncompleteType);
42
43 delete[] pointer;
44 }
45 void operator()(T *pointer) const noexcept
46 {
47 cleanup(pointer);
48 }
49};
50
51struct QScopedPointerPodDeleter
52{
53 static inline void cleanup(void *pointer) noexcept { free(pointer); }
54 void operator()(void *pointer) const noexcept { cleanup(pointer); }
55};
56
57#ifndef QT_NO_QOBJECT
58template <typename T>
59struct QScopedPointerObjectDeleteLater
60{
61 static inline void cleanup(T *pointer) { if (pointer) pointer->deleteLater(); }
62 void operator()(T *pointer) const { cleanup(pointer); }
63};
64
65class QObject;
66typedef QScopedPointerObjectDeleteLater<QObject> QScopedPointerDeleteLater;
67#endif
68
69template <typename T, typename Cleanup = QScopedPointerDeleter<T> >
70class QScopedPointer
71{
72public:
73 Q_NODISCARD_CTOR[[nodiscard]]
74 explicit QScopedPointer(T *p = nullptr) noexcept : d(p)
75 {
76 }
77
78 inline ~QScopedPointer()
79 {
80 T *oldD = this->d;
81 Cleanup::cleanup(oldD);
82 }
83
84 inline T &operator*() const
85 {
86 Q_ASSERT(d)((d) ? static_cast<void>(0) : qt_assert("d", "/opt/qt6/include/QtCore/qscopedpointer.h"
, 86))
;
87 return *d;
88 }
89
90 T *operator->() const noexcept
91 {
92 return d;
93 }
94
95 bool operator!() const noexcept
96 {
97 return !d;
98 }
99
100 explicit operator bool() const
101 {
102 return !isNull();
103 }
104
105 T *data() const noexcept
106 {
107 return d;
108 }
109
110 T *get() const noexcept
111 {
112 return d;
113 }
114
115 bool isNull() const noexcept
116 {
117 return !d;
118 }
119
120 void reset(T *other = nullptr) noexcept(noexcept(Cleanup::cleanup(std::declval<T *>())))
121 {
122 if (d == other)
123 return;
124 T *oldD = std::exchange(d, other);
125 Cleanup::cleanup(oldD);
126 }
127
128#if QT_DEPRECATED_SINCE(6, 1)(((6<<16)|(1<<8)|(0)) > 0x050E00)
129 QT_DEPRECATED_VERSION_X_6_1("Use std::unique_ptr instead, and call release().")
130 T *take() noexcept
131 {
132 T *oldD = std::exchange(d, nullptr);
133 return oldD;
134 }
135#endif
136
137#if QT_DEPRECATED_SINCE(6, 2)(((6<<16)|(2<<8)|(0)) > 0x050E00)
138 QT_DEPRECATED_VERSION_X_6_2("Use std::unique_ptr instead of QScopedPointer.")
139 void swap(QScopedPointer<T, Cleanup> &other) noexcept
140 {
141 qt_ptr_swap(d, other.d);
142 }
143#endif
144
145 typedef T *pointer;
146
147 friend bool operator==(const QScopedPointer<T, Cleanup> &lhs, const QScopedPointer<T, Cleanup> &rhs) noexcept
148 {
149 return lhs.data() == rhs.data();
150 }
151
152 friend bool operator!=(const QScopedPointer<T, Cleanup> &lhs, const QScopedPointer<T, Cleanup> &rhs) noexcept
153 {
154 return lhs.data() != rhs.data();
155 }
156
157 friend bool operator==(const QScopedPointer<T, Cleanup> &lhs, std::nullptr_t) noexcept
158 {
159 return lhs.isNull();
160 }
161
162 friend bool operator==(std::nullptr_t, const QScopedPointer<T, Cleanup> &rhs) noexcept
163 {
164 return rhs.isNull();
165 }
166
167 friend bool operator!=(const QScopedPointer<T, Cleanup> &lhs, std::nullptr_t) noexcept
168 {
169 return !lhs.isNull();
170 }
171
172 friend bool operator!=(std::nullptr_t, const QScopedPointer<T, Cleanup> &rhs) noexcept
173 {
174 return !rhs.isNull();
175 }
176
177#if QT_DEPRECATED_SINCE(6, 2)(((6<<16)|(2<<8)|(0)) > 0x050E00)
178 QT_DEPRECATED_VERSION_X_6_2("Use std::unique_ptr instead of QScopedPointer.")
179 friend void swap(QScopedPointer<T, Cleanup> &p1, QScopedPointer<T, Cleanup> &p2) noexcept
180 { p1.swap(p2); }
181#endif
182
183protected:
184 T *d;
185
186private:
187 Q_DISABLE_COPY_MOVE(QScopedPointer)QScopedPointer(const QScopedPointer &) = delete; QScopedPointer
&operator=(const QScopedPointer &) = delete; QScopedPointer
(QScopedPointer &&) = delete; QScopedPointer &operator
=(QScopedPointer &&) = delete;
188};
189
190template <typename T, typename Cleanup = QScopedPointerArrayDeleter<T> >
191class QScopedArrayPointer : public QScopedPointer<T, Cleanup>
192{
193 template <typename Ptr>
194 using if_same_type = typename std::enable_if<std::is_same<typename std::remove_cv<T>::type, Ptr>::value, bool>::type;
195public:
196 Q_NODISCARD_CTOR[[nodiscard]]
197 inline QScopedArrayPointer() : QScopedPointer<T, Cleanup>(nullptr) {}
198 inline ~QScopedArrayPointer() = default;
199
200 template <typename D, if_same_type<D> = true>
201 Q_NODISCARD_CTOR[[nodiscard]]
202 explicit QScopedArrayPointer(D *p)
203 : QScopedPointer<T, Cleanup>(p)
9
Calling default constructor for 'QScopedPointer<float, QScopedPointerArrayDeleter<float>>'
10
Returning from default constructor for 'QScopedPointer<float, QScopedPointerArrayDeleter<float>>'
204 {
205 }
206
207 T &operator[](qsizetype i)
208 {
209 return this->d[i];
210 }
211
212 const T &operator[](qsizetype i) const
213 {
214 return this->d[i];
215 }
216
217#if QT_DEPRECATED_SINCE(6, 2)(((6<<16)|(2<<8)|(0)) > 0x050E00)
218 QT_DEPRECATED_VERSION_X_6_2("Use std::unique_ptr instead of QScopedArrayPointer.")
219 void swap(QScopedArrayPointer &other) noexcept // prevent QScopedPointer <->QScopedArrayPointer swaps
220 { QScopedPointer<T, Cleanup>::swap(other); }
221#endif
222
223private:
224 explicit inline QScopedArrayPointer(void *)
225 {
226 // Enforce the same type.
227
228 // If you get a compile error here, make sure you declare
229 // QScopedArrayPointer with the same template type as you pass to the
230 // constructor. See also the QScopedPointer documentation.
231
232 // Storing a scalar array as a pointer to a different type is not
233 // allowed and results in undefined behavior.
234 }
235
236 Q_DISABLE_COPY_MOVE(QScopedArrayPointer)QScopedArrayPointer(const QScopedArrayPointer &) = delete
; QScopedArrayPointer &operator=(const QScopedArrayPointer
&) = delete; QScopedArrayPointer(QScopedArrayPointer &&
) = delete; QScopedArrayPointer &operator=(QScopedArrayPointer
&&) = delete;
237};
238
239#if QT_DEPRECATED_SINCE(6, 2)(((6<<16)|(2<<8)|(0)) > 0x050E00)
240template <typename T, typename Cleanup>
241QT_DEPRECATED_VERSION_X_6_2("Use std::unique_ptr instead of QScopedArrayPointer.")
242inline void swap(QScopedArrayPointer<T, Cleanup> &lhs, QScopedArrayPointer<T, Cleanup> &rhs) noexcept
243{ lhs.swap(rhs); }
244#endif
245
246QT_END_NAMESPACE
247
248#endif // QSCOPEDPOINTER_H