Bug Summary

File:dplugins/dimg/jpeg2000/dimgjpeg2000loader_load.cpp
Warning:line 113, column 17
Opened stream never closed. Potential resource leak

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 dimgjpeg2000loader_load.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/home/gilles/devel/8.x/build.scan/core/dplugins/dimg/jpeg2000 -fcoverage-compilation-dir=/home/gilles/devel/8.x/build.scan/core/dplugins/dimg/jpeg2000 -resource-dir /usr/lib/llvm-19/lib/clang/19 -isystem /opt/qt6/include -isystem /opt/qt6/include/QtCore -isystem /opt/qt6/mkspecs/linux-g++ -isystem /opt/qt6/include/QtGui -isystem /opt/qt6/include/QtWidgets -isystem /opt/qt6/include/KF6/KConfig -isystem /opt/qt6/include/KF6/KConfigCore -isystem /opt/qt6/include/KF6/KI18n -isystem /opt/qt6/include/QtXml -D CMS_NO_REGISTER_KEYWORD=1 -D DImg_JPEG2000_Plugin_EXPORTS -D HAVE_FFMPEG_VERSION5 -D LIBPGF_DISABLE_OPENMP -D MAGICKCORE_HDRI_ENABLE=0 -D MAGICKCORE_QUANTUM_DEPTH=16 -D QT_CORE_LIB -D QT_DEPRECATED_WARNINGS -D QT_DEPRECATED_WARNINGS_SINCE=0x060000 -D QT_DISABLE_DEPRECATED_BEFORE=0x050E00 -D QT_GUI_LIB -D QT_NO_CAST_FROM_ASCII -D QT_NO_CAST_FROM_BYTEARRAY -D QT_NO_CAST_TO_ASCII -D QT_NO_FOREACH -D QT_NO_KEYWORDS -D QT_NO_NARROWING_CONVERSIONS_IN_CONNECT -D QT_NO_URL_CAST_FROM_STRING -D QT_STRICT_ITERATORS -D QT_USE_QSTRINGBUILDER -D QT_WIDGETS_LIB -D QT_XML_LIB -D TRANSLATION_DOMAIN="digikam" -D USE_JASPER -D USE_JPEG -D USE_JPEG8 -D _GNU_SOURCE -D _LARGEFILE64_SOURCE -I /home/gilles/devel/8.x/build.scan/core/dplugins/dimg/jpeg2000 -I /home/gilles/devel/8.x/core/dplugins/dimg/jpeg2000 -I /home/gilles/devel/8.x/build.scan/core/dplugins/dimg/jpeg2000/DImg_JPEG2000_Plugin_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 -I /home/gilles/devel/8.x/core/libs/dimg/filters/auto -I /home/gilles/devel/8.x/core/libs/dimg/filters/bcg -I /home/gilles/devel/8.x/core/libs/dimg/filters/bw -I /home/gilles/devel/8.x/core/libs/dimg/filters/cb -I /home/gilles/devel/8.x/core/libs/dimg/filters/curves -I /home/gilles/devel/8.x/core/libs/dimg/filters/decorate -I /home/gilles/devel/8.x/core/libs/dimg/filters -I /home/gilles/devel/8.x/core/libs/dimg/filters/film -I /home/gilles/devel/8.x/core/libs/dimg/filters/fx -I /home/gilles/devel/8.x/core/libs/dimg/filters/greycstoration/cimg -I /home/gilles/devel/8.x/core/libs/dimg/filters/greycstoration -I /home/gilles/devel/8.x/core/libs/dimg/filters/hotpixels -I /home/gilles/devel/8.x/core/libs/dimg/filters/hsl -I /home/gilles/devel/8.x/core/libs/dimg/filters/icc -I /home/gilles/devel/8.x/core/libs/dimg/filters/lc -I /home/gilles/devel/8.x/core/libs/dimg/filters/lens -I /home/gilles/devel/8.x/core/libs/dimg/filters/levels -I /home/gilles/devel/8.x/core/libs/dimg/filters/nr -I /home/gilles/devel/8.x/core/libs/dimg/filters/raw -I /home/gilles/devel/8.x/core/libs/dimg/filters/redeye -I /home/gilles/devel/8.x/core/libs/dimg/filters/sharp -I /home/gilles/devel/8.x/core/libs/dimg/filters/transform -I /home/gilles/devel/8.x/core/libs/dimg/filters/wb -I /home/gilles/devel/8.x/core/libs/dimg/history -I /home/gilles/devel/8.x/core/libs/dimg/loaders -I /home/gilles/devel/8.x/core/libs/dngwriter -I /home/gilles/devel/8.x/core/libs/dnnmodelmanager -I /home/gilles/devel/8.x/core/libs/dplugins/core -I /home/gilles/devel/8.x/core/libs/dplugins/iface -I /home/gilles/devel/8.x/core/libs/dplugins/setup -I /home/gilles/devel/8.x/core/libs/dplugins/webservices -I /home/gilles/devel/8.x/core/libs/dplugins/widgets -I /home/gilles/devel/8.x/core/libs/dragdrop -I /home/gilles/devel/8.x/core/libs/dtrash -I /home/gilles/devel/8.x/core/libs/facesengine/common -I /home/gilles/devel/8.x/core/libs/facesengine/detection -I /home/gilles/devel/8.x/core/libs/facesengine/detection/opencv-dnn -I /home/gilles/devel/8.x/core/libs/facesengine/facedb -I /home/gilles/devel/8.x/core/libs/facesengine/recognition -I /home/gilles/devel/8.x/core/libs/facesengine/recognition/opencv-dnn -I /home/gilles/devel/8.x/core/libs/fileactionmanager -I /home/gilles/devel/8.x/core/libs/filters -I /home/gilles/devel/8.x/core/libs/imgqsort/detectors -I /home/gilles/devel/8.x/core/libs/imgqsort -I /home/gilles/devel/8.x/core/libs/iojobs -I /home/gilles/devel/8.x/core/libs/jpegutils -I /home/gilles/devel/8.x/core/libs/metadataengine/containers -I /home/gilles/devel/8.x/core/libs/metadataengine/dmetadata -I /home/gilles/devel/8.x/core/libs/metadataengine/engine -I /home/gilles/devel/8.x/core/libs/metadataengine/exiftool -I /home/gilles/devel/8.x/core/libs/metadataengine/focuspoint -I /home/gilles/devel/8.x/core/libs/mlfoundation -I /home/gilles/devel/8.x/core/libs/models -I /home/gilles/devel/8.x/core/libs/networkmanager -I /home/gilles/devel/8.x/core/libs/notificationmanager -I /home/gilles/devel/8.x/core/libs/onlineversion -I /home/gilles/devel/8.x/core/libs/pgfutils -I /home/gilles/devel/8.x/core/libs/progressmanager -I /home/gilles/devel/8.x/core/libs/properties/captions -I /home/gilles/devel/8.x/core/libs/properties/geolocation -I /home/gilles/devel/8.x/core/libs/properties/history -I /home/gilles/devel/8.x/core/libs/properties/import -I /home/gilles/devel/8.x/core/libs/properties -I /home/gilles/devel/8.x/core/libs/qtopencvimg -I /home/gilles/devel/8.x/core/libs/rawengine -I /home/gilles/devel/8.x/core/libs/settings -I /home/gilles/devel/8.x/core/libs/tags/autoassignment -I /home/gilles/devel/8.x/core/libs/tags/autoassignment/classifiers -I /home/gilles/devel/8.x/core/libs/tags/autoassignment/classifiers/multiclassyolo -I /home/gilles/devel/8.x/core/libs/tags/autoassignment/classifiers/softmax -I /home/gilles/devel/8.x/core/libs/tags/autoassignment/model -I /home/gilles/devel/8.x/core/libs/tags/autoassignment/pipelines -I /home/gilles/devel/8.x/core/libs/tags/autoassignment/pipelines/object -I /home/gilles/devel/8.x/core/libs/tags/engine -I /home/gilles/devel/8.x/core/libs/tags/manager/models -I /home/gilles/devel/8.x/core/libs/tags/manager -I /home/gilles/devel/8.x/core/libs/tags/widgets -I /home/gilles/devel/8.x/core/libs/template -I /home/gilles/devel/8.x/core/libs/threadimageio/engine -I /home/gilles/devel/8.x/core/libs/threadimageio/fileio -I /home/gilles/devel/8.x/core/libs/threadimageio/preview -I /home/gilles/devel/8.x/core/libs/threadimageio/thumb -I /home/gilles/devel/8.x/core/libs/threadimageio/video -I /home/gilles/devel/8.x/core/libs/threads -I /home/gilles/devel/8.x/core/libs/timeadjust -I /home/gilles/devel/8.x/core/libs/transitionmngr -I /home/gilles/devel/8.x/core/libs/versionmanager -I /home/gilles/devel/8.x/core/libs/video -I /home/gilles/devel/8.x/core/libs/video/manager -I /home/gilles/devel/8.x/core/libs/video/osd -I /home/gilles/devel/8.x/core/libs/video/player -I /home/gilles/devel/8.x/core/libs/widgets/colors -I /home/gilles/devel/8.x/core/libs/widgets/combo -I /home/gilles/devel/8.x/core/libs/widgets/files -I /home/gilles/devel/8.x/core/libs/widgets/fonts -I /home/gilles/devel/8.x/core/libs/widgets/graphicsview -I /home/gilles/devel/8.x/core/libs/widgets/history -I /home/gilles/devel/8.x/core/libs/widgets/iccprofiles -I /home/gilles/devel/8.x/core/libs/widgets/itemview -I /home/gilles/devel/8.x/core/libs/widgets/layout -I /home/gilles/devel/8.x/core/libs/widgets/mainview -I /home/gilles/devel/8.x/core/libs/widgets/metadata/config -I /home/gilles/devel/8.x/core/libs/widgets/metadata/exiftool -I /home/gilles/devel/8.x/core/libs/widgets/metadata/exiv2 -I /home/gilles/devel/8.x/core/libs/widgets/metadata/labels -I /home/gilles/devel/8.x/core/libs/widgets/metadata/utils -I /home/gilles/devel/8.x/core/libs/widgets/range -I /home/gilles/devel/8.x/core/libs/widgets/text -I /home/gilles/devel/8.x/core/libs/jpegutils/libjpeg/84 -I /home/gilles/devel/8.x/core/app/utils -I /home/gilles/devel/8.x/build.scan/core/app/utils -I /home/gilles/devel/8.x/core/utilities/advancedrename -I /home/gilles/devel/8.x/core/utilities/advancedrename/common -I /home/gilles/devel/8.x/core/utilities/advancedrename/parser -I /home/gilles/devel/8.x/core/utilities/advancedrename/parser/modifiers -I /home/gilles/devel/8.x/core/utilities/advancedrename/parser/options -I /home/gilles/devel/8.x/core/utilities/advancedrename/parser/options/database -I /home/gilles/devel/8.x/core/utilities/advancedrename/parser/options/database/keys -I /home/gilles/devel/8.x/core/utilities/extrasupport/addressbook -I /home/gilles/devel/8.x/core/utilities/extrasupport/filesindexer -I /home/gilles/devel/8.x/core/utilities/facemanagement/bench -I /home/gilles/devel/8.x/core/utilities/facemanagement/database -I /home/gilles/devel/8.x/core/utilities/facemanagement/dialogs -I /home/gilles/devel/8.x/core/utilities/facemanagement/items -I /home/gilles/devel/8.x/core/utilities/facemanagement/pipelines/detectrecognize -I /home/gilles/devel/8.x/core/utilities/facemanagement/pipelines/edit -I /home/gilles/devel/8.x/core/utilities/facemanagement/pipelines -I /home/gilles/devel/8.x/core/utilities/facemanagement/pipelines/recognize -I /home/gilles/devel/8.x/core/utilities/facemanagement/pipelines/reset -I /home/gilles/devel/8.x/core/utilities/facemanagement/pipelines/retrain -I /home/gilles/devel/8.x/core/utilities/facemanagement/widgets -I /home/gilles/devel/8.x/core/utilities/firstrun -I /home/gilles/devel/8.x/core/utilities/focuspointmanagement -I /home/gilles/devel/8.x/core/utilities/fuzzysearch -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/astro -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/blendings -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/core -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/geodata/data -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/geodata/graphicsitem -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/geodata/handlers/dgml -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/geodata/handlers/kml -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/geodata/parser -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/geodata/scene -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/geodata/writer -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/geodata/writers/dgml -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/geodata/writers/kml -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/graphicsview -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/layers -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/models -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/osm -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/plugins -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/plugins/render/atmosphere -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/plugins/render/compass -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/plugins/render/crosshairs -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/plugins/render/graticule -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/plugins/render/mapscale -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/plugins/render/measure -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/plugins/render/navigation -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/plugins/render/overviewmap -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/plugins/render/progress -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/plugins/runner/cache -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/plugins/runner/gpsbabel -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/plugins/runner/gpx -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/plugins/runner/gpx/handlers -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/plugins/runner/json -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/plugins/runner/kml -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/plugins/runner/nominatim-reversegeocoding -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/plugins/runner/osm -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/plugins/runner/osm/o5mreader -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/plugins/runner/osm/translators -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/plugins/runner/osm/writers -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/plugins/runner/pn2 -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/plugins/runner/pnt -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/projections -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/runners -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/settings -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/storage -I /home/gilles/devel/8.x/core/utilities/geolocation/engine/tile -I /home/gilles/devel/8.x/core/utilities/geolocation/geoiface/backends -I /home/gilles/devel/8.x/core/utilities/geolocation/geoiface/bookmark -I /home/gilles/devel/8.x/core/utilities/geolocation/geoiface/core -I /home/gilles/devel/8.x/core/utilities/geolocation/geoiface/correlator -I /home/gilles/devel/8.x/core/utilities/geolocation/geoiface/dragdrop -I /home/gilles/devel/8.x/core/utilities/geolocation/geoiface/items -I /home/gilles/devel/8.x/core/utilities/geolocation/geoiface/lookup -I /home/gilles/devel/8.x/core/utilities/geolocation/geoiface/reversegeocoding -I /home/gilles/devel/8.x/core/utilities/geolocation/geoiface/tiles -I /home/gilles/devel/8.x/core/utilities/geolocation/geoiface/tracks -I /home/gilles/devel/8.x/core/utilities/geolocation/geoiface/widgets -I /home/gilles/devel/8.x/core/utilities/geolocation/geomapwrapper -I /home/gilles/devel/8.x/core/utilities/geolocation/mapsearches -I /home/gilles/devel/8.x/core/utilities/imageeditor/core -I /home/gilles/devel/8.x/core/utilities/imageeditor/dialogs -I /home/gilles/devel/8.x/core/utilities/imageeditor/editor -I /home/gilles/devel/8.x/core/utilities/imageeditor/main -I /home/gilles/devel/8.x/core/utilities/imageeditor/widgets -I /home/gilles/devel/8.x/core/utilities/import/backend -I /home/gilles/devel/8.x/core/utilities/import/dialogs -I /home/gilles/devel/8.x/core/utilities/import/items -I /home/gilles/devel/8.x/core/utilities/import/main -I /home/gilles/devel/8.x/core/utilities/import/models -I /home/gilles/devel/8.x/core/utilities/import/views -I /home/gilles/devel/8.x/core/utilities/import/widgets -I /home/gilles/devel/8.x/core/utilities/lighttable -I /home/gilles/devel/8.x/core/utilities/maintenance/main -I /home/gilles/devel/8.x/core/utilities/maintenance/manager -I /home/gilles/devel/8.x/core/utilities/maintenance/tools/dbcleaner -I /home/gilles/devel/8.x/core/utilities/maintenance/tools/dbscan -I /home/gilles/devel/8.x/core/utilities/maintenance/tools/duplicates -I /home/gilles/devel/8.x/core/utilities/maintenance/tools/facesmanagement -I /home/gilles/devel/8.x/core/utilities/maintenance/tools/fingerprints -I /home/gilles/devel/8.x/core/utilities/maintenance/tools/imgqsort -I /home/gilles/devel/8.x/core/utilities/maintenance/tools/metaremover -I /home/gilles/devel/8.x/core/utilities/maintenance/tools/metasync -I /home/gilles/devel/8.x/core/utilities/maintenance/tools/thumbs -I /home/gilles/devel/8.x/core/utilities/maintenance/utils -I /home/gilles/devel/8.x/core/utilities/queuemanager/dplugins -I /home/gilles/devel/8.x/core/utilities/queuemanager/main -I /home/gilles/devel/8.x/core/utilities/queuemanager/manager -I /home/gilles/devel/8.x/core/utilities/queuemanager/views -I /home/gilles/devel/8.x/core/utilities/searchwindow -I /home/gilles/devel/8.x/core/utilities/setup/album -I /home/gilles/devel/8.x/core/utilities/setup/camera -I /home/gilles/devel/8.x/core/utilities/setup/collections -I /home/gilles/devel/8.x/core/utilities/setup/downloader -I /home/gilles/devel/8.x/core/utilities/setup/editor -I /home/gilles/devel/8.x/core/utilities/setup/metadata -I /home/gilles/devel/8.x/core/utilities/setup/misc -I /home/gilles/devel/8.x/core/utilities/setup -I /home/gilles/devel/8.x/build.scan/core/app -I /home/gilles/devel/8.x/core/app -I /opt/qt6/include/opencv4 -I /usr/include/ImageMagick-6 -I /usr/include/x86_64-linux-gnu/ImageMagick-6 -I /opt/qt6/include/QtMultimedia -I /opt/qt6/include/QtNetwork -I /opt/qt6/include/QtMultimediaWidgets -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/x86_64-linux-gnu/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/backward -internal-isystem /usr/lib/llvm-19/lib/clang/19/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-long-long -Wno-deprecated-copy -std=c++20 -fdeprecated-macro -ferror-limit 19 -fvisibility=hidden -fvisibility-inlines-hidden -fno-operator-names -fopenmp -fgnuc-version=4.2.1 -fno-implicit-modules -fskip-odr-check-in-gmf -fcxx-exceptions -fexceptions -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/gilles/devel/8.x/project/reports/report.scan/2025-01-21-132859-99447-1 -x c++ /home/gilles/devel/8.x/core/dplugins/dimg/jpeg2000/dimgjpeg2000loader_load.cpp
1/* ============================================================
2 *
3 * This file is a part of digiKam project
4 * https://www.digikam.org
5 *
6 * Date : 2006-06-14
7 * Description : A JPEG-2000 IO file for DImg framework- load operations
8 *
9 * SPDX-FileCopyrightText: 2006-2025 by Gilles Caulier <caulier dot gilles at gmail dot com>
10 *
11 * SPDX-License-Identifier: GPL-2.0-or-later
12 *
13 * ============================================================ */
14
15#include "dimgjpeg2000loader_p.h"
16
17namespace DigikamJPEG2000DImgPlugin
18{
19
20bool DImgJPEG2000Loader::load(const QString& filePath, DImgLoaderObserver* const observer)
21{
22 readMetadata(filePath);
23
24#ifdef Q_OS_WIN
25
26 FILE* const file = _wfopen((const wchar_t*)filePath.utf16(), L"rb");
27
28#else
29
30 FILE* const file = fopen(filePath.toUtf8().constData(), "rb");
1
Stream opened here
2
Assuming that 'fopen' is successful
31
32#endif
33
34 if (!file
2.1
'file' is non-null
)
3
Taking false branch
35 {
36 qCWarning(DIGIKAM_DIMG_LOG_JP2K)for (QLoggingCategoryMacroHolder<QtWarningMsg> qt_category
((DIGIKAM_DIMG_LOG_JP2K)()); qt_category; qt_category.control
= false) QMessageLogger(static_cast<const char *>("/home/gilles/devel/8.x/core/dplugins/dimg/jpeg2000/dimgjpeg2000loader_load.cpp"
), 36, static_cast<const char *>(__PRETTY_FUNCTION__), qt_category
.name()).warning()
<< "Unable to open JPEG2000 file";
37 loadingFailed();
38
39 return false;
40 }
41
42 imageSetAttribute(QLatin1String("format"), QLatin1String("JP2"));
43
44#if defined JAS_VERSION_MAJOR4 && JAS_VERSION_MAJOR4 >= 3
45
46 // NOTE: nothing to do.
47
48#else
49
50 QScopedPointer<DMetadata> metadata(new DMetadata(filePath));
51 QSize size = metadata->getItemDimensions();
52 QString decoderOptions = QLatin1String("max_samples=100000000");
53
54 if (size.isValid())
55 {
56 imageWidth() = size.width();
57 imageHeight() = size.height();
58 decoderOptions = QString::fromLatin1("max_samples=%1").arg(size.width() * size.height() * 4);
59 qCDebug(DIGIKAM_DIMG_LOG_JP2K)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category
((DIGIKAM_DIMG_LOG_JP2K)()); qt_category; qt_category.control
= false) QMessageLogger(static_cast<const char *>("/home/gilles/devel/8.x/core/dplugins/dimg/jpeg2000/dimgjpeg2000loader_load.cpp"
), 59, static_cast<const char *>(__PRETTY_FUNCTION__), qt_category
.name()).debug()
<< "JP2 image size:" << size;
60 }
61
62 if (!(m_loadFlags & LoadImageData) && !(m_loadFlags & LoadICCData))
63 {
64 // libjasper will load the full image in memory already when calling jas_image_decode.
65 // This is bad when scanning. See bugs 215458 and 195583.
66 // Exiv2 is used to extract this info.
67
68 fclose(file);
69
70 return true;
71 }
72
73#endif
74
75 // -------------------------------------------------------------------
76 // Initialize JPEG 2000 API.
77
78 long i = 0;
79 long x = 0;
80 long y = 0;
81 int components[4] = { 0 };
82 unsigned int maximum_component_depth = 0;
83 unsigned int scale[4] = { 0 };
84 unsigned int x_step[4] = { 0 };
85 unsigned int y_step[4] = { 0 };
86 unsigned long number_components = 0;
87 jas_image_t* jp2_image = nullptr;
88 jas_stream_t* jp2_stream = nullptr;
89 jas_matrix_t* pixels[4] = { nullptr };
90
91 if (initJasper() != 0)
4
Assuming the condition is false
5
Taking false branch
92 {
93 qCWarning(DIGIKAM_DIMG_LOG_JP2K)for (QLoggingCategoryMacroHolder<QtWarningMsg> qt_category
((DIGIKAM_DIMG_LOG_JP2K)()); qt_category; qt_category.control
= false) QMessageLogger(static_cast<const char *>("/home/gilles/devel/8.x/core/dplugins/dimg/jpeg2000/dimgjpeg2000loader_load.cpp"
), 93, static_cast<const char *>(__PRETTY_FUNCTION__), qt_category
.name()).warning()
<< "Unable to init JPEG2000 decoder";
94 loadingFailed();
95 fclose(file);
96
97 return false;
98 }
99
100 jp2_stream = jas_stream_freopen(filePath.toUtf8().constData(), "rb", file);
101
102 if (jp2_stream == nullptr)
6
Assuming the condition is false
7
Taking false branch
103 {
104 qCWarning(DIGIKAM_DIMG_LOG_JP2K)for (QLoggingCategoryMacroHolder<QtWarningMsg> qt_category
((DIGIKAM_DIMG_LOG_JP2K)()); qt_category; qt_category.control
= false) QMessageLogger(static_cast<const char *>("/home/gilles/devel/8.x/core/dplugins/dimg/jpeg2000/dimgjpeg2000loader_load.cpp"
), 104, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).warning()
<< "Unable to open JPEG2000 stream";
105 fclose(file);
106
107 cleanupJasper();
108 loadingFailed();
109
110 return false;
111 }
112
113 int fmt = jas_image_strtofmt(QByteArray("jp2").data());
8
Opened stream never closed. Potential resource leak
114
115#if defined JAS_VERSION_MAJOR4 && JAS_VERSION_MAJOR4 >= 3
116
117 jp2_image = jas_image_decode(jp2_stream, fmt, nullptr);
118
119#else
120
121 // See bug 447240 and UPSTREAM https://github.com/jasper-software/jasper/issues/315#issuecomment-1007872809
122
123 qCDebug(DIGIKAM_DIMG_LOG_JP2K)for (QLoggingCategoryMacroHolder<QtDebugMsg> qt_category
((DIGIKAM_DIMG_LOG_JP2K)()); qt_category; qt_category.control
= false) QMessageLogger(static_cast<const char *>("/home/gilles/devel/8.x/core/dplugins/dimg/jpeg2000/dimgjpeg2000loader_load.cpp"
), 123, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).debug()
<< "jas_image_decode decoder options string:" << decoderOptions;
124
125 jp2_image = jas_image_decode(jp2_stream, fmt, decoderOptions.toLatin1().data());
126
127#endif
128
129 if (jp2_image == nullptr)
130 {
131 qCWarning(DIGIKAM_DIMG_LOG_JP2K)for (QLoggingCategoryMacroHolder<QtWarningMsg> qt_category
((DIGIKAM_DIMG_LOG_JP2K)()); qt_category; qt_category.control
= false) QMessageLogger(static_cast<const char *>("/home/gilles/devel/8.x/core/dplugins/dimg/jpeg2000/dimgjpeg2000loader_load.cpp"
), 131, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).warning()
<< "Unable to decode JPEG2000 image";
132 jas_stream_close(jp2_stream);
133
134 cleanupJasper();
135 loadingFailed();
136
137 return false;
138 }
139
140 jas_stream_close(jp2_stream);
141
142 // some pseudo-progress
143
144 if (observer)
145 {
146 observer->progressInfo(0.1F);
147 }
148
149 // -------------------------------------------------------------------
150 // Check color space.
151
152 int colorModel = DImg::COLORMODELUNKNOWN;
153
154 switch (jas_clrspc_fam(jas_image_clrspc(jp2_image))((((jp2_image)->clrspc_)) >> 8))
155 {
156 case JAS_CLRSPC_FAM_RGB4:
157 {
158 components[0] = jas_image_getcmptbytype(jp2_image, JAS_IMAGE_CT_RGB_R0);
159 components[1] = jas_image_getcmptbytype(jp2_image, JAS_IMAGE_CT_RGB_G1);
160 components[2] = jas_image_getcmptbytype(jp2_image, JAS_IMAGE_CT_RGB_B2);
161
162 if ((components[0] < 0) || (components[1] < 0) || (components[2] < 0))
163 {
164 qCWarning(DIGIKAM_DIMG_LOG_JP2K)for (QLoggingCategoryMacroHolder<QtWarningMsg> qt_category
((DIGIKAM_DIMG_LOG_JP2K)()); qt_category; qt_category.control
= false) QMessageLogger(static_cast<const char *>("/home/gilles/devel/8.x/core/dplugins/dimg/jpeg2000/dimgjpeg2000loader_load.cpp"
), 164, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).warning()
<< "Error parsing JPEG2000 image : Missing Image Channel";
165 jas_image_destroy(jp2_image);
166
167 cleanupJasper();
168 loadingFailed();
169
170 return false;
171 }
172
173 number_components = 3;
174 components[3] = jas_image_getcmptbytype(jp2_image, 3);
175
176 if (components[3] > 0)
177 {
178 m_hasAlpha = true;
179 ++number_components;
180 }
181
182 colorModel = DImg::RGB;
183
184 break;
185 }
186
187 case JAS_CLRSPC_FAM_GRAY3:
188 {
189 components[0] = jas_image_getcmptbytype(jp2_image, JAS_IMAGE_CT_GRAY_Y0);
190
191 // cppcheck-suppress knownConditionTrueFalse
192 if (components[0] < 0)
193 {
194 qCWarning(DIGIKAM_DIMG_LOG_JP2K)for (QLoggingCategoryMacroHolder<QtWarningMsg> qt_category
((DIGIKAM_DIMG_LOG_JP2K)()); qt_category; qt_category.control
= false) QMessageLogger(static_cast<const char *>("/home/gilles/devel/8.x/core/dplugins/dimg/jpeg2000/dimgjpeg2000loader_load.cpp"
), 194, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).warning()
<< "Error parsing JP2000 image : Missing Image Channel";
195 jas_image_destroy(jp2_image);
196
197 cleanupJasper();
198 loadingFailed();
199
200 return false;
201 }
202
203 number_components = 1;
204 colorModel = DImg::GRAYSCALE;
205
206 break;
207 }
208
209 case JAS_CLRSPC_FAM_YCBCR5:
210 {
211 components[0] = jas_image_getcmptbytype(jp2_image, JAS_IMAGE_CT_YCBCR_Y0);
212 components[1] = jas_image_getcmptbytype(jp2_image, JAS_IMAGE_CT_YCBCR_CB1);
213 components[2] = jas_image_getcmptbytype(jp2_image, JAS_IMAGE_CT_YCBCR_CR2);
214
215 // cppcheck-suppress knownConditionTrueFalse
216 if ((components[0] < 0) || (components[1] < 0) || (components[2] < 0))
217 {
218 qCWarning(DIGIKAM_DIMG_LOG_JP2K)for (QLoggingCategoryMacroHolder<QtWarningMsg> qt_category
((DIGIKAM_DIMG_LOG_JP2K)()); qt_category; qt_category.control
= false) QMessageLogger(static_cast<const char *>("/home/gilles/devel/8.x/core/dplugins/dimg/jpeg2000/dimgjpeg2000loader_load.cpp"
), 218, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).warning()
<< "Error parsing JP2000 image : Missing Image Channel";
219 jas_image_destroy(jp2_image);
220
221 cleanupJasper();
222 loadingFailed();
223
224 return false;
225 }
226
227 number_components = 3;
228 components[3] = jas_image_getcmptbytype(jp2_image, JAS_IMAGE_CT_UNKNOWN0x10000);
229
230 if (components[3] > 0)
231 {
232 m_hasAlpha = true;
233 ++number_components;
234 }
235
236 // FIXME: image->colorspace = YCbCrColorspace;
237
238 colorModel = DImg::YCBCR;
239
240 break;
241 }
242
243 default:
244 {
245 qCWarning(DIGIKAM_DIMG_LOG_JP2K)for (QLoggingCategoryMacroHolder<QtWarningMsg> qt_category
((DIGIKAM_DIMG_LOG_JP2K)()); qt_category; qt_category.control
= false) QMessageLogger(static_cast<const char *>("/home/gilles/devel/8.x/core/dplugins/dimg/jpeg2000/dimgjpeg2000loader_load.cpp"
), 245, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).warning()
<< "Error parsing JP2000 image : Colorspace Model Is Not Supported";
246 jas_image_destroy(jp2_image);
247
248 cleanupJasper();
249 loadingFailed();
250
251 return false;
252 }
253 }
254
255 // -------------------------------------------------------------------
256 // Check image geometry.
257
258 imageWidth() = jas_image_width(jp2_image)((jp2_image)->brx_ - (jp2_image)->tlx_);
259 imageHeight() = jas_image_height(jp2_image)((jp2_image)->bry_ - (jp2_image)->tly_);
260
261 for (i = 0 ; i < (long)number_components ; ++i)
262 {
263 if (
264 (
265 ((jas_image_cmptwidth(jp2_image, components[i])((jp2_image)->cmpts_[components[i]]->width_)*
266 jas_image_cmpthstep(jp2_image, components[i])((jp2_image)->cmpts_[components[i]]->hstep_)) != (long)imageWidth())
267 ) ||
268 (
269 ((jas_image_cmptheight(jp2_image, components[i])((jp2_image)->cmpts_[components[i]]->height_)*
270 jas_image_cmptvstep(jp2_image, components[i])((jp2_image)->cmpts_[components[i]]->vstep_)) != (long)imageHeight())
271 ) ||
272 (jas_image_cmpttlx(jp2_image, components[i])((jp2_image)->cmpts_[components[i]]->tlx_) != 0) ||
273 (jas_image_cmpttly(jp2_image, components[i])((jp2_image)->cmpts_[components[i]]->tly_) != 0) ||
274 (jas_image_cmptsgnd(jp2_image, components[i])((jp2_image)->cmpts_[components[i]]->sgnd_) != false)
275 )
276 {
277 qCWarning(DIGIKAM_DIMG_LOG_JP2K)for (QLoggingCategoryMacroHolder<QtWarningMsg> qt_category
((DIGIKAM_DIMG_LOG_JP2K)()); qt_category; qt_category.control
= false) QMessageLogger(static_cast<const char *>("/home/gilles/devel/8.x/core/dplugins/dimg/jpeg2000/dimgjpeg2000loader_load.cpp"
), 277, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).warning()
<< "Error parsing JPEG2000 image : Irregular Channel Geometry Not Supported";
278 jas_image_destroy(jp2_image);
279
280 cleanupJasper();
281 loadingFailed();
282
283 return false;
284 }
285
286 x_step[i] = jas_image_cmpthstep(jp2_image, components[i])((jp2_image)->cmpts_[components[i]]->hstep_);
287 y_step[i] = jas_image_cmptvstep(jp2_image, components[i])((jp2_image)->cmpts_[components[i]]->vstep_);
288 }
289
290 // -------------------------------------------------------------------
291 // Get image format.
292
293 maximum_component_depth = 0;
294
295 for (i = 0 ; i < (long)number_components ; ++i)
296 {
297 maximum_component_depth = qMax((long)jas_image_cmptprec(jp2_image, components[i])((jp2_image)->cmpts_[components[i]]->prec_),
298 (long)maximum_component_depth);
299
300 pixels[i] = jas_matrix_create(1, ((unsigned int)imageWidth()) / x_step[i]);
301
302 if (!pixels[i])
303 {
304 qCWarning(DIGIKAM_DIMG_LOG_JP2K)for (QLoggingCategoryMacroHolder<QtWarningMsg> qt_category
((DIGIKAM_DIMG_LOG_JP2K)()); qt_category; qt_category.control
= false) QMessageLogger(static_cast<const char *>("/home/gilles/devel/8.x/core/dplugins/dimg/jpeg2000/dimgjpeg2000loader_load.cpp"
), 304, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).warning()
<< "Error decoding JPEG2000 image data : Memory Allocation Failed";
305 jas_image_destroy(jp2_image);
306
307 cleanupJasper();
308 loadingFailed();
309
310 return false;
311 }
312 }
313
314#if defined JAS_VERSION_MAJOR4 && JAS_VERSION_MAJOR4 >= 3
315
316 if (!(m_loadFlags & LoadImageData) && !(m_loadFlags & LoadICCData))
317 {
318 imageSetAttribute(QLatin1String("originalColorModel"), colorModel);
319 imageSetAttribute(QLatin1String("originalBitDepth"), maximum_component_depth);
320 imageSetAttribute(QLatin1String("originalSize"), QSize(imageWidth(), imageHeight()));
321
322 jas_image_destroy(jp2_image);
323 cleanupJasper();
324
325 return true;
326 }
327
328#endif
329
330 if (maximum_component_depth > 8)
331 {
332 m_sixteenBit = true;
333 }
334
335 for (i = 0 ; i < (long)number_components ; ++i)
336 {
337 scale[i] = 1;
338 int prec = jas_image_cmptprec(jp2_image, components[i])((jp2_image)->cmpts_[components[i]]->prec_);
339
340 if (m_sixteenBit && (prec < 16))
341 {
342 scale[i] = (1 << (16 - jas_image_cmptprec(jp2_image, components[i])((jp2_image)->cmpts_[components[i]]->prec_)));
343 }
344 }
345
346 // -------------------------------------------------------------------
347 // Get image data.
348
349 QScopedArrayPointer<uchar> data;
350
351 if (m_loadFlags & LoadImageData)
352 {
353 if (m_sixteenBit) // 16 bits image.
354 {
355 data.reset(new_failureTolerant(imageWidth(), imageHeight(), 8));
356 }
357 else
358 {
359 data.reset(new_failureTolerant(imageWidth(), imageHeight(), 4));
360 }
361
362 if (!data)
363 {
364 qCWarning(DIGIKAM_DIMG_LOG_JP2K)for (QLoggingCategoryMacroHolder<QtWarningMsg> qt_category
((DIGIKAM_DIMG_LOG_JP2K)()); qt_category; qt_category.control
= false) QMessageLogger(static_cast<const char *>("/home/gilles/devel/8.x/core/dplugins/dimg/jpeg2000/dimgjpeg2000loader_load.cpp"
), 364, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).warning()
<< "Error decoding JPEG2000 image data : Memory Allocation Failed";
365 jas_image_destroy(jp2_image);
366
367 for (i = 0 ; i < (long)number_components ; ++i)
368 {
369 jas_matrix_destroy(pixels[i]);
370 }
371
372 cleanupJasper();
373 loadingFailed();
374
375 return false;
376 }
377
378 uint checkPoint = 0;
379 uchar* dst = data.data();
380 unsigned short* dst16 = reinterpret_cast<unsigned short*>(data.data());
381
382 for (y = 0 ; y < (long)imageHeight() ; ++y)
383 {
384 for (i = 0 ; i < (long)number_components ; ++i)
385 {
386 int ret = jas_image_readcmpt(jp2_image, (short)components[i], 0,
387 ((unsigned int) y) / y_step[i],
388 ((unsigned int) imageWidth()) / x_step[i],
389 1, pixels[i]);
390
391 if (ret != 0)
392 {
393 qCWarning(DIGIKAM_DIMG_LOG_JP2K)for (QLoggingCategoryMacroHolder<QtWarningMsg> qt_category
((DIGIKAM_DIMG_LOG_JP2K)()); qt_category; qt_category.control
= false) QMessageLogger(static_cast<const char *>("/home/gilles/devel/8.x/core/dplugins/dimg/jpeg2000/dimgjpeg2000loader_load.cpp"
), 393, static_cast<const char *>(__PRETTY_FUNCTION__),
qt_category.name()).warning()
<< "Error decoding JPEG2000 image data";
394 jas_image_destroy(jp2_image);
395
396 for (i = 0 ; i < (long)number_components ; ++i)
397 {
398 jas_matrix_destroy(pixels[i]);
399 }
400
401 cleanupJasper();
402 loadingFailed();
403
404 return false;
405 }
406 }
407
408 switch (number_components)
409 {
410 case 1: // Grayscale.
411 {
412 if (!m_sixteenBit) // 8 bits image.
413 {
414 for (x = 0 ; x < (long)imageWidth() ; ++x)
415 {
416 dst[0] = (uchar)(scale[0] * jas_matrix_getv(pixels[0], x / x_step[0]));
417 dst[1] = dst[0];
418 dst[2] = dst[0];
419 dst[3] = 0xFF;
420
421 dst += 4;
422 }
423 }
424 else // 16 bits image.
425 {
426 for (x = 0 ; x < (long)imageWidth() ; ++x)
427 {
428 dst16[0] = (unsigned short)(scale[0] * jas_matrix_getv(pixels[0], x / x_step[0]));
429 dst16[1] = dst16[0];
430 dst16[2] = dst16[0];
431 dst16[3] = 0xFFFF;
432
433 dst16 += 4;
434 }
435 }
436
437 break;
438 }
439
440 case 3: // RGB.
441 {
442 if (!m_sixteenBit) // 8 bits image.
443 {
444 for (x = 0 ; x < (long)imageWidth() ; ++x)
445 {
446 // Blue
447 dst[0] = (uchar)(scale[2] * jas_matrix_getv(pixels[2], x / x_step[2]));
448 // Green
449 dst[1] = (uchar)(scale[1] * jas_matrix_getv(pixels[1], x / x_step[1]));
450 // Red
451 dst[2] = (uchar)(scale[0] * jas_matrix_getv(pixels[0], x / x_step[0]));
452 // Alpha
453 dst[3] = 0xFF;
454
455 dst += 4;
456 }
457 }
458 else // 16 bits image.
459 {
460 for (x = 0 ; x < (long)imageWidth() ; ++x)
461 {
462 // Blue
463 dst16[0] = (unsigned short)(scale[2] * jas_matrix_getv(pixels[2], x / x_step[2]));
464 // Green
465 dst16[1] = (unsigned short)(scale[1] * jas_matrix_getv(pixels[1], x / x_step[1]));
466 // Red
467 dst16[2] = (unsigned short)(scale[0] * jas_matrix_getv(pixels[0], x / x_step[0]));
468 // Alpha
469 dst16[3] = 0xFFFF;
470
471 dst16 += 4;
472 }
473 }
474
475 break;
476 }
477
478 case 4: // RGBA.
479 {
480 if (!m_sixteenBit) // 8 bits image.
481 {
482 for (x = 0 ; x < (long)imageWidth() ; ++x)
483 {
484 // Blue
485 dst[0] = (uchar)(scale[2] * jas_matrix_getv(pixels[2], x / x_step[2]));
486 // Green
487 dst[1] = (uchar)(scale[1] * jas_matrix_getv(pixels[1], x / x_step[1]));
488 // Red
489 dst[2] = (uchar)(scale[0] * jas_matrix_getv(pixels[0], x / x_step[0]));
490 // Alpha
491 dst[3] = (uchar)(scale[3] * jas_matrix_getv(pixels[3], x / x_step[3]));
492
493 dst += 4;
494 }
495 }
496 else // 16 bits image.
497 {
498 for (x = 0 ; x < (long)imageWidth() ; ++x)
499 {
500 // Blue
501 dst16[0] = (unsigned short)(scale[2] * jas_matrix_getv(pixels[2], x / x_step[2]));
502 // Green
503 dst16[1] = (unsigned short)(scale[1] * jas_matrix_getv(pixels[1], x / x_step[1]));
504 // Red
505 dst16[2] = (unsigned short)(scale[0] * jas_matrix_getv(pixels[0], x / x_step[0]));
506 // Alpha
507 dst16[3] = (unsigned short)(scale[3] * jas_matrix_getv(pixels[3], x / x_step[3]));
508
509 dst16 += 4;
510 }
511 }
512
513 break;
514 }
515 }
516
517 // Use 0-10% and 90-100% for pseudo-progress
518
519 if (observer && (y >= (long)checkPoint))
520 {
521 checkPoint += granularity(observer, y, 0.8F);
522
523 if (!observer->continueQuery())
524 {
525 jas_image_destroy(jp2_image);
526
527 for (i = 0 ; i < (long)number_components ; ++i)
528 {
529 jas_matrix_destroy(pixels[i]);
530 }
531
532 cleanupJasper();
533 loadingFailed();
534
535 return false;
536 }
537
538 observer->progressInfo(0.1F + (0.8F * (((float)y) / ((float)imageHeight()))));
539 }
540 }
541 }
542
543 // -------------------------------------------------------------------
544 // Get ICC color profile.
545
546 if (m_loadFlags & LoadICCData)
547 {
548 jas_iccprof_t* icc_profile = nullptr;
549 jas_stream_t* icc_stream = nullptr;
550 jas_cmprof_t* cm_profile = nullptr;
551
552 // To prevent cppcheck warnings.
553
554 (void)icc_profile;
555 (void)icc_stream;
556 (void)cm_profile;
557
558 cm_profile = jas_image_cmprof(jp2_image)((jp2_image)->cmprof_);
559
560 if (cm_profile != nullptr)
561 {
562 icc_profile = jas_iccprof_createfromcmprof(cm_profile);
563 }
564
565 if (icc_profile != nullptr)
566 {
567 icc_stream = jas_stream_memopen(nullptr, 0);
568
569 if (icc_stream != nullptr)
570 {
571 if (jas_iccprof_save(icc_profile, icc_stream) == 0)
572 {
573 if (jas_stream_flush(icc_stream) == 0)
574 {
575 jas_stream_memobj_t* const blob = reinterpret_cast<jas_stream_memobj_t*>(icc_stream->obj_);
576 QByteArray profile_rawdata;
577 profile_rawdata.resize(blob->len_);
578 memcpy(profile_rawdata.data(), blob->buf_, blob->len_);
579 imageSetIccProfile(IccProfile(profile_rawdata));
580 jas_stream_close(icc_stream);
581 }
582 }
583 }
584 }
585 else
586 {
587 // If ICC profile is null, check Exif metadata.
588
589 checkExifWorkingColorSpace();
590 }
591 }
592
593 if (observer)
594 {
595 observer->progressInfo(1.0F);
596 }
597
598 imageData() = data.take();
599 imageSetAttribute(QLatin1String("originalColorModel"), colorModel);
600 imageSetAttribute(QLatin1String("originalBitDepth"), maximum_component_depth);
601 imageSetAttribute(QLatin1String("originalSize"), QSize(imageWidth(), imageHeight()));
602
603 jas_image_destroy(jp2_image);
604
605 for (i = 0 ; i < (long)number_components ; ++i)
606 {
607 jas_matrix_destroy(pixels[i]);
608 }
609
610 cleanupJasper();
611
612 return true;
613}
614
615} // namespace DigikamJPEG2000DImgPlugin