diff --git a/gwenview/lib/document/loadingdocumentimpl.cpp b/gwenview/lib/document/loadingdocumentimpl.cpp
index 0928ce9..c57f22a 100644
--- gwenview/lib/document/loadingdocumentimpl.cpp
+++ gwenview/lib/document/loadingdocumentimpl.cpp
@@ -58,6 +58,12 @@ namespace Gwenview
 
 const int HEADER_SIZE = 256;
 
+// Null message handler for threads - suppresses all Qt debug output
+static void nullMessageHandler(QtMsgType, const char*)
+{
+    // Ignore all messages from threads to avoid KDE debug infrastructure
+}
+
 struct LoadingDocumentImplPrivate
 {
     LoadingDocumentImpl* q;
@@ -121,11 +127,13 @@ struct LoadingDocumentImplPrivate
             //   image using plugins matching this format first.
             mFormatHint = q->document()->url().fileName()
                 .section('.', -1).toAscii().toLower();
-            mMetaInfoFutureWatcher.reset(new BoolThread(q, std::bind(&LoadingDocumentImplPrivate::loadMetaInfo, this)));
+            mMetaInfoFutureWatcher.reset(new BoolThread(nullptr, std::bind(&LoadingDocumentImplPrivate::loadMetaInfo, this)));
             q->connect(
                 mMetaInfoFutureWatcher.data(), SIGNAL(finished()),
                 q, SLOT(slotMetaInfoLoaded())
             );
+            // Increase stack size for LibRaw which allocates large structures on stack
+            mMetaInfoFutureWatcher->setStackSize(4 * 1024 * 1024); // 4MB
             mMetaInfoFutureWatcher->start();
             break;
 
@@ -141,17 +149,22 @@ struct LoadingDocumentImplPrivate
         Q_ASSERT(mMetaInfoLoaded);
         Q_ASSERT(mImageDataInvertedZoom != 0);
         Q_ASSERT(!mImageDataFutureWatcher->isRunning());
-        mImageDataFutureWatcher.reset(new VoidThread(q, std::bind(&LoadingDocumentImplPrivate::loadImageData, this)));
+        mImageDataFutureWatcher.reset(new VoidThread(nullptr, std::bind(&LoadingDocumentImplPrivate::loadImageData, this)));
         q->connect(
             mImageDataFutureWatcher.data(), SIGNAL(finished()),
             q, SLOT(slotImageLoaded())
         );
+        // Increase stack size for LibRaw and image decoding
+        mImageDataFutureWatcher->setStackSize(4 * 1024 * 1024); // 4MB
         mImageDataFutureWatcher->start();
     }
 
     bool loadMetaInfo()
     {
-        kDebug() << "mFormatHint" << mFormatHint;
+        // Note: No kDebug()/kWarning() calls - runs in thread, not thread-safe
+        // Install null message handler to suppress Qt internal warnings/debug from QImageReader
+        QtMsgHandler oldHandler = qInstallMsgHandler(nullMessageHandler);
+
         QBuffer buffer;
         buffer.setBuffer(&mData);
         buffer.open(QIODevice::ReadOnly);
@@ -160,39 +173,38 @@ struct LoadingDocumentImplPrivate
         mImageSize = reader.size();
 
         if (!reader.canRead()) {
-            kWarning() << "QImageReader::read() using format hint" << mFormatHint << "failed:" << reader.errorString();
             if (buffer.pos() != 0) {
-                kWarning() << "A bad Katie image decoder moved the buffer to" << buffer.pos() << "in a call to canRead()! Rewinding.";
                 buffer.seek(0);
             }
             reader.setFormat(QByteArray());
             // Set buffer again, otherwise QImageReader won't restart from scratch
             reader.setDevice(&buffer);
             if (!reader.canRead()) {
-                kWarning() << "QImageReader::read() without format hint failed:" << reader.errorString();
                 return false;
             }
-            kWarning() << "Image format is actually" << reader.format() << "not" << mFormatHint;
         }
 
         mFormat = reader.format();
 
-        kDebug() << "mFormat" << mFormat;
-        GV_RETURN_VALUE_IF_FAIL(!mFormat.isEmpty(), false);
+        qInstallMsgHandler(oldHandler);
 
-        kDebug() << "mImageSize" << mImageSize;
+        if (mFormat.isEmpty()) {
+            return false;
+        }
 
         return true;
     }
 
     void loadImageData()
     {
+        // Note: No kDebug()/kWarning() calls - runs in thread, not thread-safe
+        // Install null message handler to suppress Qt internal warnings/debug from QImageReader
+        QtMsgHandler oldHandler = qInstallMsgHandler(nullMessageHandler);
+
         QBuffer buffer;
         buffer.setBuffer(&mData);
         buffer.open(QIODevice::ReadOnly);
         QImageReader reader(&buffer, mFormat);
-
-        kDebug() << "mImageDataInvertedZoom=" << mImageDataInvertedZoom;
         if (mImageSize.isValid()
                 && mImageDataInvertedZoom != 1
                 && reader.supportsOption(QImageIOHandler::ScaledSize)
@@ -201,26 +213,19 @@ struct LoadingDocumentImplPrivate
             // image size
             QSize size = reader.size() / mImageDataInvertedZoom;
             if (!size.isEmpty()) {
-                kDebug() << "Setting scaled size to" << size;
                 reader.setScaledSize(size);
-            } else {
-                kDebug() << "Not setting scaled size as it is empty" << size;
             }
         }
 
         if (reader.supportsAnimation() && reader.jumpToImage(0)) {
             if (reader.imageCount() > 0) {
-                kDebug() << "Really an animated image";
                 mAnimated = true;
-            } else {
-                kWarning() << q->document()->url() << "is not really an animated image (only one frame)";
             }
         }
 
-        bool ok = reader.read(&mImage);
-        if (!ok) {
-            kWarning() << "QImageReader::read() failed";
-        }
+        reader.read(&mImage);
+
+        qInstallMsgHandler(oldHandler);
     }
 };
 
@@ -237,24 +242,26 @@ LoadingDocumentImpl::LoadingDocumentImpl(Document* document)
 
 LoadingDocumentImpl::~LoadingDocumentImpl()
 {
-    // Disconnect watchers to make sure they do not trigger further work
-    if (d->mMetaInfoFutureWatcher) {
-        d->mMetaInfoFutureWatcher->disconnect();
-    }
-    if (d->mImageDataFutureWatcher) {
-        d->mImageDataFutureWatcher->disconnect();
+    // CRITICAL: Disconnect transfer job signals first to prevent callbacks to deleted object
+    if (d->mTransferJob) {
+        disconnect(d->mTransferJob, 0, this, 0);
+        // Don't call kill() - it accesses KIO scheduler which may be destroyed
     }
 
+    // Disconnect and wait for threads
     if (d->mMetaInfoFutureWatcher) {
-        d->mMetaInfoFutureWatcher->wait();
+        d->mMetaInfoFutureWatcher->disconnect();
+        if (d->mMetaInfoFutureWatcher->isRunning()) {
+            d->mMetaInfoFutureWatcher->wait();
+        }
     }
     if (d->mImageDataFutureWatcher) {
-        d->mImageDataFutureWatcher->wait();
+        d->mImageDataFutureWatcher->disconnect();
+        if (d->mImageDataFutureWatcher->isRunning()) {
+            d->mImageDataFutureWatcher->wait();
+        }
     }
 
-    if (d->mTransferJob) {
-        d->mTransferJob->kill();
-    }
     delete d;
 }
 
