Bug Summary

File:/home/gilles/Devel/8.x/core/libs/dimg/filters/transform/autocrop.cpp
Warning:line 956, column 22
The right 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 autocrop.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 -fcoverage-compilation-dir=/home/gilles/Devel/8.x/build.scan/core/libs/dimg -resource-dir /usr/lib/llvm-16/lib/clang/16 -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 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_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/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/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/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/geolocation/marble/astro -I /home/gilles/Devel/8.x/core/utilities/geolocation/marble/blendings -I /home/gilles/Devel/8.x/core/utilities/geolocation/marble/core -I /home/gilles/Devel/8.x/core/utilities/geolocation/marble/geodata/data -I /home/gilles/Devel/8.x/core/utilities/geolocation/marble/geodata/graphicsitem -I /home/gilles/Devel/8.x/core/utilities/geolocation/marble/geodata/handlers/dgml -I /home/gilles/Devel/8.x/core/utilities/geolocation/marble/geodata/handlers/kml -I /home/gilles/Devel/8.x/core/utilities/geolocation/marble/geodata/parser -I /home/gilles/Devel/8.x/core/utilities/geolocation/marble/geodata/scene -I /home/gilles/Devel/8.x/core/utilities/geolocation/marble/geodata/writer -I /home/gilles/Devel/8.x/core/utilities/geolocation/marble/geodata/writers/dgml -I /home/gilles/Devel/8.x/core/utilities/geolocation/marble/geodata/writers/kml -I /home/gilles/Devel/8.x/core/utilities/geolocation/marble/graphicsview -I /home/gilles/Devel/8.x/core/utilities/geolocation/marble/layers -I /home/gilles/Devel/8.x/core/utilities/geolocation/marble/models -I /home/gilles/Devel/8.x/core/utilities/geolocation/marble/osm -I /home/gilles/Devel/8.x/core/utilities/geolocation/marble/plugins -I /home/gilles/Devel/8.x/core/utilities/geolocation/marble/plugins/render/atmosphere -I /home/gilles/Devel/8.x/core/utilities/geolocation/marble/plugins/render/compass -I /home/gilles/Devel/8.x/core/utilities/geolocation/marble/plugins/render/crosshairs -I /home/gilles/Devel/8.x/core/utilities/geolocation/marble/plugins/render/graticule -I /home/gilles/Devel/8.x/core/utilities/geolocation/marble/plugins/render/mapscale -I /home/gilles/Devel/8.x/core/utilities/geolocation/marble/plugins/render/measure -I /home/gilles/Devel/8.x/core/utilities/geolocation/marble/plugins/render/navigation -I /home/gilles/Devel/8.x/core/utilities/geolocation/marble/plugins/render/overviewmap -I /home/gilles/Devel/8.x/core/utilities/geolocation/marble/plugins/render/progress -I /home/gilles/Devel/8.x/core/utilities/geolocation/marble/plugins/runner/cache -I /home/gilles/Devel/8.x/core/utilities/geolocation/marble/plugins/runner/gpsbabel -I /home/gilles/Devel/8.x/core/utilities/geolocation/marble/plugins/runner/gpx -I /home/gilles/Devel/8.x/core/utilities/geolocation/marble/plugins/runner/gpx/handlers -I /home/gilles/Devel/8.x/core/utilities/geolocation/marble/plugins/runner/json -I /home/gilles/Devel/8.x/core/utilities/geolocation/marble/plugins/runner/kml -I /home/gilles/Devel/8.x/core/utilities/geolocation/marble/plugins/runner/nominatim-reversegeocoding -I /home/gilles/Devel/8.x/core/utilities/geolocation/marble/plugins/runner/osm -I /home/gilles/Devel/8.x/core/utilities/geolocation/marble/plugins/runner/osm/o5mreader -I /home/gilles/Devel/8.x/core/utilities/geolocation/marble/plugins/runner/osm/translators -I /home/gilles/Devel/8.x/core/utilities/geolocation/marble/plugins/runner/osm/writers -I /home/gilles/Devel/8.x/core/utilities/geolocation/marble/plugins/runner/pn2 -I /home/gilles/Devel/8.x/core/utilities/geolocation/marble/plugins/runner/pnt -I /home/gilles/Devel/8.x/core/utilities/geolocation/marble/projections -I /home/gilles/Devel/8.x/core/utilities/geolocation/marble/runners -I /home/gilles/Devel/8.x/core/utilities/geolocation/marble/settings -I /home/gilles/Devel/8.x/core/utilities/geolocation/marble/storage -I /home/gilles/Devel/8.x/core/utilities/geolocation/marble/tile -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 -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 /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-16/lib/clang/16/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 -fdebug-compilation-dir=/home/gilles/Devel/8.x/build.scan/core/libs/dimg -ferror-limit 19 -fvisibility=hidden -fvisibility-inlines-hidden -fno-operator-names -fopenmp -fgnuc-version=4.2.1 -fno-implicit-modules -fcxx-exceptions -fexceptions -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /mnt/data/Devel/8.x/project/reports/report.scan/2024-04-22-145814-394276-1 -x c++ /home/gilles/Devel/8.x/core/libs/dimg/filters/transform/autocrop.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 : Auto Crop analyzer
8 * Algorithm based on black point detection on
9 * the basis of spiral traversal
10 *
11 * SPDX-FileCopyrightText: 2013 by Sayantan Datta <sayantan dot knz at gmail dot com>
12 * SPDX-FileCopyrightText: 2013-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
13 *
14 * SPDX-License-Identifier: GPL-2.0-or-later
15 *
16 * ============================================================ */
17
18#include "autocrop.h"
19
20// C++ includes
21
22#include <cmath>
23#include <cfloat>
24
25// Qt includes
26
27#include <QTextStream>
28#include <QFile>
29#include <QPoint>
30#include <QColor>
31
32// Local includes
33
34#include "digikam_debug.h"
35
36namespace Digikam
37{
38
39class Q_DECL_HIDDEN__attribute__((visibility("hidden"))) AutoCrop::Private
40{
41public:
42
43 Private() = default;
44
45 QRect cropArea;
46};
47
48AutoCrop::AutoCrop(DImg* const img, QObject* const parent)
49 : DImgThreadedAnalyser(parent, QLatin1String("AutoCrop")),
50 d (new Private)
51{
52 setOriginalImage(*img);
53}
54
55AutoCrop::~AutoCrop()
56{
57 delete d;
58}
59
60QRect AutoCrop::spiralClockwiseTraversal(const QImage& source, int topCrop, int bottomCrop)
61{
62 int i, j, ni;
63
64 if (topCrop == -1)
65 {
66 topCrop = 0;
67 }
68
69 if (bottomCrop == -1)
70 {
71 bottomCrop = source.height();
72 }
73
74 QSize resultsize = QSize(source.width(), (source.height() - topCrop - (source.height() - bottomCrop)));
75 QImage threshold = QImage(resultsize, QImage::Format_RGB888);
76
77 for (i = topCrop, ni = 0 ; i < bottomCrop ; ++i, ++ni)
78 {
79 for (j = 0 ; j < source.width() ; ++j)
80 {
81 threshold.setPixel(j, ni, source.pixel(j, i));
82 }
83 }
84
85 QColor c;
86 int limitcolumn = threshold.width();
87 int limitrow = threshold.height();
88 int centeri = ((limitrow/2)-1);
89 int centerj = ((limitcolumn/2)-1);
90 int startrighti = 0;
91 int startrightj = 0;
92 int endrighti = 0;
93 int endrightj = 0;
94 int startlefti = 0;
95 int startleftj = 0;
96 int endlefti = 0;
97 int endleftj = 0;
98 int startupi = 0;
99 int startupj = 0;
100 int endupi = 0;
101 int endupj = 0;
102 int startdowni = 0;
103 int startdownj = 0;
104 int enddowni = 0;
105 int enddownj = 0;
106 int travelright = 0;
107 int travelleft = 0;
108 int travelup = 0;
109 int traveldown = 0;
110 int rightmargin = 0;
111 int leftmargin = 0;
112 int bottommargin = 0;
113 int topmargin = 0;
114 int counter = 0;
115 bool fixtopmargin = false;
116 bool fixrightmargin = false;
117 bool fixleftmargin = false;
118 bool fixbottommargin = false;
119/*
120 int count = limitcolumn + limitrow -1;
121*/
122 bool rightEdge = false;
123 bool leftEdge = false;
124 bool topEdge = false;
125 bool bottomEdge = false;
126
127 endupi = centeri;
128 endupj = centerj;
129 travelright = -1;
130 traveldown = -1;
131 travelleft = 0;
132 travelup = 0;
133
134 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/transform/autocrop.cpp"
), 134, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "Center pixel : " << centerj << " , " << centeri;
135
136 while (true)
137 {
138 //qCDebug(DIGIKAM_DIMG_LOG) << "count = "<<count;
139
140 switch (counter % 4)
141 {
142 case 0: // traveling right
143 {
144 if (fixtopmargin == true)
145 {
146 if (fixrightmargin == false)
147 {
148 endrightj++;
149
150 if (endrightj >= threshold.width())
151 {
152 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/transform/autocrop.cpp"
), 152, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "We cannot go right anymore";
153 fixrightmargin = true;
154 rightmargin = limitcolumn - 1;
155 rightEdge = true;
156 }
157 }
158
159 break;
160 }
161
162 travelright += 2;
163
164 if (fixrightmargin == true)
165 {
166 travelright--;
167 }
168
169 if (fixleftmargin == true)
170 {
171 travelright--;
172 }
173
174 //qCDebug(DIGIKAM_DIMG_LOG) << "TRAVELING RIGHT";
175 //qCDebug(DIGIKAM_DIMG_LOG) << "Endupi" << endupi;
176 startrighti = endupi;
177 startrightj = endupj;
178 endrightj = startrightj + travelright;
179 //qCDebug(DIGIKAM_DIMG_LOG) << "Moving Right EndRight = " << endrightj;
180
181 if (endrightj >= limitcolumn)
182 {
183 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/transform/autocrop.cpp"
), 183, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "We have reached limitcolumn, i.e. width";
184 endrightj = limitcolumn - 1;
185 fixrightmargin = true;
186 rightmargin = limitcolumn - 1;
187 counter++;
188 travelright--;
189 rightEdge = true;
190 }
191
192 i = startrighti;
193 j = startrightj;
194 (void)j; // Remove clang warnings.
195
196 for (j = startrightj + 1 ; j <= endrightj ; ++j)
197 {
198 //qCDebug(DIGIKAM_DIMG_LOG) << "At pixel "<< j << " , " << i;
199 c = QColor::fromRgb(threshold.pixel(j,i));
200
201 if (c == Qt::black)
202 {
203 // we have found an empty space
204
205 fixtopmargin = true;
206 topmargin = i;
207 endupi++;
208 travelup--;
209 break;
210 }
211 }
212
213 endrighti = startrighti;
214
215 break;
216 }
217
218 case 1: // traveling down
219 {
220 if (fixrightmargin == true)
221 {
222 if (fixbottommargin == false)
223 {
224 enddowni++;
225
226 if (enddowni >= limitrow)
227 {
228 fixbottommargin = true;
229 bottommargin = limitrow - 1;
230 bottomEdge = true;
231 }
232 }
233
234 //endrightj--;
235 //qCDebug(DIGIKAM_DIMG_LOG) << "Traveling down : Case Skipped\n";
236 break;
237 }
238
239 traveldown += 2;
240
241 if (fixbottommargin == true)
242 {
243 traveldown--;
244 }
245
246 if (fixtopmargin == true)
247 {
248 traveldown--;
249 }
250
251 startdowni = endrighti;
252 startdownj = endrightj;
253 enddowni = startdowni + traveldown;
254 //qCDebug(DIGIKAM_DIMG_LOG) << "Moving Down EndDown = " << enddowni;
255
256 if (enddowni >= limitrow)
257 {
258 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/transform/autocrop.cpp"
), 258, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "We have reached limitrow, i.e. Height";
259 enddowni = limitrow - 1;
260 counter++;
261 bottommargin = limitrow - 1;
262 fixbottommargin = true;
263 traveldown--;
264 bottomEdge = true;
265 }
266
267 i = startdowni;
268 (void)i; // Remove clang warning.
269 j = startdownj;
270
271 for (i = startdowni + 1 ; i <= enddowni ; ++i)
272 {
273// qCDebug(DIGIKAM_DIMG_LOG) << "At pixel "<< j << " , " << i;
274 c = QColor::fromRgb(threshold.pixel(j,i));
275
276 if (c == Qt::black)
277 {
278 //we have found an empty space
279
280 fixrightmargin = true;
281 rightmargin = j;
282 endrightj--;
283 travelright--;
284 break;
285 }
286 }
287
288 enddownj = startdownj;
289
290 break;
291 }
292 case 2 : //traveling left
293 {
294 if (fixbottommargin == true)
295 {
296 if (fixleftmargin == false)
297 {
298 endleftj--;
299
300 if (endleftj < 0)
301 {
302 fixleftmargin = true;
303 leftmargin = 0;
304 leftEdge = true;
305 }
306 }
307
308 break;
309 }
310
311 travelleft += 2;
312
313 if (fixleftmargin == true)
314 {
315 travelleft--;
316 }
317
318 if (fixrightmargin == true)
319 {
320 travelleft--;
321 }
322
323 startlefti = enddowni;
324 startleftj = enddownj;
325 endleftj = startleftj - travelleft;
326 //qCDebug(DIGIKAM_DIMG_LOG) << "Moving Left Endleft = " << endleftj;
327
328 if (endleftj < 0)
329 {
330 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/transform/autocrop.cpp"
), 330, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "We have gone too left";
331 endleftj = 0;
332 counter++;
333 leftmargin = 0;
334 fixleftmargin = true;
335 travelleft--;
336 leftEdge = true;
337 }
338
339 i = startlefti;
340 j = startleftj;
341 (void)j; // Remove clang warning.
342
343 for (j = startleftj - 1 ; j >= endleftj ; --j)
344 {
345 //qCDebug(DIGIKAM_DIMG_LOG) << "At pixel "<< j << " , " << i;
346 c = QColor::fromRgb(threshold.pixel(j,i));
347
348 if (c == Qt::black)
349 {
350 // we have found an empty space
351
352 fixbottommargin = true;
353 bottommargin = i;
354 enddowni--;
355 traveldown--;
356 break;
357 }
358 }
359
360 endlefti = startlefti;
361
362 break;
363 }
364
365 case 3: //traveling up
366 {
367 if (fixleftmargin == true)
368 {
369 if (fixtopmargin == false)
370 {
371 endupi--;
372 endupj = leftmargin;
373
374 if (endupi < 0)
375 {
376 fixtopmargin = true;
377 topmargin = 0;
378 topEdge = true;
379 }
380 }
381
382 break;
383 }
384
385 travelup += 2;
386
387 if (fixbottommargin == true)
388 {
389 travelup--;
390 }
391
392 if (fixtopmargin == true)
393 {
394 travelup--;
395 }
396
397 startupi = endlefti;
398 startupj = endleftj;
399 endupi = startupi - travelup;
400 //qCDebug(DIGIKAM_DIMG_LOG) << "Moving Up Endup = " << endupi;
401
402 if (endupi < 0)
403 {
404 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/transform/autocrop.cpp"
), 404, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "We have gone too right";
405 endupi = 0;
406 topEdge = true;
407 counter++;
408 fixtopmargin = true;
409 topmargin = 0;
410 travelup--;
411 }
412
413 i = startupi;
414 (void)i; // Remove clang warning.
415 j = startupj;
416
417 for (i = startupi - 1 ; i >= endupi ; --i)
418 {
419 //qCDebug(DIGIKAM_DIMG_LOG) << "At pixel "<< j << " , " << i;
420 c = QColor::fromRgb(threshold.pixel(j, i));
421
422 if (c == Qt::black)
423 {
424 // we have found an empty space
425
426 fixleftmargin = true;
427 leftmargin = j;
428 endleftj++;
429 travelleft--;
430 break;
431 }
432 }
433
434 endupj = startupj;
435
436 break;
437 }
438 }
439
440 counter++;
441
442 if (
443 (fixbottommargin == true) &&
444 (fixtopmargin == true) &&
445 (fixleftmargin == true) &&
446 (fixrightmargin == true)
447 )
448 {
449 break;
450 }
451 }
452
453// qCDebug(DIGIKAM_DIMG_LOG) << "Count : " << count;
454 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/transform/autocrop.cpp"
), 454, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "Endupi : " << endupi;
455 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/transform/autocrop.cpp"
), 455, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "Endupj : " << endupj;
456 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/transform/autocrop.cpp"
), 456, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "Endrighti : " << endrighti;
457 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/transform/autocrop.cpp"
), 457, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "Endrightj : " << endrightj;
458 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/transform/autocrop.cpp"
), 458, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "Enddowni : " << enddowni;
459 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/transform/autocrop.cpp"
), 459, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "Enddownj : " << enddownj;
460 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/transform/autocrop.cpp"
), 460, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "Endlefti : " << endlefti;
461 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/transform/autocrop.cpp"
), 461, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "Endleftj : " << endleftj;
462 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/transform/autocrop.cpp"
), 462, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "Done" << Qt::endl;
463
464 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/transform/autocrop.cpp"
), 464, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "Left Margin : " << leftmargin;
465 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/transform/autocrop.cpp"
), 465, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "Right Margin : " << rightmargin;
466 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/transform/autocrop.cpp"
), 466, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "Top Margin : " << topmargin;
467 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/transform/autocrop.cpp"
), 467, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "Bottom Margin : " << bottommargin;
468 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/transform/autocrop.cpp"
), 468, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "Done" << Qt::endl;
469
470 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/transform/autocrop.cpp"
), 470, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "Left Edge : " << leftEdge;
471 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/transform/autocrop.cpp"
), 471, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "Right Edge : " << rightEdge;
472 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/transform/autocrop.cpp"
), 472, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "Top Edge : " << topEdge;
473 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/transform/autocrop.cpp"
), 473, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "Bottom Edge : " << bottomEdge;
474 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/transform/autocrop.cpp"
), 474, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "Done" << Qt::endl;
475
476 if (bottomEdge)
477 {
478 bottommargin++;
479 }
480
481 if (topEdge)
482 {
483 topmargin--;
484 }
485
486 if (leftEdge)
487 {
488 leftmargin--;
489 }
490
491 if (rightEdge)
492 {
493 rightmargin++;
494 }
495
496 //----------------------releasing images
497
498 QPoint icp1;
499 icp1.setX(leftmargin + 1);
500 icp1.setY(topCrop + topmargin + 1);
501 QPoint icp2;
502 icp2.setX(rightmargin - 1);
503 icp2.setY(topCrop + bottommargin - 1);
504 QRect cropArea;
505 cropArea.setTopLeft(icp1);
506 cropArea.setBottomRight(icp2);
507
508 return cropArea;
509}
510
511void AutoCrop::startAnalyse()
512{
513 QImage img = m_orgImage.copyQImage();
514 int breakflag = 0;
515 int topRow = -1;
516 int topColumn = -1;
517 int bottomRow = -1;
518 int bottomColumn = -1;
519 int leftRow = -1;
520 int leftColumn = -1;
521 int rightRow = -1;
522 int rightColumn = -1;
523 QColor c;
524 int i, j;
525
526 postProgress(5);
527
528 //---------------------- Finding the outer boundaries of the image (i.e. with black portions)
529
530 /**
531 * This would be done in 4 steps
532 * 1. Search column wise:
533 * (a) From the left to the right, this is to get the left boundary
534 * (b) From the right to the left, this is to get the right boundary
535 * 2. Search row wise :
536 * (a) From the top to the bottom, this is to get the top boundary
537 * (b) From the bottom to the top, this is to get the bottom boundary
538 */
539
540 // 1(a) Traversing the image from top to bottom, left to right, to get left boundary
541
542 breakflag = 0;
543 int width = img.width();
544 int height = img.height();
545
546 for (i = 0 ; i < width ; ++i)
1
Assuming 'i' is < 'width'
2
Loop condition is true. Entering loop body
6
Assuming 'i' is >= 'width'
7
Loop condition is false. Execution continues on line 572
547 {
548 for (j = 0 ; j < height ; ++j)
3
Assuming 'j' is >= 'height'
4
Loop condition is false. Execution continues on line 566
549 {
550 c = QColor::fromRgb(img.pixel(i, j));
551
552 if ((c == Qt::black) || !c.isValid())
553 {
554 // Nothing to do.
555 }
556 else
557 {
558 //we have found our pixel
559 leftRow = j;
560 leftColumn = i;
561 breakflag = 1;
562 break;
563 }
564 }
565
566 if (breakflag
4.1
'breakflag' is not equal to 1
== 1)
5
Taking false branch
567 {
568 break;
569 }
570 }
571
572 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/transform/autocrop.cpp"
), 572, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "Done Till step 1(a)";
8
Loop condition is false. Execution continues on line 573
573 postProgress(30);
574
575 //1(b) Traversing the image from top to bottom, right to left, to get right boundary
576
577 breakflag = 0;
578 (void)breakflag; // Remove clang warnings.
579
580 for (i = 0 ; i < width ; ++i)
9
Loop condition is true. Entering loop body
11
Loop condition is false. Execution continues on line 601
581 {
582 for (j = 0 ; j
9.1
'j' is >= 'height'
< height ; ++j)
10
Loop condition is false. Execution continues on line 580
583 {
584 c = QColor::fromRgb(img.pixel(i, j));
585
586 if ((c == Qt::black) || !c.isValid())
587 {
588 // Nothing to do.
589 }
590 else
591 {
592 // we have found our pixel
593
594 rightRow = j;
595 rightColumn = i;
596 break;
597 }
598 }
599 }
600
601 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/transform/autocrop.cpp"
), 601, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "Done Till step 1(b)";
12
Loop condition is false. Execution continues on line 602
602 postProgress(50);
603
604 // 2(a) Traversing the image left to right, top to down, to get top boundary
605
606 breakflag = 0;
607
608 for (i = 0 ; i
12.1
'i' is >= 'height'
< height ; ++i)
13
Loop condition is false. Execution continues on line 635
609 {
610 for (j = 0 ; j < width ; ++j)
611 {
612 c = QColor::fromRgb(img.pixel(j, i));
613
614 if ((c == Qt::black) || !c.isValid())
615 {
616 // Nothing to do.
617 }
618 else
619 {
620 // we have found our pixel
621
622 topRow = i;
623 topColumn = j;
624 breakflag = 1;
625 break;
626 }
627 }
628
629 if (breakflag == 1)
630 {
631 break;
632 }
633 }
634
635 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/transform/autocrop.cpp"
), 635, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "Done Till step 2(a)";
14
Loop condition is false. Execution continues on line 636
636 postProgress(70);
637
638 // 2(b) Traversing the image from left to right, bottom up, to get lower boundary
639
640 breakflag = 0;
641
642 for (i = height - 1 ; i >= 0 ; --i)
15
Assuming 'i' is < 0
16
Loop condition is false. Execution continues on line 669
643 {
644 for (j = 0 ; j < width ; ++j)
645 {
646 c = QColor::fromRgb(img.pixel(j,i));
647
648 if ((c == Qt::black) || !c.isValid())
649 {
650 // Nothing to do.
651 }
652 else
653 {
654 // we have found our pixel
655
656 bottomRow = i;
657 bottomColumn = j;
658 breakflag = 1;
659 break;
660 }
661 }
662
663 if (breakflag == 1)
664 {
665 break;
666 }
667 }
668
669 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/transform/autocrop.cpp"
), 669, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "Done Till step 2(b)";
17
Loop condition is false. Execution continues on line 670
670 postProgress(90);
671
672 //------making the required output--------------------
673
674 QString outercropParameters;
675 outercropParameters.append(QLatin1String("TopMost Pixel : ( "));
676 outercropParameters.append(QString::number(topRow));
677 outercropParameters.append(QLatin1String(", "));
678 outercropParameters.append(QString::number(topColumn));
679 outercropParameters.append(QLatin1String(")\nBottomMost Pixel : ( "));
680 outercropParameters.append(QString::number(bottomRow));
681 outercropParameters.append(QLatin1String(", "));
682 outercropParameters.append(QString::number(bottomColumn));
683 outercropParameters.append(QLatin1String(")\nLeftMost Pixel : ( "));
684 outercropParameters.append(QString::number(leftRow));
685 outercropParameters.append(QLatin1String(", "));
686 outercropParameters.append(QString::number(leftColumn));
687 outercropParameters.append(QLatin1String(")\nRightMost Pixel : ( "));
688 outercropParameters.append(QString::number(rightRow));
689 outercropParameters.append(QLatin1String(", "));
690 outercropParameters.append(QString::number(rightColumn));
691 outercropParameters.append(QLatin1String(")\nDONE"));
692 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/transform/autocrop.cpp"
), 692, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< outercropParameters;
18
Loop condition is false. Execution continues on line 693
693 postProgress(91);
694
695 QPoint p1;
696 p1.setX(leftColumn);
697 p1.setY(topRow);
698 QPoint p2;
699 p2.setX(rightColumn);
700 p2.setY(bottomRow);
701 QRect crop;
702 crop.setTopLeft(p1);
703 crop.setBottomRight(p2);
704
705 // crop Image to outerCrop
706
707 QImage result;
708 QSize resultsize = QSize(crop.width(), crop.height());
709 result = QImage(resultsize, QImage::Format_RGB888);
710 int ni, nj;
711
712 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/transform/autocrop.cpp"
), 712, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "Outer Crop area:";
19
Loop condition is false. Execution continues on line 713
713 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/transform/autocrop.cpp"
), 713, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "From "<< crop.top() << " to " << crop.bottom()
20
Loop condition is false. Execution continues on line 716
714 << " & " << crop.left() << " to " << crop.right();
715
716 for (i = crop.top(), ni = 0 ; i <= crop.bottom() ; ++i, ++ni)
21
Loop condition is true. Entering loop body
24
Loop condition is false. Execution continues on line 726
717 {
718 for (j = crop.left(), nj = 0 ; j <= crop.right() ; ++j, ++nj)
22
Loop condition is true. Entering loop body
23
Loop condition is false. Execution continues on line 716
719 {
720 result.setPixel(nj, ni, img.pixel(j, i));
721 }
722 }
723
724 //---------------------threshold the image
725
726 QImage threshold = QImage(resultsize,QImage::Format_RGB888);
727 int toggleflag1 = 0,toggleflag2 = 0;
728 int whitepixelCount = 0;
729
730 //-----initialize
731
732 for (i = 0 ; i < result.height() ; ++i)
25
Assuming the condition is false
26
Loop condition is false. Execution continues on line 742
733 {
734 for (j = 0 ; j < result.width() ; ++j)
735 {
736 threshold.setPixel(j, i, Qt::black);
737 }
738 }
739
740 //----------mark points on horizontal scan
741
742 for (i = 0 ; i < result.height() ; ++i)
27
Assuming the condition is false
28
Loop condition is false. Execution continues on line 780
743 {
744 toggleflag1 = -1;
745 toggleflag2 = -1;
746
747 for (j = 0 ; j < result.width() ; ++j)
748 {
749 c = QColor::fromRgb(result.pixel(j, i));
750
751 if (c != Qt::black)
752 {
753 toggleflag1 = j;
754 break;
755 }
756 }
757
758 for (j = (result.width()-1) ; j >= 0 ; --j)
759 {
760 c = QColor::fromRgb(result.pixel(j, i));
761
762 if (c != Qt::black)
763 {
764 toggleflag2 = j;
765 break;
766 }
767 }
768
769 if (toggleflag1 >= 0)
770 {
771 for (j = toggleflag1 ; j <= toggleflag2 ; ++j)
772 {
773 threshold.setPixel(j, i, qRgb(255, 255, 255));
774 }
775 }
776 }
777
778 //----------fill black points on vertical scan
779
780 for (j = 0 ; j < result.width() ; ++j)
29
Assuming the condition is false
30
Loop condition is false. Execution continues on line 826
781 {
782 toggleflag1 = -1;
783 toggleflag2 = -2;
784
785 for (i = 0 ; i < result.height() ; ++i)
786 {
787 c = QColor::fromRgb(result.pixel(j, i));
788
789 if (c != Qt::black)
790 {
791 toggleflag1 = i;
792 break;
793 }
794 }
795
796 for (i = (result.height()-1) ; i >= 0 ; --i)
797 {
798 c = QColor::fromRgb(result.pixel(j, i));
799
800 if (c != Qt::black)
801 {
802 toggleflag2 = i;
803 break;
804 }
805 }
806
807 if (toggleflag1 >= 0)
808 {
809 for (i = 0 ; i < toggleflag1 ; ++i)
810 {
811 threshold.setPixel(j, i, qRgb(0, 0, 0));
812 }
813 }
814
815 if (toggleflag2 >= 0)
816 {
817 for (i = (toggleflag2+1) ; i < (result.height()) ; ++i)
818 {
819 threshold.setPixel(j, i, qRgb(0, 0, 0));
820 }
821 }
822 }
823
824 // ---count of white pixel in threshold
825
826 for (i = 0 ; i < threshold.height() ; ++i)
31
Assuming the condition is true
32
Loop condition is true. Entering loop body
35
Assuming the condition is true
36
Loop condition is true. Entering loop body
39
Assuming the condition is false
40
Loop condition is false. Execution continues on line 839
827 {
828 for (j = 0 ; j < threshold.width() ; ++j)
33
Assuming the condition is false
34
Loop condition is false. Execution continues on line 826
37
Assuming the condition is false
38
Loop condition is false. Execution continues on line 826
829 {
830 c = QColor::fromRgb(threshold.pixel(j, i));
831
832 if (c == Qt::white)
833 {
834 whitepixelCount++;
835 }
836 }
837 }
838
839 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/transform/autocrop.cpp"
), 839, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "White pixel count in thresholded image = " << whitepixelCount;
41
Loop condition is false. Execution continues on line 840
840 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/transform/autocrop.cpp"
), 840, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "Thresholding Complete\n";
42
Loop condition is false. Execution continues on line 844
841
842 //---------------------inner crop
843
844 QRect InrCrop = spiralClockwiseTraversal(threshold,-1,-1);
845 QPoint icp1;
846 icp1.setX(InrCrop.topLeft().x() + leftColumn);
847 icp1.setY(InrCrop.topLeft().y() + topRow);
848 QPoint icp2;
849 icp2.setX(InrCrop.bottomRight().x() + leftColumn);
850 icp2.setY(InrCrop.bottomRight().y() + topRow);
851 QRect cropArea;
852 cropArea.setTopLeft(icp1);
853 cropArea.setBottomRight(icp2);
854
855 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/transform/autocrop.cpp"
), 855, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "cropArea : "<<cropArea;
43
Loop condition is false. Execution continues on line 862
856
857 // Step 1. check for extra small crop
858 // Step 2. Find out first minima from left and right, crop accordingly
859
860 //-----Step 1 -- Check for extra small crop
861
862 int area = cropArea.height() * cropArea.width();
863
864 if (area > (whitepixelCount / 1.43))
44
Assuming the condition is false
45
Taking false branch
865 {
866 d->cropArea.setTopLeft(icp1);
867 d->cropArea.setBottomRight(icp2);
868 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/transform/autocrop.cpp"
), 868, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "Inner Crop Area : " << d->cropArea;
869 return;
870 }
871 else
872 {
873 //threshold.save("ThresholdedImage.jpg",0,100);
874
875 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/transform/autocrop.cpp"
), 875, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "Area not adequate!";
46
Loop condition is false. Execution continues on line 876
876 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/transform/autocrop.cpp"
), 876, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "Extra Cropping Required";
47
Loop condition is false. Execution continues on line 880
877
878 // --- Step 2 -- Search between local minima
879
880 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/transform/autocrop.cpp"
), 880, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "In local minima function";
48
Loop condition is false. Execution continues on line 884
881
882 // We need to find the maxima between the first two local minima from either side
883
884 int* const blackpointCount = new int[threshold.width()]{};
49
Storing uninitialized value
885 int leftminima = 0;
886 int rightminima = (threshold.width()-1);
887 int topCropLine = 0;
888 int bottomCropLine = threshold.height()-1;
889 int temp;
890 int temppos;
891 int count;
892
893 (void) bottomCropLine; // Remove clang warnings.
894
895 // initialize black point count
896
897 for (i = 0 ; i < threshold.width() ; ++i)
50
Assuming the condition is true
51
Loop condition is true. Entering loop body
52
Assuming the condition is true
53
Loop condition is true. Entering loop body
54
Assuming the condition is false
55
Loop condition is false. Execution continues on line 902
898 {
899 blackpointCount[i] = 0;
900 }
901
902 for (j = 0 ; j < threshold.width() ; ++j)
56
Assuming the condition is false
57
Loop condition is false. Execution continues on line 923
903 {
904 count = 0;
905
906 for (i = 0 ; i < threshold.height(); ++i)
907 {
908 c = QColor::fromRgb(threshold.pixel(j, i));
909
910 if (c == Qt::black)
911 {
912 count++;
913 }
914 else
915 {
916 break;
917 }
918 }
919
920 blackpointCount[j] = count;
921 }
922
923 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/transform/autocrop.cpp"
), 923, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "Top black element count Data Entry Completed";
58
Loop condition is false. Execution continues on line 927
924
925 // --- Searching left minima
926
927 for (j = 1 ; j < threshold.width() ; ++j)
59
Assuming the condition is false
60
Loop condition is false. Execution continues on line 937
928 {
929 if ((blackpointCount[j] > blackpointCount[j-1]) &&
930 (blackpointCount[j] < (0.2*threshold.height())))
931 {
932 leftminima = j-1;
933 break;
934 }
935 }
936
937 for (j = (threshold.width()-2) ; j >= 0 ; --j)
61
Assuming 'j' is < 0
62
Loop condition is false. Execution continues on line 947
938 {
939 if ((blackpointCount[j] > blackpointCount[j+1]) &&
940 (blackpointCount[j] < (0.2*threshold.height())))
941 {
942 rightminima = j+1;
943 break;
944 }
945 }
946
947 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/transform/autocrop.cpp"
), 947, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "Top Part right minima : " << rightminima << " Left Minima : " << leftminima;
63
Loop condition is false. Execution continues on line 951
948
949 // --- find the maximum among these minima
950
951 temp = blackpointCount[leftminima];
952 temppos = leftminima;
953
954 for (j = leftminima+1 ; j <= rightminima ; ++j)
64
Assuming 'j' is <= 'rightminima'
65
Loop condition is true. Entering loop body
67
The value 2 is assigned to 'j'
68
Assuming 'j' is <= 'rightminima'
69
Loop condition is true. Entering loop body
955 {
956 if (temp < blackpointCount[j])
66
Taking false branch
70
The right operand of '<' is a garbage value
957 {
958 temp = blackpointCount[j];
959 temppos = j;
960 }
961 }
962
963 topCropLine = temp;
964 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/transform/autocrop.cpp"
), 964, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "Found top crop line";
965 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/transform/autocrop.cpp"
), 965, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "Found in column = " << temppos << "and the topCropLine is "<< topCropLine;
966 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/transform/autocrop.cpp"
), 966, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "Searching for bottom crop line";
967
968 //-----For the bottom of the image
969
970 // initialize black point count
971
972 for (i = 0 ; i < threshold.width() ; ++i)
973 {
974 blackpointCount[i] = 0;
975 }
976
977 for (j = 0 ; j < threshold.width() ; ++j)
978 {
979 count = 0;
980
981 for (i = (threshold.height()-1) ; i >= 0; --i)
982 {
983 c = QColor::fromRgb(result.pixel(j, i));
984
985 if (c == Qt::black)
986 {
987 count++;
988 }
989 else
990 {
991 break;
992 }
993 }
994
995 blackpointCount[j] = count;
996 }
997
998 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/transform/autocrop.cpp"
), 998, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "Bottom black element count Data Entry Completed";
999
1000 // --- Searching left minima
1001
1002 for (j = 1 ; j < threshold.width() ; ++j)
1003 {
1004 if ((blackpointCount[j] > blackpointCount[j-1]) &&
1005 (blackpointCount[j] < (0.2*threshold.height())))
1006 {
1007 leftminima = j-1;
1008 break;
1009 }
1010 }
1011
1012 for (j = (threshold.width()-2) ; j >= 0 ; --j)
1013 {
1014 if ((blackpointCount[j] > blackpointCount[j+1]) &&
1015 (blackpointCount[j] < (0.2*threshold.height())))
1016 {
1017 rightminima = j+1;
1018 break;
1019 }
1020 }
1021
1022 // --- find the maximum among these minima
1023
1024 temp = blackpointCount[leftminima];
1025 temppos = leftminima;
1026
1027 for (j = leftminima+1 ; j <= rightminima ; ++j)
1028 {
1029 if (temp < blackpointCount[j])
1030 {
1031 temp = blackpointCount[j];
1032 temppos = j;
1033 }
1034 }
1035
1036 bottomCropLine = temp;
1037 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/transform/autocrop.cpp"
), 1037, static_cast<const char *>(__PRETTY_FUNCTION__)
, qt_category.name()).debug()
<< "Found top crop line";
1038 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/transform/autocrop.cpp"
), 1038, static_cast<const char *>(__PRETTY_FUNCTION__)
, qt_category.name()).debug()
<< "Found in column = " << temppos;
1039 QRect newCrop = spiralClockwiseTraversal(threshold, topCropLine, (threshold.height()-bottomCropLine));
1040
1041 if (newCrop != crop)
1042 {
1043 icp1.setX(newCrop.topLeft().x() + leftColumn);
1044 icp1.setY(newCrop.topLeft().y() + topRow);
1045 icp2.setX(newCrop.bottomRight().x() + leftColumn);
1046 icp2.setY(newCrop.bottomRight().y() + topRow);
1047 d->cropArea.setTopLeft(icp1);
1048 d->cropArea.setBottomRight(icp2);
1049 }
1050
1051 delete [] blackpointCount;
1052 }
1053
1054 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/transform/autocrop.cpp"
), 1054, static_cast<const char *>(__PRETTY_FUNCTION__)
, qt_category.name()).debug()
<< "Inner Crop Area : " << cropArea;
1055/*
1056 return(cropArea);
1057 resultsize = QSize (cropArea.width(), cropArea.height());
1058 QImage ic = QImage(resultsize,img.format());
1059
1060 for (i = cropArea.top(), ni = 0 ; i <= cropArea.bottom() ; i++, ni++ )
1061 {
1062 for (j = cropArea.left(), nj = 0 ; j <= cropArea.right() ; j++, nj++ )
1063 {
1064 ic.setPixel(nj, ni, img.pixel(j, i));
1065 }
1066 }
1067
1068 qCDebug(DIGIKAM_DIMG_LOG) << "From "<<cropArea.top()<<" to "<<cropArea.bottom()<<" & "<<cropArea.left()<<" to "<<cropArea.right();
1069
1070 if (ic.save("InnerCrop.jpg",0,100))
1071 {
1072 qCDebug(DIGIKAM_DIMG_LOG) << "Inner Crop Function Saves the day!";
1073 }
1074 else
1075 {
1076 qCDebug(DIGIKAM_DIMG_LOG) << "Inner Crop Functions fails";
1077 }
1078*/
1079 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/transform/autocrop.cpp"
), 1079, static_cast<const char *>(__PRETTY_FUNCTION__)
, qt_category.name()).debug()
<< "Inner Crop Area : " << d->cropArea;
1080}
1081
1082QRect AutoCrop::autoInnerCrop() const
1083{
1084 return d->cropArea;
1085}
1086
1087} // namespace Digikam
1088
1089#include "moc_autocrop.cpp"