File indexing completed on 2024-05-05 04:19:18

0001 // vim: set tabstop=4 shiftwidth=4 expandtab:
0002 /*
0003 Gwenview: an image viewer
0004 Copyright 2008 Aurélien Gâteau <agateau@kde.org>
0005 
0006 This program is free software; you can redistribute it and/or
0007 modify it under the terms of the GNU General Public License
0008 as published by the Free Software Foundation; either version 2
0009 of the License, or (at your option) any later version.
0010 
0011 This program is distributed in the hope that it will be useful,
0012 but WITHOUT ANY WARRANTY; without even the implied warranty of
0013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0014 GNU General Public License for more details.
0015 
0016 You should have received a copy of the GNU General Public License
0017 along with this program; if not, write to the Free Software
0018 Foundation, Inc., 51 Franklin Street, Fifth Floor, Cambridge, MA 02110-1301, USA.
0019 
0020 */
0021 // Self
0022 #include "preloader.h"
0023 
0024 // Qt
0025 
0026 // KF
0027 
0028 // Local
0029 #include "gwenview_app_debug.h"
0030 #include <lib/document/documentfactory.h>
0031 
0032 namespace Gwenview
0033 {
0034 #undef ENABLE_LOG
0035 #undef LOG
0036 // #define ENABLE_LOG
0037 #ifdef ENABLE_LOG
0038 #define LOG(x) qCDebug(GWENVIEW_APP_LOG) << x
0039 #else
0040 #define LOG(x) ;
0041 #endif
0042 
0043 struct PreloaderPrivate {
0044     Preloader *q = nullptr;
0045     Document::Ptr mDocument;
0046     QSize mSize;
0047 
0048     void forgetDocument()
0049     {
0050         // Forget about the document. Keeping a reference to it would prevent it
0051         // from being garbage collected.
0052         QObject::disconnect(mDocument.data(), nullptr, q, nullptr);
0053         mDocument = nullptr;
0054     }
0055 };
0056 
0057 Preloader::Preloader(QObject *parent)
0058     : QObject(parent)
0059     , d(new PreloaderPrivate)
0060 {
0061     d->q = this;
0062 }
0063 
0064 Preloader::~Preloader()
0065 {
0066     delete d;
0067 }
0068 
0069 void Preloader::preload(const QUrl &url, const QSize &size)
0070 {
0071     LOG("url=" << url);
0072     if (d->mDocument) {
0073         disconnect(d->mDocument.data(), nullptr, this, nullptr);
0074     }
0075 
0076     d->mDocument = DocumentFactory::instance()->load(url);
0077     d->mSize = size;
0078     connect(d->mDocument.data(), &Document::metaInfoUpdated, this, &Preloader::doPreload);
0079 
0080     if (d->mDocument->size().isValid()) {
0081         LOG("size is already available");
0082         doPreload();
0083     }
0084 }
0085 
0086 void Preloader::doPreload()
0087 {
0088     if (!d->mDocument) {
0089         return;
0090     }
0091 
0092     if (d->mDocument->loadingState() == Document::LoadingFailed) {
0093         LOG("loading failed");
0094         d->forgetDocument();
0095         return;
0096     }
0097 
0098     if (!d->mDocument->size().isValid()) {
0099         LOG("size not available yet");
0100         return;
0101     }
0102 
0103     qreal zoom = qMin(d->mSize.width() / qreal(d->mDocument->width()), d->mSize.height() / qreal(d->mDocument->height()));
0104 
0105     if (zoom < Document::maxDownSampledZoom()) {
0106         LOG("preloading down sampled, zoom=" << zoom);
0107         d->mDocument->prepareDownSampledImageForZoom(zoom);
0108     } else {
0109         LOG("preloading full image");
0110         d->mDocument->startLoadingFullImage();
0111     }
0112     d->forgetDocument();
0113 }
0114 
0115 } // namespace
0116 
0117 #include "moc_preloader.cpp"