Bug 517588 - Cut and paste crash, jas_init_library: Assertion `!jas_global.initialized' failed
Summary: Cut and paste crash, jas_init_library: Assertion `!jas_global.initialized' fa...
Status: RESOLVED FIXED
Alias: None
Product: digikam
Classification: Applications
Component: Plugin-DImg-JP2K (other bugs)
Version First Reported In: 9.0.0
Platform: Other Linux
: NOR crash
Target Milestone: ---
Assignee: Digikam Developers
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2026-03-15 00:24 UTC by Dave Gilbert
Modified: 2026-03-16 12:30 UTC (History)
2 users (show)

See Also:
Latest Commit:
Version Fixed/Implemented In: 9.1.0
Sentry Crash Report:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Dave Gilbert 2026-03-15 00:24:16 UTC
SUMMARY
I've got a repeatable crash on Fedora 44Beta's Digikam 9.0.0 and was asked to upstream the bug.
It looks like Digikam is calling jas_init_library(..) in the jasper jpeg library, twice, 

(Sometimes the paste will work and then digikam will crash rather than it crashing first)
Originally filed as https://bugzilla.redhat.com/show_bug.cgi?id=2447616

STEPS TO REPRODUCE
1. Open an image in the image editor
2. Open an external program - e.g. gimp that can accept a paste
3. Select an area of the image in digikam and 'copy' to the clipboard
4. In gimp select file->Create->From clipboard

(Sometimes it fails between 3 and 4)

OBSERVED RESULT

