Summary: | Crash when saving scanned image to .tiff | ||
---|---|---|---|
Product: | [Frameworks and Libraries] libksane | Reporter: | Michael G. Hansen <mike> |
Component: | general | Assignee: | imaging-bugs-null |
Status: | RESOLVED FIXED | ||
Severity: | crash | CC: | caulier.gilles, kde, marcel.wiesweg, ran31som |
Priority: | NOR | ||
Version: | unspecified | ||
Target Milestone: | --- | ||
Platform: | Debian testing | ||
OS: | Linux | ||
Latest Commit: | Version Fixed In: | ||
Sentry Crash Report: |
Description
Michael G. Hansen
2009-07-17 15:11:44 UTC
libtiff4 version: 3.8.2-13 reproduced here with current trunk i try to understand the issue. the main pb comes from common/libkipiplugins/kpwriteimage.cpp line 537 TIFFSetField(tif, TIFFTAG_EXTRASAMPLES, EXTRASAMPLE_ASSOCALPHA); i commented it for test purposes and all is OK i will try to debug more today Nicolas, Look there : http://www.awaresystems.be/imaging/tiff/tifftags/extrasamples.html In other words, this want mean that tiff image will have an alpha chanel, typicaly taken from ARGB QImage container. Imagine that QIMage data is composed of RGB components... boum... I see recently tat Kare as changed a lots of code from libksane. This can be the problem. A wrap around is to check if the QImage has an alpha chanel and adapt tiff image tag accordingly Gilles Caulier after looking deeper i have clue: in acquireimages/scandialog.cpp line 292 we have if ( frmt != KSaneIface::KSaneWidget::FormatRGB_16_C ) { QByteArray data((const char*)img.bits(), img.numBytes()); wImageIface.setImageData(data, img.width(), img.height(), false, true, prof, meta); } this is used when there is no alpha Channel, but KSaneIface::KSaneWidget::FormatRGB_8_C doesn't have any alpha channel too so i want to add : Index: acquireimages/scandialog.cpp =================================================================== --- acquireimages/scandialog.cpp (révision 998526) +++ acquireimages/scandialog.cpp (copie de travail) @@ -288,14 +288,15 @@ meta.setImageColorWorkSpace(KExiv2Iface::KExiv2::WORKSPACE_SRGB); KIPIPlugins::KPWriteImage wImageIface; - if (frmt != KSaneIface::KSaneWidget::FormatRGB_16_C) + + if ( frmt != KSaneIface::KSaneWidget::FormatRGB_16_C || frmt != KSaneIface::KSaneWidget::FormatRGB_8_C ) { QByteArray data((const char*)img.bits(), img.numBytes()); wImageIface.setImageData(data, img.width(), img.height(), false, true, prof, meta); } else { - // 16 bits color depth image. + // 8 and 16 bits color depth image. wImageIface.setImageData(ksane_data, width, height, true, false, prof, meta); } this doesn't fix the issue for me but this seems cleaner and maybe fix some other crashes My logic was wrong. This patch fixes the issue. can i commit this ? Index: acquireimages/scandialog.cpp =================================================================== --- acquireimages/scandialog.cpp (révision 998526) +++ acquireimages/scandialog.cpp (copie de travail) @@ -288,15 +288,16 @@ meta.setImageColorWorkSpace(KExiv2Iface::KExiv2::WORKSPACE_SRGB); KIPIPlugins::KPWriteImage wImageIface; - if (frmt != KSaneIface::KSaneWidget::FormatRGB_16_C) + + if ( (frmt = KSaneIface::KSaneWidget::FormatRGB_16_C) || (frmt = KSaneIface::KSaneWidget::FormatRGB_8_C) ) { - QByteArray data((const char*)img.bits(), img.numBytes()); - wImageIface.setImageData(data, img.width(), img.height(), false, true, prof, meta); + // 8 and 16 bits color depth image. + wImageIface.setImageData(ksane_data, width, height, true, false, prof, meta); } else { - // 16 bits color depth image. - wImageIface.setImageData(ksane_data, width, height, true, false, prof, meta); + QByteArray data((const char*)img.bits(), img.numBytes()); + wImageIface.setImageData(data, img.width(), img.height(), false, true, prof, meta); } if (format == QString("JPEG")) Fine for me Gilles sorry i forgot to close the bugreport when commiting. i commited revision 998596. Please reopen if the bug still appear I'm sorry to say that the patch still does not work for me. I am now also getting crashes when saving to PNG. I think the problem is that wImageIface.setImageData is now called with sixteenBit=true for both 8 and 16 bit cases. Declaration: void setImageData(const QByteArray& data, uint width, uint height, bool sixteenBit, bool hasAlpha, const QByteArray& iccProfile, const KExiv2Iface::KExiv2& metadata) // relevant code: if ( (frmt = KSaneIface::KSaneWidget::FormatRGB_16_C) || (frmt = KSaneIface::KSaneWidget::FormatRGB_8_C) ) { // 8 and 16 bits color depth image. wImageIface.setImageData(ksane_data, width, height, true, false, prof, meta); sorry, forgot to re-open can you provide a backtrace for you crash and for the crash with a PNG file please ? [KCrash Handler] #6 KIPIPlugins::KPWriteImage::write2PNG (this=0xbf802de0, destPath=@0xbf802dd0) at /home/niconico/Documents/SVN_KDE/extragear/graphics/kipi-plugins/common/libkipiplugins/kpwriteimage.cpp:455 #7 0xa8b4742e in KIPIAcquireImagesPlugin::ScanDialog::slotSaveImage (this=0xbf8039e4, ksane_data=@0xd47036c, width=5098, height=7012, bytes_per_line=20392, ksaneformat=3) at /home/niconico/Documents/SVN_KDE/extragear/graphics/kipi-plugins/acquireimages/scandialog.cpp:309 #8 0xa8b486cb in KIPIAcquireImagesPlugin::ScanDialog::qt_metacall (this=0xbf8039e4, _c=QMetaObject::InvokeMetaMethod, _id=73, _a=0xbf803018) at /home/niconico/Documents/SVN_KDE/extragear/graphics/kipi-plugins/build/acquireimages/scandialog.moc:70 #9 0xb5815f29 in QMetaObject::activate (sender=0xd1b8b30, from_signal_index=27, to_signal_index=27, argv=0xbf803018) at kernel/qobject.cpp:3104 #10 0xb5816c65 in QMetaObject::activate (sender=0xd1b8b30, m=0xa8b228e8, local_signal_index=0, argv=0xbf803018) at kernel/qobject.cpp:3178 #11 0xa8b075ee in KSaneIface::KSaneWidget::imageReady (this=0xd1b8b30, _t1=@0xd47036c, _t2=5098, _t3=7012, _t4=20392, _t5=3) at /usr/src/debug/kdegraphics-4.2.96/build/libs/libksane/libksane/ksane.moc:93 #12 0xa8b076a7 in KSaneIface::KSaneWidget::qt_metacall (this=0xd1b8b30, _c=QMetaObject::InvokeMetaMethod, _id=27, _a=0xbf803158) at /usr/src/debug/kdegraphics-4.2.96/build/libs/libksane/libksane/ksane.moc:77 #13 0xb5815f29 in QMetaObject::activate (sender=0xd4702b8, from_signal_index=4, to_signal_index=4, argv=0xbf803158) at kernel/qobject.cpp:3104 #14 0xb5816c65 in QMetaObject::activate (sender=0xd4702b8, m=0xa8b22a08, local_signal_index=0, argv=0xbf803158) at kernel/qobject.cpp:3178 #15 0xa8b0c3ee in KSaneIface::KSaneWidgetPrivate::imageReady (this=0xd4702b8, _t1=@0xd47036c, _t2=5098, _t3=7012, _t4=20392, _t5=3) at /usr/src/debug/kdegraphics-4.2.96/build/libs/libksane/libksane/ksane_widget_private.moc:118 #16 0xa8b0c553 in KSaneIface::KSaneWidgetPrivate::scanDone (this=0xd4702b8) at /usr/src/debug/kdegraphics-4.2.96/libs/libksane/libksane/ksane_widget_private.cpp:867 #17 0xa8b0c8a3 in KSaneIface::KSaneWidgetPrivate::processData (this=0xd4702b8) at /usr/src/debug/kdegraphics-4.2.96/libs/libksane/libksane/ksane_widget_private.cpp:993 #18 0xa8b0d194 in KSaneIface::KSaneWidgetPrivate::qt_metacall (this=0xd4702b8, _c=QMetaObject::InvokeMetaMethod, _id=18, _a=0xbbada10) at /usr/src/debug/kdegraphics-4.2.96/build/libs/libksane/libksane/ksane_widget_private.moc:106 #19 0xb580e68a in QMetaCallEvent::placeMetaCall (this=0xd4f47b8, object=0xd4702b8) at kernel/qobject.cpp:477 #20 0xb580fda6 in QObject::event (this=0xd4702b8, e=0xd4f47b8) at kernel/qobject.cpp:1102 #21 0xb5cd63ac in QApplicationPrivate::notify_helper (this=0x9c582d0, receiver=0xd4702b8, e=0xd4f47b8) at kernel/qapplication.cpp:4056 #22 0xb5cddefe in QApplication::notify (this=0xbf805c98, receiver=0xd4702b8, e=0xd4f47b8) at kernel/qapplication.cpp:3603 #23 0xb676fcd8 in KApplication::notify (this=0xbf805c98, receiver=0xd4702b8, event=0xd4f47b8) at /usr/src/debug/kdelibs-4.2.96/kdeui/kernel/kapplication.cpp:302 #24 0xb57ff79e in QCoreApplication::notifyInternal (this=0xbf805c98, receiver=0xd4702b8, event=0xd4f47b8) at kernel/qcoreapplication.cpp:610 #25 0xb580040a in QCoreApplicationPrivate::sendPostedEvents (receiver=0x0, event_type=0, data=0x9c328a0) at ../../src/corelib/kernel/qcoreapplication.h:213 #26 0xb58005ec in QCoreApplication::sendPostedEvents (receiver=0x0, event_type=0) at kernel/qcoreapplication.cpp:1140 #27 0xb582bdcd in postEventSourceDispatch (s=0x9c5b108) at ../../src/corelib/kernel/qcoreapplication.h:218 /home/niconico/Documents/SVN_KDE/extragear/graphics/kipi-plugins/common/libkipiplugins/kpwriteimage.cpp:455 Sound like you is outside image data... Gilles what do you mean gilles ? i think i understand what you mean. How can we know this ? i mean how to know if a PNG image can be set with sixteenBit ? I googled a bit on the offending line in kwriteimage.cpp that caused the original crash and found this bugreport on libimlib2 including a patch: http://www.mail-archive.com/debian-bugs-closed@lists.debian.org/msg98527.html Applying this patch to kwriteimage.cpp and reverting the changes to scandialog.cpp to pre-998596 fixes the crashes for me (for 8-bit tiff, that is, as I do not have a way to test 16-bit). Index: common/libkipiplugins/kpwriteimage.cpp =================================================================== --- common/libkipiplugins/kpwriteimage.cpp (revision 998734) +++ common/libkipiplugins/kpwriteimage.cpp (working copy) @@ -533,8 +533,9 @@ if (d->hasAlpha) { - TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 4); - TIFFSetField(tif, TIFFTAG_EXTRASAMPLES, EXTRASAMPLE_ASSOCALPHA); + uint16 extras[] = { EXTRASAMPLE_ASSOCALPHA }; + TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 4); + TIFFSetField(tif, TIFFTAG_EXTRASAMPLES, 1, extras); } else { Nicolas, Few pointers to check and compare. digiKam has TIFF, PNG, and JPEG image loader. Code is similar in kpwriteimage, but simplified a little. Look there : http://websvn.kde.org/trunk/extragear/graphics/digikam/libs/dimg/loaders/tiffloader.cpp?revision=997129&view=markup http://websvn.kde.org/trunk/extragear/graphics/digikam/libs/dimg/loaders/pngloader.cpp?revision=997129&view=markup http://websvn.kde.org/trunk/extragear/graphics/digikam/libs/dimg/loaders/jpegloader.cpp?revision=998736&view=markup Excepted for JPEG, PNG and TIFF loader support 16 bits/colors/pixels. Gilles Caulier From `man TIFFSetField`: Tag Name Count Types Notes TIFFTAG_EXTRASAMPLES 2 uint16,uint16* † count & types array For "TIFFTAG_EXTRASAMPLES", "TIFFSetField" expects two parameters, instead of just one value, so the code from the patch is right. Looking at http://websvn.kde.org/trunk/extragear/graphics/digikam/libs/dimg/loaders/tiffloader.cpp?revision=997129&view=markup Isn't the parameter to TIFFSetField here also wrong? "EXTRASAMPLE_ASSOCALPHA" just happens to be 1, that's why it does not show: Index: libs/dimg/loaders/tiffloader.cpp =================================================================== --- libs/dimg/loaders/tiffloader.cpp (revision 1001413) +++ libs/dimg/loaders/tiffloader.cpp (working copy) @@ -587,7 +587,7 @@ { uint16 sampleinfo[1] = { EXTRASAMPLE_UNASSALPHA }; TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 4); - TIFFSetField(tif, TIFFTAG_EXTRASAMPLES, EXTRASAMPLE_ASSOCALPHA, sampleinfo); + TIFFSetField(tif, TIFFTAG_EXTRASAMPLES, 1, sampleinfo); } else { Marcel, look comment #19 from Michael. What do you think about... Michael, digiKam tiff loader is inspired from and old version of ImageMagick tiff loader, and checking last code, i think you has right : http://trac.imagemagick.org/browser/ImageMagick/branches/ImageMagick-6.5.4/coders/tiff.c#L2309 Gilles Caulier Indeed our code is strange there. We should apply the patch. Further down in the code, we premultiply by alpha; so I think we have associated alpha (EXTRASAMPLE_ASSOCALPHA)? Nicolas, To test without a real sane device, just go to /etc/sane.d/dll.conf and uncomment "test" driver. After that, you will see 2 test devices in sane list. You can select bits depth (8 or 16) to test indeep code. Gilles Caulier SVN commit 1001752 by cgilles: fix associed alpha chanel registration with tiff image writer BUGS: 200558 M +5 -1 kpwriteimage.cpp WebSVN link: http://websvn.kde.org/?view=rev&revision=1001752 *** Bug 205140 has been marked as a duplicate of this bug. *** SVN commit 1026910 by sars: Revert commit 998596: "Fix crash when saving images in .tiff format" 998596 broke saving 8bit color images. This should fix 208107 "corrupted image when saving a scan" and has should not break 200558 again as there was another fix for that. I can now save 8 and 16 bit PNG, and 8 bitt TIFF, but the 16bit TIFFs are corrupted. BUG:208107 CCBUG:200558 M +5 -6 scandialog.cpp WebSVN link: http://websvn.kde.org/?view=rev&revision=1026910 |