Bug Summary

File:/home/gilles/devel/GIT/8.x/core/libs/dimg/filters/nr/nrestimate.cpp
Warning:line 196, column 28
The left operand of '>' is a garbage value

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 nrestimate.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/GIT/8.x/build.scan/core/libs/dimg -fcoverage-compilation-dir=/home/gilles/devel/GIT/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_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/GIT/8.x/build.scan/core/libs/dimg -I /home/gilles/devel/GIT/8.x/core/libs/dimg -I /home/gilles/devel/GIT/8.x/build.scan/core/libs/dimg/core_dimg_obj_autogen/include -I /home/gilles/devel/GIT/8.x/core/libs/video/player/qtmm -I /home/gilles/devel/GIT/8.x/core/libs/album/engine -I /home/gilles/devel/GIT/8.x/core/libs/album/manager -I /home/gilles/devel/GIT/8.x/core/libs/album/treeview -I /home/gilles/devel/GIT/8.x/core/libs/album/widgets -I /home/gilles/devel/GIT/8.x/core/libs/database/collection -I /home/gilles/devel/GIT/8.x/core/libs/database/coredb -I /home/gilles/devel/GIT/8.x/core/libs/database/dbjobs -I /home/gilles/devel/GIT/8.x/core/libs/database/engine -I /home/gilles/devel/GIT/8.x/core/libs/database/haar -I /home/gilles/devel/GIT/8.x/core/libs/database/history -I /home/gilles/devel/GIT/8.x/core/libs/database/item/containers -I /home/gilles/devel/GIT/8.x/core/libs/database/item/lister -I /home/gilles/devel/GIT/8.x/core/libs/database/item/query -I /home/gilles/devel/GIT/8.x/core/libs/database/item/scanner -I /home/gilles/devel/GIT/8.x/core/libs/database/models -I /home/gilles/devel/GIT/8.x/core/libs/database/server -I /home/gilles/devel/GIT/8.x/core/libs/database/similaritydb -I /home/gilles/devel/GIT/8.x/core/libs/database/tags -I /home/gilles/devel/GIT/8.x/core/libs/database/thumbsdb -I /home/gilles/devel/GIT/8.x/core/libs/database/utils/ifaces -I /home/gilles/devel/GIT/8.x/core/libs/database/utils/scan -I /home/gilles/devel/GIT/8.x/core/libs/database/utils/widgets -I /home/gilles/devel/GIT/8.x/core/libs/dialogs -I /home/gilles/devel/GIT/8.x/core/libs/dimg/color -I /home/gilles/devel/GIT/8.x/core/libs/dimg/filters/auto -I /home/gilles/devel/GIT/8.x/core/libs/dimg/filters/bcg -I /home/gilles/devel/GIT/8.x/core/libs/dimg/filters/bw -I /home/gilles/devel/GIT/8.x/core/libs/dimg/filters/cb -I /home/gilles/devel/GIT/8.x/core/libs/dimg/filters/curves -I /home/gilles/devel/GIT/8.x/core/libs/dimg/filters/decorate -I /home/gilles/devel/GIT/8.x/core/libs/dimg/filters -I /home/gilles/devel/GIT/8.x/core/libs/dimg/filters/film -I /home/gilles/devel/GIT/8.x/core/libs/dimg/filters/fx -I /home/gilles/devel/GIT/8.x/core/libs/dimg/filters/greycstoration/cimg -I /home/gilles/devel/GIT/8.x/core/libs/dimg/filters/greycstoration -I /home/gilles/devel/GIT/8.x/core/libs/dimg/filters/hotpixels -I /home/gilles/devel/GIT/8.x/core/libs/dimg/filters/hsl -I /home/gilles/devel/GIT/8.x/core/libs/dimg/filters/icc -I /home/gilles/devel/GIT/8.x/core/libs/dimg/filters/lc -I /home/gilles/devel/GIT/8.x/core/libs/dimg/filters/lens -I /home/gilles/devel/GIT/8.x/core/libs/dimg/filters/levels -I /home/gilles/devel/GIT/8.x/core/libs/dimg/filters/nr -I /home/gilles/devel/GIT/8.x/core/libs/dimg/filters/raw -I /home/gilles/devel/GIT/8.x/core/libs/dimg/filters/redeye -I /home/gilles/devel/GIT/8.x/core/libs/dimg/filters/sharp -I /home/gilles/devel/GIT/8.x/core/libs/dimg/filters/transform -I /home/gilles/devel/GIT/8.x/core/libs/dimg/filters/wb -I /home/gilles/devel/GIT/8.x/core/libs/dimg/history -I /home/gilles/devel/GIT/8.x/core/libs/dimg/loaders -I /home/gilles/devel/GIT/8.x/core/libs/dngwriter -I /home/gilles/devel/GIT/8.x/core/libs/dplugins/core -I /home/gilles/devel/GIT/8.x/core/libs/dplugins/iface -I /home/gilles/devel/GIT/8.x/core/libs/dplugins/setup -I /home/gilles/devel/GIT/8.x/core/libs/dplugins/webservices -I /home/gilles/devel/GIT/8.x/core/libs/dplugins/widgets -I /home/gilles/devel/GIT/8.x/core/libs/dragdrop -I /home/gilles/devel/GIT/8.x/core/libs/dtrash -I /home/gilles/devel/GIT/8.x/core/libs/facesengine/common -I /home/gilles/devel/GIT/8.x/core/libs/facesengine/detection -I /home/gilles/devel/GIT/8.x/core/libs/facesengine/detection/opencv-dnn -I /home/gilles/devel/GIT/8.x/core/libs/facesengine/facedb -I /home/gilles/devel/GIT/8.x/core/libs/facesengine/preprocessing -I /home/gilles/devel/GIT/8.x/core/libs/facesengine/preprocessing/recognition -I /home/gilles/devel/GIT/8.x/core/libs/facesengine/preprocessing/shape-predictor -I /home/gilles/devel/GIT/8.x/core/libs/facesengine/recognition -I /home/gilles/devel/GIT/8.x/core/libs/facesengine/recognition/opencv-dnn -I /home/gilles/devel/GIT/8.x/core/libs/fileactionmanager -I /home/gilles/devel/GIT/8.x/core/libs/filters -I /home/gilles/devel/GIT/8.x/core/libs/imgqsort/detectors -I /home/gilles/devel/GIT/8.x/core/libs/imgqsort -I /home/gilles/devel/GIT/8.x/core/libs/iojobs -I /home/gilles/devel/GIT/8.x/core/libs/jpegutils -I /home/gilles/devel/GIT/8.x/core/libs/metadataengine/containers -I /home/gilles/devel/GIT/8.x/core/libs/metadataengine/dmetadata -I /home/gilles/devel/GIT/8.x/core/libs/metadataengine/engine -I /home/gilles/devel/GIT/8.x/core/libs/metadataengine/exiftool -I /home/gilles/devel/GIT/8.x/core/libs/metadataengine/focuspoint -I /home/gilles/devel/GIT/8.x/core/libs/models -I /home/gilles/devel/GIT/8.x/core/libs/networkmanager -I /home/gilles/devel/GIT/8.x/core/libs/notificationmanager -I /home/gilles/devel/GIT/8.x/core/libs/onlineversion -I /home/gilles/devel/GIT/8.x/core/libs/pgfutils -I /home/gilles/devel/GIT/8.x/core/libs/progressmanager -I /home/gilles/devel/GIT/8.x/core/libs/properties/captions -I /home/gilles/devel/GIT/8.x/core/libs/properties/geolocation -I /home/gilles/devel/GIT/8.x/core/libs/properties/history -I /home/gilles/devel/GIT/8.x/core/libs/properties/import -I /home/gilles/devel/GIT/8.x/core/libs/properties -I /home/gilles/devel/GIT/8.x/core/libs/rawengine -I /home/gilles/devel/GIT/8.x/core/libs/settings -I /home/gilles/devel/GIT/8.x/core/libs/tags/autoassignment -I /home/gilles/devel/GIT/8.x/core/libs/tags/autoassignment/model -I /home/gilles/devel/GIT/8.x/core/libs/tags/engine -I /home/gilles/devel/GIT/8.x/core/libs/tags/manager/models -I /home/gilles/devel/GIT/8.x/core/libs/tags/manager -I /home/gilles/devel/GIT/8.x/core/libs/tags/widgets -I /home/gilles/devel/GIT/8.x/core/libs/template -I /home/gilles/devel/GIT/8.x/core/libs/threadimageio/engine -I /home/gilles/devel/GIT/8.x/core/libs/threadimageio/fileio -I /home/gilles/devel/GIT/8.x/core/libs/threadimageio/preview -I /home/gilles/devel/GIT/8.x/core/libs/threadimageio/thumb -I /home/gilles/devel/GIT/8.x/core/libs/threadimageio/video -I /home/gilles/devel/GIT/8.x/core/libs/threads -I /home/gilles/devel/GIT/8.x/core/libs/timeadjust -I /home/gilles/devel/GIT/8.x/core/libs/transitionmngr -I /home/gilles/devel/GIT/8.x/core/libs/versionmanager -I /home/gilles/devel/GIT/8.x/core/libs/video -I /home/gilles/devel/GIT/8.x/core/libs/video/manager -I /home/gilles/devel/GIT/8.x/core/libs/video/osd -I /home/gilles/devel/GIT/8.x/core/libs/video/player -I /home/gilles/devel/GIT/8.x/core/libs/widgets/colors -I /home/gilles/devel/GIT/8.x/core/libs/widgets/combo -I /home/gilles/devel/GIT/8.x/core/libs/widgets/files -I /home/gilles/devel/GIT/8.x/core/libs/widgets/fonts -I /home/gilles/devel/GIT/8.x/core/libs/widgets/graphicsview -I /home/gilles/devel/GIT/8.x/core/libs/widgets/history -I /home/gilles/devel/GIT/8.x/core/libs/widgets/iccprofiles -I /home/gilles/devel/GIT/8.x/core/libs/widgets/itemview -I /home/gilles/devel/GIT/8.x/core/libs/widgets/layout -I /home/gilles/devel/GIT/8.x/core/libs/widgets/mainview -I /home/gilles/devel/GIT/8.x/core/libs/widgets/metadata/config -I /home/gilles/devel/GIT/8.x/core/libs/widgets/metadata/exiftool -I /home/gilles/devel/GIT/8.x/core/libs/widgets/metadata/exiv2 -I /home/gilles/devel/GIT/8.x/core/libs/widgets/metadata/labels -I /home/gilles/devel/GIT/8.x/core/libs/widgets/metadata/utils -I /home/gilles/devel/GIT/8.x/core/libs/widgets/range -I /home/gilles/devel/GIT/8.x/core/libs/widgets/text -I /home/gilles/devel/GIT/8.x/core/libs/jpegutils/libjpeg/84 -I /home/gilles/devel/GIT/8.x/core/app/utils -I /home/gilles/devel/GIT/8.x/build.scan/core/app/utils -I /home/gilles/devel/GIT/8.x/core/utilities/advancedrename -I /home/gilles/devel/GIT/8.x/core/utilities/advancedrename/common -I /home/gilles/devel/GIT/8.x/core/utilities/advancedrename/parser -I /home/gilles/devel/GIT/8.x/core/utilities/advancedrename/parser/modifiers -I /home/gilles/devel/GIT/8.x/core/utilities/advancedrename/parser/options -I /home/gilles/devel/GIT/8.x/core/utilities/advancedrename/parser/options/database -I /home/gilles/devel/GIT/8.x/core/utilities/advancedrename/parser/options/database/keys -I /home/gilles/devel/GIT/8.x/core/utilities/extrasupport/addressbook -I /home/gilles/devel/GIT/8.x/core/utilities/extrasupport/filesindexer -I /home/gilles/devel/GIT/8.x/core/utilities/facemanagement/bench -I /home/gilles/devel/GIT/8.x/core/utilities/facemanagement/database -I /home/gilles/devel/GIT/8.x/core/utilities/facemanagement/items -I /home/gilles/devel/GIT/8.x/core/utilities/facemanagement/threads -I /home/gilles/devel/GIT/8.x/core/utilities/facemanagement/widgets -I /home/gilles/devel/GIT/8.x/core/utilities/facemanagement/workers -I /home/gilles/devel/GIT/8.x/core/utilities/firstrun -I /home/gilles/devel/GIT/8.x/core/utilities/focuspointmanagement -I /home/gilles/devel/GIT/8.x/core/utilities/fuzzysearch -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/geoiface/backends -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/geoiface/bookmark -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/geoiface/core -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/geoiface/correlator -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/geoiface/dragdrop -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/geoiface/items -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/geoiface/lookup -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/geoiface/reversegeocoding -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/geoiface/tiles -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/geoiface/tracks -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/geoiface/widgets -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/geomapwrapper -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/mapsearches -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/marble/astro -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/marble/blendings -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/marble/core -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/marble/geodata/data -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/marble/geodata/graphicsitem -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/marble/geodata/handlers/dgml -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/marble/geodata/handlers/kml -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/marble/geodata/parser -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/marble/geodata/scene -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/marble/geodata/writer -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/marble/geodata/writers/dgml -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/marble/geodata/writers/kml -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/marble/graphicsview -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/marble/layers -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/marble/models -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/marble/osm -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/marble/plugins -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/marble/plugins/render/atmosphere -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/marble/plugins/render/compass -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/marble/plugins/render/crosshairs -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/marble/plugins/render/graticule -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/marble/plugins/render/mapscale -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/marble/plugins/render/measure -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/marble/plugins/render/navigation -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/marble/plugins/render/overviewmap -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/marble/plugins/render/progress -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/marble/plugins/runner/cache -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/marble/plugins/runner/gpsbabel -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/marble/plugins/runner/gpx -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/marble/plugins/runner/gpx/handlers -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/marble/plugins/runner/json -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/marble/plugins/runner/kml -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/marble/plugins/runner/nominatim-reversegeocoding -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/marble/plugins/runner/osm -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/marble/plugins/runner/osm/o5mreader -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/marble/plugins/runner/osm/translators -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/marble/plugins/runner/osm/writers -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/marble/plugins/runner/pn2 -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/marble/plugins/runner/pnt -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/marble/projections -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/marble/runners -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/marble/settings -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/marble/storage -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/marble/tile -I /home/gilles/devel/GIT/8.x/core/utilities/imageeditor/core -I /home/gilles/devel/GIT/8.x/core/utilities/imageeditor/dialogs -I /home/gilles/devel/GIT/8.x/core/utilities/imageeditor/editor -I /home/gilles/devel/GIT/8.x/core/utilities/imageeditor/main -I /home/gilles/devel/GIT/8.x/core/utilities/imageeditor/widgets -I /home/gilles/devel/GIT/8.x/core/utilities/import/backend -I /home/gilles/devel/GIT/8.x/core/utilities/import/dialogs -I /home/gilles/devel/GIT/8.x/core/utilities/import/items -I /home/gilles/devel/GIT/8.x/core/utilities/import/main -I /home/gilles/devel/GIT/8.x/core/utilities/import/models -I /home/gilles/devel/GIT/8.x/core/utilities/import/views -I /home/gilles/devel/GIT/8.x/core/utilities/import/widgets -I /home/gilles/devel/GIT/8.x/core/utilities/lighttable -I /home/gilles/devel/GIT/8.x/core/utilities/maintenance -I /home/gilles/devel/GIT/8.x/core/utilities/queuemanager/dplugins -I /home/gilles/devel/GIT/8.x/core/utilities/queuemanager/main -I /home/gilles/devel/GIT/8.x/core/utilities/queuemanager/manager -I /home/gilles/devel/GIT/8.x/core/utilities/queuemanager/views -I /home/gilles/devel/GIT/8.x/core/utilities/searchwindow -I /home/gilles/devel/GIT/8.x/core/utilities/setup/album -I /home/gilles/devel/GIT/8.x/core/utilities/setup/camera -I /home/gilles/devel/GIT/8.x/core/utilities/setup/collections -I /home/gilles/devel/GIT/8.x/core/utilities/setup/downloader -I /home/gilles/devel/GIT/8.x/core/utilities/setup/editor -I /home/gilles/devel/GIT/8.x/core/utilities/setup/metadata -I /home/gilles/devel/GIT/8.x/core/utilities/setup/misc -I /home/gilles/devel/GIT/8.x/core/utilities/setup -I /home/gilles/devel/GIT/8.x/core/app/main -I /home/gilles/devel/GIT/8.x/core/app/date -I /home/gilles/devel/GIT/8.x/core/app/dragdrop -I /home/gilles/devel/GIT/8.x/core/app/views/stack -I /home/gilles/devel/GIT/8.x/core/app/views/utils -I /home/gilles/devel/GIT/8.x/core/app/items/utils -I /home/gilles/devel/GIT/8.x/core/app/items/delegate -I /home/gilles/devel/GIT/8.x/core/app/views/sidebar -I /home/gilles/devel/GIT/8.x/core/libs/dimg/filters/transform/lqr -I /usr/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.7.0 -I /opt/qt6/include/QtGui/6.7.0/QtGui -I /opt/qt6/include/QtCore/6.7.0 -I /opt/qt6/include/QtCore/6.7.0/QtCore -I /opt/qt6/include/QtDBus/6.7.0 -I /opt/qt6/include/QtDBus/6.7.0/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-18/lib/clang/18/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 /mnt/data2/devel/GIT/8.x/project/reports/report.scan/2024-05-02-171729-435512-1 -x c++ /home/gilles/devel/GIT/8.x/core/libs/dimg/filters/nr/nrestimate.cpp

