Bug Summary

File:/home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/storage/DownloadRegion.cpp
Warning:line 281, column 27
Called C++ object pointer is null

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 DownloadRegion.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/utilities/geolocation/engine -fcoverage-compilation-dir=/home/gilles/devel/GIT/8.x/build.scan/core/utilities/geolocation/engine -resource-dir /usr/lib/llvm-18/lib/clang/18 -D CMS_NO_REGISTER_KEYWORD=1 -D HAVE_FFMPEG_VERSION5 -D LIBPGF_DISABLE_OPENMP -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 USE_JASPER -D USE_JPEG -D USE_JPEG8 -D _GNU_SOURCE -D _LARGEFILE64_SOURCE -D digikamcore_EXPORTS -I /home/gilles/devel/GIT/8.x/build.scan/core/utilities/geolocation/engine -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine -I /home/gilles/devel/GIT/8.x/build.scan/core/utilities/geolocation/engine/core_marble_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 -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/engine/astro -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/blendings -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/core -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/geodata/data -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/geodata/graphicsitem -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/geodata/handlers/dgml -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/geodata/handlers/kml -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/geodata/parser -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/geodata/scene -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/geodata/writer -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/geodata/writers/dgml -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/geodata/writers/kml -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/graphicsview -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/layers -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/models -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/osm -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/plugins -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/plugins/render/atmosphere -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/plugins/render/compass -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/plugins/render/crosshairs -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/plugins/render/graticule -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/plugins/render/mapscale -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/plugins/render/measure -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/plugins/render/navigation -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/plugins/render/overviewmap -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/plugins/render/progress -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/plugins/runner/cache -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/plugins/runner/gpsbabel -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/plugins/runner/gpx -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/plugins/runner/gpx/handlers -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/plugins/runner/json -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/plugins/runner/kml -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/plugins/runner/nominatim-reversegeocoding -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/plugins/runner/osm -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/plugins/runner/osm/o5mreader -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/plugins/runner/osm/translators -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/plugins/runner/osm/writers -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/plugins/runner/pn2 -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/plugins/runner/pnt -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/projections -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/runners -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/settings -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/storage -I /home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/tile -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/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/main -I /home/gilles/devel/GIT/8.x/core/utilities/maintenance/manager -I /home/gilles/devel/GIT/8.x/core/utilities/maintenance/tools/autotags -I /home/gilles/devel/GIT/8.x/core/utilities/maintenance/tools/dbcleaner -I /home/gilles/devel/GIT/8.x/core/utilities/maintenance/tools/dbscan -I /home/gilles/devel/GIT/8.x/core/utilities/maintenance/tools/duplicates -I /home/gilles/devel/GIT/8.x/core/utilities/maintenance/tools/facesmanagement -I /home/gilles/devel/GIT/8.x/core/utilities/maintenance/tools/fingerprints -I /home/gilles/devel/GIT/8.x/core/utilities/maintenance/tools/imgqsort -I /home/gilles/devel/GIT/8.x/core/utilities/maintenance/tools/metaremover -I /home/gilles/devel/GIT/8.x/core/utilities/maintenance/tools/metasync -I /home/gilles/devel/GIT/8.x/core/utilities/maintenance/tools/thumbs -I /home/gilles/devel/GIT/8.x/core/utilities/maintenance/utils -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/views/sidebar -I /home/gilles/devel/GIT/8.x/core/app/items/utils -I /home/gilles/devel/GIT/8.x/core/app/items/overlays -I /home/gilles/devel/GIT/8.x/core/app/items/views -I /home/gilles/devel/GIT/8.x/core/app/items/thumbbar -I /home/gilles/devel/GIT/8.x/core/app/views/preview -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 /opt/qt6/include/QtXml -I /opt/qt6/include/QtSvg -I /opt/qt6/include/QtConcurrent -I /opt/qt6/include/KF6/KI18n -I /opt/qt6/include/KF6/KConfig -I /opt/qt6/include/KF6/KConfigCore -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-07-24-085343-476556-1 -x c++ /home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/storage/DownloadRegion.cpp
1/* ============================================================
2 *
3 * This file is a part of digiKam project
4 * https://www.digikam.org
5 *
6 * Date : 2023-05-15
7 * Description : geolocation engine based on Marble.
8 * (c) 2007-2022 Marble Team
9 * https://invent.kde.org/education/marble/-/raw/master/data/credits_authors.html
10 *
11 * SPDX-FileCopyrightText: 2023-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
12 *
13 * SPDX-License-Identifier: LGPL-2.1-or-later
14 *
15 * ============================================================ */
16
17#include "DownloadRegion.h"
18
19// Local includes
20
21#include "MarbleModel.h"
22#include "MarbleMap.h"
23#include "MarbleMath.h"
24#include "TextureLayer.h"
25#include "GeoDataLatLonAltBox.h"
26#include "GeoDataLineString.h"
27#include "GeoSceneDocument.h"
28#include "GeoSceneMap.h"
29#include "GeoSceneLayer.h"
30#include "GeoSceneTileDataset.h"
31#include "GeoSceneAbstractTileProjection.h"
32#include "TileCoordsPyramid.h"
33#include "digikam_debug.h"
34
35namespace Marble
36{
37
38class Q_DECL_HIDDEN__attribute__((visibility("hidden"))) DownloadRegionPrivate
39{
40public:
41
42 MarbleModel* m_marbleModel = nullptr;
43
44 QPair<int, int> m_tileLevelRange;
45
46 int m_visibleTileLevel;
47
48public:
49
50 DownloadRegionPrivate();
51
52 int rad2PixelX(qreal const lon, const TileLayer* tileLayer) const;
53
54 int rad2PixelY(qreal const lat, const TileLayer* tileLayer) const;
55};
56
57DownloadRegionPrivate::DownloadRegionPrivate() : m_marbleModel(nullptr),
58 m_tileLevelRange(0, 0), m_visibleTileLevel(0)
59{
60 // nothing to do
61}
62
63// copied from AbstractScanlineTextureMapper and slightly adjusted
64int DownloadRegionPrivate::rad2PixelX(qreal const lon, const TileLayer* tileLayer) const
65{
66 qreal tileWidth = tileLayer && tileLayer->layerCount() > 0 ? tileLayer->tileSize().width() : 256;
67 qreal const globalWidth = tileWidth * tileLayer->tileColumnCount(m_visibleTileLevel);
68 return static_cast<int>(globalWidth * 0.5 * (1 + lon / M_PI3.14159265358979323846));
69}
70
71// copied from AbstractScanlineTextureMapper and slightly adjusted
72int DownloadRegionPrivate::rad2PixelY(qreal const lat, const TileLayer* tileLayer) const
73{
74 if (tileLayer)
75 {
76 qreal tileHeight = (tileLayer->layerCount() > 0) ? tileLayer->tileSize().height()
77 : 256;
78 qreal const globalHeight = tileHeight * tileLayer->tileRowCount(m_visibleTileLevel);
79
80 switch (tileLayer->tileProjection()->type())
81 {
82 case GeoSceneAbstractTileProjection::Equirectangular:
83 {
84 return static_cast<int>(globalHeight * (0.5 - lat / M_PI3.14159265358979323846));
85 }
86
87 case GeoSceneAbstractTileProjection::Mercator:
88 {
89 if (fabs(lat) < 1.4835)
90 {
91 return static_cast<int>(globalHeight * 0.5 * (1 - gdInv(lat) / M_PI3.14159265358979323846));
92 }
93
94 if (lat >= +1.4835)
95 {
96 return static_cast<int>(globalHeight * 0.5 * (1 - 3.1309587 / M_PI3.14159265358979323846));
97 }
98
99 if (lat <= -1.4835)
100 {
101 return static_cast<int>(globalHeight * 0.5 * (1 + 3.1309587 / M_PI3.14159265358979323846));
102 }
103 }
104 }
105 }
106
107 // Dummy value to avoid a warning.
108 return 0;
109}
110
111DownloadRegion::DownloadRegion(QObject* parent) : QObject(parent),
112 d(new DownloadRegionPrivate)
113{
114 // nothing to do
115}
116
117void DownloadRegion::setMarbleModel(MarbleModel* model)
118{
119 d->m_marbleModel = model;
120}
121
122DownloadRegion::~DownloadRegion()
123{
124 delete d;
125}
126
127void DownloadRegion::setTileLevelRange(const int minimumTileLevel, const int maximumTileLevel)
128{
129 Q_ASSERT(minimumTileLevel >= 0)((minimumTileLevel >= 0) ? static_cast<void>(0) : qt_assert
("minimumTileLevel >= 0", "/home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/storage/DownloadRegion.cpp"
, 129))
;
130 Q_ASSERT(maximumTileLevel >= 0)((maximumTileLevel >= 0) ? static_cast<void>(0) : qt_assert
("maximumTileLevel >= 0", "/home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/storage/DownloadRegion.cpp"
, 130))
;
131 Q_ASSERT(minimumTileLevel <= maximumTileLevel)((minimumTileLevel <= maximumTileLevel) ? static_cast<void
>(0) : qt_assert("minimumTileLevel <= maximumTileLevel"
, "/home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/storage/DownloadRegion.cpp"
, 131))
;
132 d->m_tileLevelRange.first = minimumTileLevel;
133 d->m_tileLevelRange.second = maximumTileLevel;
134}
135
136QVector<TileCoordsPyramid> DownloadRegion::region(const TileLayer* tileLayer, const GeoDataLatLonAltBox& downloadRegion) const
137{
138 Q_ASSERT(tileLayer)((tileLayer) ? static_cast<void>(0) : qt_assert("tileLayer"
, "/home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/storage/DownloadRegion.cpp"
, 138))
;
139
140 int tileLevelRangeFirst = d->m_tileLevelRange.first;
141 int tileLevelRangeSecond = d->m_tileLevelRange.second;
142
143 TileType tileType = dynamic_cast<const TextureLayer*>(tileLayer) ? TextureTileType : VectorTileType;
144
145 QVector<int> validLevels;
146 validLevels = validTileLevels(tileType);
147
148 // Align the tileLevelRangeSecond with the validTileLevels
149 if (!validLevels.isEmpty())
150 {
151 int lastIndex = validLevels.count() - 1;
152
153 for (int i = 0; i < validLevels.count(); ++i)
154 {
155 if (validLevels.at(lastIndex - i) <= tileLevelRangeSecond
156 && validLevels.at(lastIndex - i) >= tileLevelRangeFirst)
157 {
158 tileLevelRangeSecond = validLevels.at(lastIndex - i);
159 break;
160 }
161 }
162 }
163
164 int const westX = d->rad2PixelX(downloadRegion.west(), tileLayer);
165 int const northY = d->rad2PixelY(downloadRegion.north(), tileLayer);
166 int const eastX = d->rad2PixelX(downloadRegion.east(), tileLayer);
167 int const southY = d->rad2PixelY(downloadRegion.south(), tileLayer);
168
169 // FIXME: remove this stuff
170 qCDebug(DIGIKAM_MARBLE_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category
((DIGIKAM_MARBLE_LOG)()); qt_category; qt_category.control = false
) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/storage/DownloadRegion.cpp"
), 170, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "DownloadRegionDialog downloadRegion:"
171 << "north:" << downloadRegion.north()
172 << "south:" << downloadRegion.south()
173 << "east:" << downloadRegion.east()
174 << "west:" << downloadRegion.west();
175 qCDebug(DIGIKAM_MARBLE_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category
((DIGIKAM_MARBLE_LOG)()); qt_category; qt_category.control = false
) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/storage/DownloadRegion.cpp"
), 175, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "north/west (x/y):" << westX << northY;
176 qCDebug(DIGIKAM_MARBLE_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category
((DIGIKAM_MARBLE_LOG)()); qt_category; qt_category.control = false
) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/storage/DownloadRegion.cpp"
), 176, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "south/east (x/y):" << eastX << southY;
177
178 int const tileWidth = tileLayer->tileSize().width();
179 int const tileHeight = tileLayer->tileSize().height();
180 qCDebug(DIGIKAM_MARBLE_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category
((DIGIKAM_MARBLE_LOG)()); qt_category; qt_category.control = false
) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/storage/DownloadRegion.cpp"
), 180, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "DownloadRegionDialog downloadRegion: tileSize:" << tileWidth << tileHeight;
181
182 int const visibleLevelX1 = qMin(westX, eastX);
183 int const visibleLevelY1 = qMin(northY, southY);
184 int const visibleLevelX2 = qMax(westX, eastX);
185 int const visibleLevelY2 = qMax(northY, southY);
186
187 qCDebug(DIGIKAM_MARBLE_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category
((DIGIKAM_MARBLE_LOG)()); qt_category; qt_category.control = false
) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/storage/DownloadRegion.cpp"
), 187, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "visible level pixel coords (level/x1/y1/x2/y2):" << d->m_visibleTileLevel
188 << visibleLevelX1 << visibleLevelY1 << visibleLevelX2 << visibleLevelY2;
189
190 int bottomLevelX1, bottomLevelY1, bottomLevelX2, bottomLevelY2;
191
192 // the pixel coords calculated above are referring to the visible tile level,
193 // if the bottom level is a different level, we have to take it into account
194 if (d->m_visibleTileLevel > tileLevelRangeSecond)
195 {
196 int const deltaLevel = d->m_visibleTileLevel - tileLevelRangeSecond;
197 bottomLevelX1 = visibleLevelX1 >> deltaLevel;
198 bottomLevelY1 = visibleLevelY1 >> deltaLevel;
199 bottomLevelX2 = visibleLevelX2 >> deltaLevel;
200 bottomLevelY2 = visibleLevelY2 >> deltaLevel;
201 }
202
203 else if (d->m_visibleTileLevel < tileLevelRangeSecond)
204 {
205 int const deltaLevel = tileLevelRangeSecond - d->m_visibleTileLevel;
206 bottomLevelX1 = visibleLevelX1 << deltaLevel;
207 bottomLevelY1 = visibleLevelY1 << deltaLevel;
208 bottomLevelX2 = visibleLevelX2 << deltaLevel;
209 bottomLevelY2 = visibleLevelY2 << deltaLevel;
210 }
211
212 else
213 {
214 bottomLevelX1 = visibleLevelX1;
215 bottomLevelY1 = visibleLevelY1;
216 bottomLevelX2 = visibleLevelX2;
217 bottomLevelY2 = visibleLevelY2;
218 }
219
220 qCDebug(DIGIKAM_MARBLE_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category
((DIGIKAM_MARBLE_LOG)()); qt_category; qt_category.control = false
) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/storage/DownloadRegion.cpp"
), 220, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "bottom level pixel coords (level/x1/y1/x2/y2):"
221 << tileLevelRangeSecond
222 << bottomLevelX1 << bottomLevelY1 << bottomLevelX2 << bottomLevelY2;
223
224 TileCoordsPyramid coordsPyramid(tileLevelRangeFirst, tileLevelRangeSecond);
225 coordsPyramid.setValidTileLevels(validLevels);
226
227 QRect bottomLevelTileCoords;
228 bottomLevelTileCoords.setCoords
229 (bottomLevelX1 / tileWidth,
230 bottomLevelY1 / tileHeight,
231 bottomLevelX2 / tileWidth + (bottomLevelX2 % tileWidth > 0 ? 1 : 0) - 1, // -1 needed for proper counting
232 bottomLevelY2 / tileHeight + (bottomLevelY2 % tileHeight > 0 ? 1 : 0) - 1); // -1 needed for proper counting
233 qCDebug(DIGIKAM_MARBLE_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category
((DIGIKAM_MARBLE_LOG)()); qt_category; qt_category.control = false
) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/storage/DownloadRegion.cpp"
), 233, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "bottom level tile coords: (x1/y1/size):" << bottomLevelTileCoords;
234 coordsPyramid.setBottomLevelCoords(bottomLevelTileCoords);
235
236 qCDebug(DIGIKAM_MARBLE_LOG)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category
((DIGIKAM_MARBLE_LOG)()); qt_category; qt_category.control = false
) QMessageLogger(static_cast<const char *>("/home/gilles/devel/GIT/8.x/core/utilities/geolocation/engine/storage/DownloadRegion.cpp"
), 236, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "tiles count:" << coordsPyramid.tilesCount();
237 QVector<TileCoordsPyramid> pyramid;
238 pyramid << coordsPyramid;
239 return pyramid;
240}
241
242void DownloadRegion::setVisibleTileLevel(const int tileLevel)
243{
244 d->m_visibleTileLevel = tileLevel;
245}
246
247QVector<TileCoordsPyramid> DownloadRegion::fromPath(const TileLayer* tileLayer, qreal offset, const GeoDataLineString& waypoints) const
248{
249 if (!d->m_marbleModel)
1
Assuming field 'm_marbleModel' is non-null
2
Taking false branch
250 {
251 return QVector<TileCoordsPyramid>();
252 }
253
254 int tileLevelRangeFirst = d->m_tileLevelRange.first;
255 int tileLevelRangeSecond = d->m_tileLevelRange.second;
256
257 TileType tileType = dynamic_cast<const TextureLayer*>(tileLayer) ? TextureTileType : VectorTileType;
3
Assuming 'tileLayer' is null
4
'?' condition is false
258
259 QVector<int> validLevels;
260 validLevels = validTileLevels(tileType);
261
262 // Align the tileLevelRangeSecond with the validTileLevels
263 if (!validLevels.isEmpty())
5
Assuming the condition is false
6
Taking false branch
264 {
265 int lastIndex = validLevels.count() - 1;
266
267 for (int i = 0; i < validLevels.count(); ++i)
268 {
269 if (validLevels.at(lastIndex - i) <= tileLevelRangeSecond
270 && validLevels.at(lastIndex - i) >= tileLevelRangeFirst)
271 {
272 tileLevelRangeSecond = validLevels.at(lastIndex - i);
273 break;
274 }
275 }
276 }
277
278 TileCoordsPyramid coordsPyramid(tileLevelRangeFirst, tileLevelRangeSecond);
279 coordsPyramid.setValidTileLevels(validLevels);
280
281 int const tileWidth = tileLayer->tileSize().width();
7
Called C++ object pointer is null
282 int const tileHeight = tileLayer->tileSize().height();
283
284 qreal radius = d->m_marbleModel->planetRadius();
285 QVector<TileCoordsPyramid> pyramid;
286 qreal radianOffset = offset / radius;
287
288 for (int i = 1; i < waypoints.size(); ++i)
289 {
290 GeoDataCoordinates position = waypoints[i];
291 qreal lonCenter = position.longitude();
292 qreal latCenter = position.latitude();
293
294 // coordinates of the of the vertices of the square(topleft and bottomright) at an offset distance from the waypoint
295 qreal latNorth = asin(sin(latCenter) * cos(radianOffset) + cos(latCenter) * sin(radianOffset) * cos(7 * M_PI3.14159265358979323846 / 4));
296 qreal dlonWest = atan2(sin(7 * M_PI3.14159265358979323846 / 4) * sin(radianOffset) * cos(latCenter), cos(radianOffset) - sin(latCenter) * sin(latNorth));
297 qreal lonWest = fmod(lonCenter - dlonWest + M_PI3.14159265358979323846, 2 * M_PI3.14159265358979323846) - M_PI3.14159265358979323846;
298 qreal latSouth = asin(sin(latCenter) * cos(radianOffset) + cos(latCenter) * sin(radianOffset) * cos(3 * M_PI3.14159265358979323846 / 4));
299 qreal dlonEast = atan2(sin(3 * M_PI3.14159265358979323846 / 4) * sin(radianOffset) * cos(latCenter), cos(radianOffset) - sin(latCenter) * sin(latSouth));
300 qreal lonEast = fmod(lonCenter - dlonEast + M_PI3.14159265358979323846, 2 * M_PI3.14159265358979323846) - M_PI3.14159265358979323846;
301
302 int const northY = d->rad2PixelY(latNorth, tileLayer);
303 int const southY = d->rad2PixelY(latSouth, tileLayer);
304 int const eastX = d->rad2PixelX(lonEast, tileLayer);
305 int const westX = d->rad2PixelX(lonWest, tileLayer);
306
307 int const west = qMin(westX, eastX);
308 int const north = qMin(northY, southY);
309 int const east = qMax(westX, eastX);
310 int const south = qMax(northY, southY);
311
312 int bottomLevelTileX1 = 0;
313 int bottomLevelTileY1 = 0;
314 int bottomLevelTileX2 = 0;
315 int bottomLevelTileY2 = 0;
316
317 if (d->m_visibleTileLevel > tileLevelRangeSecond)
318 {
319 int const deltaLevel = d->m_visibleTileLevel - tileLevelRangeSecond;
320 bottomLevelTileX1 = west >> deltaLevel;
321 bottomLevelTileY1 = north >> deltaLevel;
322 bottomLevelTileX2 = east >> deltaLevel;
323 bottomLevelTileY2 = south >> deltaLevel;
324 }
325
326 else if (d->m_visibleTileLevel < tileLevelRangeSecond)
327 {
328 int const deltaLevel = tileLevelRangeSecond - d->m_visibleTileLevel;
329 bottomLevelTileX1 = west << deltaLevel;
330 bottomLevelTileY1 = north << deltaLevel;
331 bottomLevelTileX2 = east << deltaLevel;
332 bottomLevelTileY2 = south << deltaLevel;
333 }
334
335 else
336 {
337 bottomLevelTileX1 = west;
338 bottomLevelTileY1 = north;
339 bottomLevelTileX2 = east;
340 bottomLevelTileY2 = south;
341 }
342
343 QRect waypointRegion;
344 //square region around the waypoint
345 waypointRegion.setCoords(bottomLevelTileX1 / tileWidth, bottomLevelTileY1 / tileHeight,
346 bottomLevelTileX2 / tileWidth, bottomLevelTileY2 / tileHeight);
347 coordsPyramid.setBottomLevelCoords(waypointRegion);
348 pyramid << coordsPyramid;
349 }
350
351 return pyramid;
352}
353
354QVector<int> DownloadRegion::validTileLevels(const TileType tileType) const
355{
356 QVector<int> validTileLevels;
357
358 GeoSceneMap* map = d->m_marbleModel->mapTheme()->map();
359 QVector<GeoSceneLayer*> layers = map->layers();
360
361 for (auto layer : layers)
362 {
363 if ((layer->backend() == QString::fromUtf8("vectortile") && tileType == VectorTileType)
364 || (layer->backend() == QString::fromUtf8("texture") && tileType == TextureTileType))
365 {
366 GeoSceneTileDataset* dataset = dynamic_cast<GeoSceneTileDataset*>(layer->datasets().first());
367 validTileLevels = dataset->tileLevels();
368 break;
369 }
370 }
371
372 return validTileLevels;
373}
374
375} // namespace Marble
376
377#include "moc_DownloadRegion.cpp"