digikam: /builddir/build/BUILD/jasper-4.2.8-build/jasper-version-4.2.8/src/libjasper/base/jas_init.c:505: jas_init_library: Assertion `!jas_global.initialized' failed.

EXPECTED RESULT

A happy paste

SOFTWARE/OS VERSIONS

digiKam: 9.0.0
KDE Frameworks: 6.24.0
Qt: Using 6.10.2 and built against 6.10.2
Fedora Linux 44 (Forty Four Prerelease) (Xcb)
Build ABI: x86_64-little_endian-lp64
Kernel: linux 6.19.7-300.fc44.x86_64

Linux/KDE Plasma: plasma-welcome-6.6.2-1.fc44.x86_64

ADDITIONAL INFORMATION

I'm running under xfce
Back trace on crash

--------
#0  __pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6, no_tid=no_tid@entry=0)
    at pthread_kill.c:44
#1  0x00007fe9fb07aa73 in __pthread_kill_internal (threadid=<optimized out>, signo=6) at pthread_kill.c:89
#2  0x00007fe9fb01f34e in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
#3  0x00007fe9fb0067b3 in __GI_abort () at abort.c:77
#4  0x00007fe9fb007804 in __libc_message_impl
    (vma_name=vma_name@entry=0x7fe9fb1baea3 "glibc: assert", fmt=<optimized out>) at ../sysdeps/posix/libc_fatal.c:138
#5  0x00007fe9fb017285 in __libc_message_wrapper (vmaname=0x7fe9fb1baea3 "glibc: assert", fmt=<optimized out>)
    at ../include/stdio.h:203
#6  __assert_fail
    (assertion=assertion@entry=0x7fe9f87892c8 "!jas_global.initialized", file=file@entry=0x7fe9f8784848 "/builddir/build/BUILD/jasper-4.2.8-build/jasper-version-4.2.8/src/libjasper/base/jas_init.c", line=line@entry=505, function=function@entry=0x7fe9f878b460 <__PRETTY_FUNCTION__.7.lto_priv.2> "jas_init_library") at assert.c:37
#7  0x00007fe9f87461f0 in jas_init_library ()
    at /usr/src/debug/jasper-4.2.8-2.fc44.x86_64/src/libjasper/base/jas_init.c:505
#8  0x00007fe8784248fe in Jpeg2000JasperReader::Jpeg2000JasperReader
    (this=0x7fff9fa0eab0, iod=<optimized out>, format=Jp2Format, this=<optimized out>, iod=<optimized out>, format=<optimized out>) at /usr/src/debug/qt6-qtimageformats-6.10.2-1.fc44.x86_64/src/plugins/imageformats/jp2/qjp2handler.cpp:316
#9  0x00007fe8784263f4 in QJp2Handler::write (this=0x55a4cdc48b90, image=...)
    at /usr/src/debug/qt6-qtimageformats-6.10.2-1.fc44.x86_64/src/plugins/imageformats/jp2/qjp2handler.cpp:222
#10 0x00007fe9fbeb4a3b in QImageWriter::write (this=0x7fff9fa0ec08, image=<optimized out>)
    at /usr/src/debug/qt6-qtbase-6.10.2-2.fc44.x86_64/src/gui/image/qimagewriter.cpp:682
#11 0x00007fe9fbe7da03 in QImage::save
    (this=this@entry=0x7fff9fa0ec80, device=device@entry=0x7fff9fa0ec70, format=0x55a4cdba29e0 "J2K", quality=quality@entry=-1) at /usr/src/debug/qt6-qtbase-6.10.2-2.fc44.x86_64/src/gui/image/qimage.cpp:3967
--Type <RET> for more, q to quit, c to continue without paging--
#12 0x00007fe9fbf1c1f6 in QInternalMimeData::renderDataHelper (mimeType=..., data=data@entry=0x55a4c9c2b840) at /usr/src/debug/qt6-qtbase-6.10.2-2.fc44.x86_64/src/gui/kernel/qinternalmimedata.cpp:195
#13 0x00007fe8cc92d630 in QXcbMime::mimeDataForAtom
    (connection=0x55a4b04db1b0, a=a@entry=615, mimeData=mimeData@entry=0x55a4c9c2b840, data=data@entry=0x7fff9fa0ee80, atomFormat=atomFormat@entry=0x7fff9fa0ee70, dataFormat=dataFormat@entry=0x7fff9fa0ee74)
    at /usr/src/debug/qt6-qtbase-6.10.2-2.fc44.x86_64/src/plugins/platforms/xcb/qxcbmime.cpp:77
#14 0x00007fe8cc8f5aa4 in QXcbClipboard::sendSelection (this=this@entry=0x55a4b0515a50, d=d@entry=0x55a4c9c2b840, target=615, window=12582916, property=379)
    at /usr/src/debug/qt6-qtbase-6.10.2-2.fc44.x86_64/src/plugins/platforms/xcb/qxcbobject.h:17
#15 0x00007fe8cc8f7ad5 in QXcbClipboard::handleSelectionRequest (this=0x55a4b0515a50, req=req@entry=0x55a4cdc9f390) at /usr/src/debug/qt6-qtbase-6.10.2-2.fc44.x86_64/src/plugins/platforms/xcb/qxcbclipboard.cpp:593
#16 0x00007fe8cc8fbde0 in QXcbConnection::handleXcbEvent (this=this@entry=0x55a4b04db1b0, event=event@entry=0x55a4cdc9f390) at /usr/src/debug/qt6-qtbase-6.10.2-2.fc44.x86_64/src/plugins/platforms/xcb/qxcbconnection.cpp:667
#17 0x00007fe8cc8fd1d7 in QXcbConnection::processXcbEvents (this=0x55a4b04db1b0, flags=...) at /usr/src/debug/qt6-qtbase-6.10.2-2.fc44.x86_64/src/plugins/platforms/xcb/qxcbconnection.cpp:1088
#18 0x00007fe8cc9215cf in xcbSourceDispatch (source=<optimized out>) at /usr/src/debug/qt6-qtbase-6.10.2-2.fc44.x86_64/src/plugins/platforms/xcb/qxcbeventdispatcher.cpp:57
#19 0x00007fe9f92e1e64 in g_main_dispatch (context=0x7fe8b8000f00) at ../glib/gmain.c:3591
#20 g_main_context_dispatch_unlocked (context=0x7fe8b8000f00) at ../glib/gmain.c:4451
#21 0x00007fe9f92e5f78 in g_main_context_iterate_unlocked (context=context@entry=0x7fe8b8000f00, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at ../glib/gmain.c:4516
#22 0x00007fe9f92e6123 in g_main_context_iteration (context=0x7fe8b8000f00, may_block=1) at ../glib/gmain.c:4582
#23 0x00007fe9fba508ed in QEventDispatcherGlib::processEvents (this=0x55a4b0766150, flags=...) at /usr/src/debug/qt6-qtbase-6.10.2-2.fc44.x86_64/src/corelib/kernel/qeventdispatcher_glib.cpp:399
#24 0x00007fe9fb716f03 in QEventLoop::exec (this=this@entry=0x7fff9fa0f380, flags=..., flags@entry=...) at /usr/src/debug/qt6-qtbase-6.10.2-2.fc44.x86_64/src/corelib/global/qflags.h:77
#25 0x00007fe9fb7120d2 in QCoreApplication::exec () at /usr/src/debug/qt6-qtbase-6.10.2-2.fc44.x86_64/src/corelib/kernel/qcoreapplication.cpp:1452
#26 0x00007fe9fbeeb88d in QGuiApplication::exec () at /usr/src/debug/qt6-qtbase-6.10.2-2.fc44.x86_64/src/gui/kernel/qguiapplication.cpp:1977
#27 0x00007fe9fca3ee19 in QApplication::exec () at /usr/src/debug/qt6-qtbase-6.10.2-2.fc44.x86_64/src/widgets/kernel/qapplication.cpp:2575
#28 0x000055a477e50d27 in main (argc=<optimized out>, argv=<optimized out>) at /usr/src/debug/digikam-9.0.0-2.fc44.x86_64/core/app/main/main.cpp:496

--------
The first call to the library init is coming from:

#0  jas_init_library () at /usr/src/debug/jasper-4.2.8-2.fc44.x86_64/src/libjasper/base/jas_init.c:476
#1  0x00007ffea4391788 in DigikamJPEG2000DImgPlugin::DImgJPEG2000Plugin::DImgJPEG2000Plugin (this=this@entry=0x55556af950f0, parent=0x0)
    at /usr/src/debug/digikam-9.0.0-2.fc44.x86_64/core/dplugins/dimg/jpeg2000/dimgjpeg2000plugin.cpp:55
#2  0x00007ffea4398e47 in qt_plugin_instance ()
    at /usr/src/debug/digikam-9.0.0-2.fc44.x86_64/redhat-linux-build/core/dplugins/dimg/jpeg2000/DImg_JPEG2000_Plugin_autogen/include/moc_dimgjpeg2000plugin.cpp:110
#3  0x00007ffff4049443 in QLibraryPrivate::pluginInstance (this=0x55556af54bc0)
    at /usr/src/debug/qt6-qtbase-6.10.2-2.fc44.x86_64/src/corelib/plugin/qlibrary.cpp:515
#4  0x00007ffff3da4d33 in QPluginLoader::instance (this=this@entry=0x55556af950c0)
    at /usr/src/debug/qt6-qtbase-6.10.2-2.fc44.x86_64/src/corelib/plugin/qpluginloader.cpp:143
#5  0x00007ffff5fe864d in Digikam::DPluginLoader::Private::loadPlugins (this=0x555556ee5460)
    at /usr/src/debug/digikam-9.0.0-2.fc44.x86_64/core/libs/dplugins/setup/dpluginloader_p.cpp:244
#6  0x00007ffff7544cc3 in Digikam::DigikamApp::DigikamApp (this=this@entry=0x555556228200, this=<optimized out>)
    at /usr/src/debug/digikam-9.0.0-2.fc44.x86_64/core/app/main/digikamapp.cpp:167
#7  0x0000555555557a2a in main (argc=<optimized out>, argv=<optimized out>) at /usr/src/debug/digikam-9.0.0-2.fc44.x86_64/core/app/main/main.cpp:441
Comment 1 Maik Qualmann 2026-03-15 05:02:11 UTC
The second Jasper initialization comes from the KImageFormat plugins, specifically from our QImage Loader.

For some reason, the image is being rejected by our Jpeg2000 Loader, resulting in a fallback to the QImage Loader and thus triggering the second Jasper initialization.

We need to block Jpeg2000 files for our QImage Loader. I see no other option.

Maik
Comment 2 Maik Qualmann 2026-03-15 05:05:41 UTC
I now see that it's a save operation; the QImage Loader is saving a file. What file format is being saved when it crashes?

Maik
Comment 3 Maik Qualmann 2026-03-15 05:13:34 UTC
Okay, it's a paste operation and it uses QImage::save()...

Maik
Comment 4 Maik Qualmann 2026-03-15 06:59:01 UTC
We set the image selection as a QImage using QMimeData::setImageData() and pass it to the QClipboard. Internally in Qt, it's then stored as a Jpeg2000 image in QInternalMimeData::renderDataHelper(). Normally, Qt would process it as a PNG. So I suspect Fedora patched something to improve interaction with GNOME programs.

To avoid encoding the QMimeData myself, I'll take a different approach...

Maik
Comment 5 Dave Gilbert 2026-03-15 11:46:15 UTC
(In reply to Maik Qualmann from comment #4)
> We set the image selection as a QImage using QMimeData::setImageData() and
> pass it to the QClipboard. Internally in Qt, it's then stored as a Jpeg2000
> image in QInternalMimeData::renderDataHelper(). Normally, Qt would process
> it as a PNG. So I suspect Fedora patched something to improve interaction
> with GNOME programs.
> 
> To avoid encoding the QMimeData myself, I'll take a different approach...
> 
> Maik

The jasper library init all seems rather delicate; neither or the routes that use it sound unreasonable, and who knows if another plugin would call a library that would want it somewhere.
Comment 6 Maik Qualmann 2026-03-15 19:25:26 UTC
Git commit 9dd5e992b71b6a855fc419114344d4bd181bc08f by Maik Qualmann.
Committed on 15/03/2026 at 19:23.
Pushed by mqualmann into branch 'master'.

use the QImage Loader if JPEG2000 is available.
Since jas_init_library() and jas_cleanup_library() can only be
called once in the main thread, it is almost impossible to
handle them if another Jasper Loader is present in a library.
FIXED-IN: 9.1.0

M  +1    -1    NEWS
M  +13   -2    core/dplugins/dimg/jpeg2000/dimgjpeg2000plugin.cpp

https://invent.kde.org/graphics/digikam/-/commit/9dd5e992b71b6a855fc419114344d4bd181bc08f
Comment 7 Dave Gilbert 2026-03-16 12:30:10 UTC
(In reply to Maik Qualmann from comment #6)
> Git commit 9dd5e992b71b6a855fc419114344d4bd181bc08f by Maik Qualmann.
> Committed on 15/03/2026 at 19:23.
> Pushed by mqualmann into branch 'master'.
> 
> use the QImage Loader if JPEG2000 is available.
> Since jas_init_library() and jas_cleanup_library() can only be
> called once in the main thread, it is almost impossible to
> handle them if another Jasper Loader is present in a library.
> FIXED-IN: 9.1.0
> 
> M  +1    -1    NEWS
> M  +13   -2    core/dplugins/dimg/jpeg2000/dimgjpeg2000plugin.cpp
> 
> https://invent.kde.org/graphics/digikam/-/commit/
> 9dd5e992b71b6a855fc419114344d4bd181bc08f

Thanks - that was quick!
Maik built testing packages on Fedora with that fix in, andit seems to fix it for me.

Thanks again,

Dave