/home/gilles/devel/GIT/8.x/core/libs/dimg/filters/nr/nrestimate.cpp

1/* ============================================================
2 *
3 * This file is a part of digiKam project
4 * https://www.digikam.org
5 *
6 * Date : 2012-10-18
7 * Description : Wavelets YCrCb Noise Reduction settings estimation by image content analys.
8 * Wavelets theory is based on "À Trous" Discrete Wavelet Transform
9 * described into "The Handbook of Astronomical Image Processing" book
10 * from Richard Berry and James Burnell, chapter 18.
11 * See this wiki page for details:
12 * community.kde.org/Digikam/SoK2012/AutoNR
13 *
14 * SPDX-FileCopyrightText: 2012-2013 by Sayantan Datta <sayantan dot knz at gmail dot com>
15 * SPDX-FileCopyrightText: 2012-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
16 *
17 * SPDX-License-Identifier: GPL-2.0-or-later
18 *
19 * ============================================================ */
20
21#include "nrestimate.h"
22
23// C++ includes
24
25#include <cmath>
26#include <cfloat>
27
28// OpenCV includes
29
30#include "digikam_opencv.h"
31
32// Qt includes
33
34#include <QTextStream>
35#include <QFile>
36
37// Local includes
38
39#include "digikam_debug.h"
40
41namespace Digikam
42{
43
44class Q_DECL_HIDDEN__attribute__((visibility("hidden"))) NREstimate::Private
45{
46public:
47
48 Private() = default;
49
50 NRContainer prm;
51
52 QString path; ///< Path to host log files.
53
54 float* fimg[3] = { nullptr };
55 const uint clusterCount = 30;
56 const uint size = 512; ///< Size of squared original image.
57};
58
59NREstimate::NREstimate(DImg* const img, QObject* const parent)
60 : DImgThreadedAnalyser(parent, QLatin1String("NREstimate")),
61 d (new Private)
62{
63 // Use the Top/Left corner of 256x256 pixels to analys noise contents from image.
64 // This will speed-up computation time with OpenCV
65
66 int w = (img->width() > d->size) ? d->size : img->width();
67 int h = (img->height() > d->size) ? d->size : img->height();
68 setOriginalImage(img->copy(0, 0, w, h));
69}
70
71NREstimate::~NREstimate()
72{
73 delete d;
74}
75
76void NREstimate::setLogFilesPath(const QString& path)
77{
78 d->path = path;
79}
80
81void NREstimate::readImage() const
82{
83 DColor col;
84
85 for (int c = 0 ; runningFlag() && (c < 3) ; ++c)
86 {
87 d->fimg[c] = new float[m_orgImage.numPixels()];
88 }
89
90 int j = 0;
91
92 for (uint y = 0 ; runningFlag() && (y < m_orgImage.height()) ; ++y)
93 {
94 for (uint x = 0 ; runningFlag() && (x < m_orgImage.width()) ; ++x)
95 {
96 col = m_orgImage.getPixelColor(x, y);
97 d->fimg[0][j] = col.red();
98 d->fimg[1][j] = col.green();
99 d->fimg[2][j] = col.blue();
100 j++;
101 }
102 }
103}
104
105NRContainer NREstimate::settings() const
106{
107 return d->prm;
108}
109
110void NREstimate::startAnalyse()
111{
112 readImage();
113 postProgress(5);
114
115 //--convert fimg to CvMat*-------------------------------------------------------------------------------
116
117 // convert the image into YCrCb color model
118
119 NRFilter::srgb2ycbcr(d->fimg, m_orgImage.numPixels());
120
121 // One dimensional CvMat which stores the image
122
123 CvMat* points = cvCreateMat(m_orgImage.numPixels(), 3, CV_32FC1(((5) & ((1 << 3) - 1)) + (((1)-1) << 3)));
124
125 // matrix to store the index of the clusters
126
127 CvMat* clusters = cvCreateMat(m_orgImage.numPixels(), 1, CV_32SC1(((4) & ((1 << 3) - 1)) + (((1)-1) << 3)));
128
129 // pointer variable to handle the CvMat* points (the image in CvMat format)
130
131 float* pointsPtr = reinterpret_cast<float*>(points->data.ptr);
132
133 for (uint x = 0 ; runningFlag() && (x < m_orgImage.numPixels()) ; ++x)
1
Assuming the condition is false
134 {
135 for (int y = 0 ; runningFlag() && (y < 3) ; ++y)
136 {
137 *pointsPtr++ = (float)d->fimg[y][x];
138 }
139 }
140
141 // Array to store the centers of the clusters
142
143 CvArr* centers = nullptr;
144
145 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/GIT/8.x/core/libs/dimg/filters/nr/nrestimate.cpp"
), 145, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "Everything ready for the cvKmeans2 or as it seems to";
2
Loop condition is false. Execution continues on line 146
146 postProgress(10);
147
148 //-- KMEANS ---------------------------------------------------------------------------------------------
149
150 cvKMeans2(points, d->clusterCount, clusters,
151 cvTermCriteria(CV_TERMCRIT_EPS2 + CV_TERMCRIT_ITER1, 10, 1.0), 3, nullptr, 0, centers, nullptr);
152
153 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/GIT/8.x/core/libs/dimg/filters/nr/nrestimate.cpp"
), 153, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "cvKmeans2 successfully run";
3
Loop condition is false. Execution continues on line 154
154 postProgress(15);
155
156 //-- Divide into cluster->columns, sample->rows, in matrix standard deviation ---------------------------
157
158 QScopedArrayPointer<int> rowPosition(new int[d->clusterCount]{});
4
Storing uninitialized value
5
Calling constructor for 'QScopedArrayPointer<int, QScopedPointerArrayDeleter<int>>'
8
Returning from constructor for 'QScopedArrayPointer<int, QScopedPointerArrayDeleter<int>>'
159
160 // The row position array would just make the hold the number of elements in each cluster
161
162 for (uint i = 0 ; runningFlag() && (i
9.1
'i' is < field 'clusterCount'
9.1
'i' is < field 'clusterCount'
< d->clusterCount
) ; ++i)
9
Assuming the condition is true
10
Loop condition is true. Entering loop body
11
Assuming the condition is true
12
Assuming 'i' is >= field 'clusterCount'
13
Loop condition is false. Execution continues on line 169
163 {
164 // initializing the cluster count array
165
166 rowPosition[i] = 0;
167 }
168
169 int rowIndex = 0;
170 int columnIndex = 0;
171
172 for (uint i = 0 ; runningFlag() && (i < m_orgImage.numPixels()) ; ++i)
14
Assuming the condition is false
173 {
174 columnIndex = clusters->data.i[i];
175 rowPosition[columnIndex]++;
176 }
177
178/*
179 qCDebug(DIGIKAM_DIMG_LOG) << "Lets see what the rowPosition array looks like : ";
180
181 for (uint i = 0 ; runningFlag() && (i < d->clusterCount) ; ++i)
182 {
183 qCDebug(DIGIKAM_DIMG_LOG) << "Cluster : "<< i << " the count is :" << rowPosition[i];
184 }
185*/
186
187 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/GIT/8.x/core/libs/dimg/filters/nr/nrestimate.cpp"
), 187, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "array indexed, and ready to find maximum";
15
Loop condition is false. Execution continues on line 188
188 postProgress(20);
189
190 //-- Finding maximum of the rowPosition array ------------------------------------------------------------
191
192 int max = rowPosition[0];
193
194 for (uint i = 1 ; runningFlag() && (i < d->clusterCount) ; ++i)
16
'i' initialized to 1
17
Assuming the condition is true
18
Assuming 'i' is < field 'clusterCount'
19
Loop condition is true. Entering loop body
195 {
196 if (rowPosition[i] > max)
20
Passing the value 1 via 1st parameter 'i'
21
The left operand of '>' is a garbage value
197 {
198 max = rowPosition[i];
199 }
200 }
201
202 QString maxString;
203 maxString.append(QString::number(max));
204
205 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/GIT/8.x/core/libs/dimg/filters/nr/nrestimate.cpp"
), 205, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< QString::fromLatin1("maximum declared = %1").arg(maxString);
206 postProgress(25);
207
208 //-- Divide and conquer ---------------------------------------------------------------------------------
209
210 CvMat* sd = cvCreateMat(max, (d->clusterCount * points->cols), CV_32FC1(((5) & ((1 << 3) - 1)) + (((1)-1) << 3)));
211
212 postProgress(30);
213
214 //-- Initialize the rowPosition array -------------------------------------------------------------------
215
216 QScopedArrayPointer<int> rPosition(new int[d->clusterCount]);
217
218 for (uint i = 0 ; runningFlag() && (i < d->clusterCount) ; ++i)
219 {
220 rPosition[i] = 0;
221 }
222
223 float* ptr = nullptr;
224
225 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/GIT/8.x/core/libs/dimg/filters/nr/nrestimate.cpp"
), 225, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "The rowPosition array is ready!";
226 postProgress(40);
227
228 for (uint i = 0 ; runningFlag() && (i < m_orgImage.numPixels()) ; ++i)
229 {
230 columnIndex = clusters->data.i[i];
231 rowIndex = rPosition[columnIndex];
232
233 // moving to the right row
234
235 ptr = reinterpret_cast<float*>(sd->data.ptr + rowIndex*(sd->step));
236
237 // moving to the right column
238
239 for (int j = 0 ; runningFlag() && (j < columnIndex) ; ++j)
240 {
241 for (int z = 0 ; runningFlag() && (z < (points->cols)) ; ++z)
242 {
243 ptr++;
244 }
245 }
246
247 for (int z = 0 ; runningFlag() && (z < (points->cols)) ; ++z)
248 {
249 *ptr++ = cvGet2D(points, i, z).val[0];
250 }
251
252 rPosition[columnIndex] = rPosition[columnIndex] + 1;
253 }
254
255 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/GIT/8.x/core/libs/dimg/filters/nr/nrestimate.cpp"
), 255, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "sd matrix creation over!";
256 postProgress(50);
257
258 //-- This part of the code would involve the sd matrix and make the mean and the std of the data -------------------
259
260 CvScalar std;
261 CvScalar mean;
262 int totalcount = 0; // Number of non-empty clusters
263 CvMat* meanStore = cvCreateMat(d->clusterCount, points->cols, CV_32FC1(((5) & ((1 << 3) - 1)) + (((1)-1) << 3)));
264 CvMat* stdStore = cvCreateMat(d->clusterCount, points->cols, CV_32FC1(((5) & ((1 << 3) - 1)) + (((1)-1) << 3)));
265 float* meanStorePtr = reinterpret_cast<float*>(meanStore->data.ptr);
266 float* stdStorePtr = reinterpret_cast<float*>(stdStore->data.ptr);
267
268 for (int i = 0 ; runningFlag() && (i < sd->cols) ; ++i)
269 {
270 // cppcheck-suppress knownConditionTrueFalse
271 if (runningFlag() && (rowPosition[(i/points->cols)] >= 1))
272 {
273 CvMat* workingArr = cvCreateMat(rowPosition[(i / points->cols)], 1, CV_32FC1(((5) & ((1 << 3) - 1)) + (((1)-1) << 3)));
274 ptr = reinterpret_cast<float*>(workingArr->data.ptr);
275
276 // cppcheck-suppress knownConditionTrueFalse
277 for (int j = 0 ; runningFlag() && (j < rowPosition[(i / (points->cols))]) ; ++j)
278 {
279 *ptr++ = cvGet2D(sd, j, i).val[0];
280 }
281
282 cvAvgSdv(workingArr, &mean, &std);
283 *meanStorePtr++ = (float)mean.val[0];
284 *stdStorePtr++ = (float)std.val[0];
285 totalcount++;
286 cvReleaseMat(&workingArr);
287 }
288 }
289
290 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/GIT/8.x/core/libs/dimg/filters/nr/nrestimate.cpp"
), 290, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "Make the mean and the std of the data";
291 postProgress(60);
292
293 // -----------------------------------------------------------------------------------------------------------------
294
295 meanStorePtr = reinterpret_cast<float*>(meanStore->data.ptr);
296 stdStorePtr = reinterpret_cast<float*>(stdStore->data.ptr);
297
298 if (runningFlag() && !d->path.isEmpty())
299 {
300 QString logFile = d->path;
301 logFile = logFile.section(QLatin1Char('/'), -1);
302 logFile = logFile.left(logFile.indexOf(QLatin1Char('.')));
303 logFile.append(QLatin1String("logMeanStd.txt"));
304
305 QFile filems(logFile);
306
307 if (filems.open(QIODevice::WriteOnly | QIODevice::Text))
308 {
309 QTextStream oms(&filems);
310 oms << "Mean Data\n";
311
312 for (int i = 0 ; i < totalcount ; ++i)
313 {
314 oms << *meanStorePtr++;
315 oms << "\t";
316
317 if (((i + 1) % 3) == 0)
318 {
319 oms << "\n";
320 }
321 }
322
323 oms << "\nStd Data\n";
324
325 for (int i = 0 ; i < totalcount ; ++i)
326 {
327 oms << *stdStorePtr++;
328 oms << "\t";
329
330 if (((i + 1) % 3) == 0)
331 {
332 oms << "\n";
333 }
334 }
335
336 filems.close();
337
338 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/GIT/8.x/core/libs/dimg/filters/nr/nrestimate.cpp"
), 338, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "Done with the basic work of storing the mean and the std";
339 }
340 }
341
342 postProgress(70);
343
344 //-- Calculating weighted mean, and weighted std -----------------------------------------------------------
345
346 QTextStream owms;
347 QFile filewms;
348
349 if (runningFlag() && !d->path.isEmpty())
350 {
351 QString logFile2 = d->path;
352 logFile2 = logFile2.section(QLatin1Char('/'), -1);
353 logFile2 = logFile2.left(logFile2.indexOf(QLatin1Char('.')));
354 logFile2.append(QLatin1String("logWeightedMeanStd.txt"));
355
356 filewms.setFileName(logFile2);
357
358 if (filewms.open(QIODevice::WriteOnly | QIODevice::Text))
359 owms.setDevice(&filewms);
360 }
361
362 QString info;
363 float weightedMean = 0.0f;
364 float weightedStd = 0.0f;
365 float datasd[3] = {0.0f, 0.0f, 0.0f};
366
367 for (int j = 0 ; runningFlag() && (j < points->cols) ; ++j)
368 {
369 meanStorePtr = reinterpret_cast<float*>(meanStore->data.ptr);
370 stdStorePtr = reinterpret_cast<float*>(stdStore->data.ptr);
371
372 for (int moveToChannel = 0 ; moveToChannel <= j ; ++moveToChannel)
373 {
374 meanStorePtr++;
375 stdStorePtr++;
376 }
377
378 for (uint i = 0 ; i < d->clusterCount ; ++i)
379 {
380 if (rowPosition[i] >= 1)
381 {
382 weightedMean += (*meanStorePtr) * rowPosition[i];
383 weightedStd += (*stdStorePtr) * rowPosition[i];
384 meanStorePtr += points->cols;
385 stdStorePtr += points->cols;
386 }
387 }
388
389 weightedMean = weightedMean / (m_orgImage.numPixels());
390 weightedStd = weightedStd / (m_orgImage.numPixels());
391 datasd[j] = weightedStd;
392
393 if (!d->path.isEmpty())
394 {
395 owms << QLatin1String("\nChannel : ") << j << QLatin1Char('\n');
396 owms << QLatin1String("Weighted Mean : ") << weightedMean << QLatin1Char('\n');
397 owms << QLatin1String("Weighted Std : ") << weightedStd << QLatin1Char('\n');
398 }
399
400 info.append(QLatin1String("\n\nChannel: "));
401 info.append(QString::number(j));
402 info.append(QLatin1String("\nWeighted Mean: "));
403 info.append(QString::number(weightedMean));
404 info.append(QLatin1String("\nWeighted Standard Deviation: "));
405 info.append(QString::number(weightedStd));
406 }
407
408 if (runningFlag() && !d->path.isEmpty())
409 {
410 filewms.close();
411 }
412
413 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/GIT/8.x/core/libs/dimg/filters/nr/nrestimate.cpp"
), 413, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "Info : " << info;
414 postProgress(80);
415
416 // -- adaptation ---------------------------------------------------------------------------------------
417
418 double L = 1.2;
419 double LSoft = 0.9;
420 double Cr = 1.2;
421 double CrSoft = 0.9;
422 double Cb = 1.2;
423 double CbSoft = 0.9;
424
425 if (runningFlag())
426 {
427 // for 16 bits images only
428
429 if (m_orgImage.sixteenBit())
430 {
431 for (int i = 0 ; i < points->cols ; ++i)
432 {
433 if (i < 3)
434 {
435 datasd[i] = datasd[i] / 256;
436 }
437 }
438 }
439
440 if (datasd[0] < 7)
441 {
442 L = datasd[0] - 0.98;
443 }
444
445 // cppcheck-suppress knownConditionTrueFalse
446 else if ((datasd[0] >= 7) && (datasd[0] < 8))
447 {
448 L = datasd[0] - 1.2;
449 }
450
451 else if ((datasd[0] >= 8) && (datasd[0] < 9))
452 {
453 L = datasd[0] - 1.5;
454 }
455
456 else
457 {
458 L = datasd[0] - 1.7;
459 }
460
461 if (L < 0)
462 {
463 L = 0;
464 }
465
466 if (L > 9)
467 {
468 L = 9;
469 }
470
471 Cr = datasd[2] * 0.8;
472 Cb = datasd[1] * 0.8;
473
474 if (Cr > 7)
475 {
476 Cr = 7;
477 }
478
479 if (Cb > 7)
480 {
481 Cb = 7;
482 }
483
484 L = floorf(L * 100) / 100;
485 Cb = floorf(Cb * 100) / 100;
486 Cr = floorf(Cr * 100) / 100;
487
488 if (L > 9)
489 {
490 LSoft = CrSoft = CbSoft = 0.8;
491 }
492 else if (L > 3)
493 {
494 LSoft = CrSoft = CbSoft = 0.7;
495 }
496 else
497 {
498 LSoft = CrSoft = CbSoft = 0.6;
499 }
500 }
501
502 d->prm.thresholds[0] = L;
503 d->prm.thresholds[1] = Cb;
504 d->prm.thresholds[2] = Cr;
505 d->prm.softness[0] = LSoft;
506 d->prm.softness[1] = CbSoft;
507 d->prm.softness[2] = CrSoft;
508
509 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/GIT/8.x/core/libs/dimg/filters/nr/nrestimate.cpp"
), 509, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "All is completed";
510 postProgress(90);
511
512 //-- releasing matrices and closing files ----------------------------------------------------------------------
513
514 cvReleaseMat(&sd);
515 cvReleaseMat(&stdStore);
516 cvReleaseMat(&meanStore);
517 cvReleaseMat(&points);
518 cvReleaseMat(&clusters);
519
520 for (uint i = 0 ; i < 3 ; ++i)
521 {
522 delete [] d->fimg[i];
523 }
524
525 postProgress(100);
526}
527
528} // namespace Digikam
529
530#include "moc_nrestimate.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)
6
Calling default constructor for 'QScopedPointer<int, QScopedPointerArrayDeleter<int>>'
7
Returning from default constructor for 'QScopedPointer<int, QScopedPointerArrayDeleter<int>>'
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