1 // vim: set tabstop=4 shiftwidth=4 expandtab:
2 /*
3 Gwenview: an image viewer
4 Copyright 2007 Aurélien Gâteau <agateau@kde.org>
5 
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; either version 2
9 of the License, or (at your option) any later version.
10 
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 
20 */
21 // Self
22 #include "documentloadedimpl.h"
23 
24 // Qt
25 #include <QByteArray>
26 #include <QImage>
27 #include <QImageWriter>
28 #include <QTransform>
29 #include <QUrl>
30 
31 // KF
32 
33 // Local
34 #include "documentjob.h"
35 #include "gwenview_lib_debug.h"
36 #include "gwenviewconfig.h"
37 #include "imageutils.h"
38 #include "savejob.h"
39 
40 namespace Gwenview
41 {
42 struct DocumentLoadedImplPrivate {
43     QByteArray mRawData;
44     bool mQuietInit;
45 };
46 
DocumentLoadedImpl(Document * document,const QByteArray & rawData,bool quietInit)47 DocumentLoadedImpl::DocumentLoadedImpl(Document *document, const QByteArray &rawData, bool quietInit)
48     : AbstractDocumentImpl(document)
49     , d(new DocumentLoadedImplPrivate)
50 {
51     if (document->keepRawData()) {
52         d->mRawData = rawData;
53     }
54     d->mQuietInit = quietInit;
55 }
56 
~DocumentLoadedImpl()57 DocumentLoadedImpl::~DocumentLoadedImpl()
58 {
59     delete d;
60 }
61 
init()62 void DocumentLoadedImpl::init()
63 {
64     if (!d->mQuietInit) {
65         Q_EMIT imageRectUpdated(document()->image().rect());
66         Q_EMIT loaded();
67     }
68 }
69 
isEditable() const70 bool DocumentLoadedImpl::isEditable() const
71 {
72     return true;
73 }
74 
loadingState() const75 Document::LoadingState DocumentLoadedImpl::loadingState() const
76 {
77     return Document::Loaded;
78 }
79 
saveInternal(QIODevice * device,const QByteArray & format)80 bool DocumentLoadedImpl::saveInternal(QIODevice *device, const QByteArray &format)
81 {
82     QImageWriter writer(device, format);
83     // If we're saving a non-JPEG image as a JPEG, respect the quality setting
84     if (format == QByteArrayLiteral("jpeg") || format == QByteArrayLiteral("jxl") || format == QByteArrayLiteral("webp") || format == QByteArrayLiteral("avif")
85         || format == QByteArrayLiteral("heif") || format == QByteArrayLiteral("heic")) {
86         writer.setQuality(GwenviewConfig::jPEGQuality());
87     }
88     bool ok = writer.write(document()->image());
89     if (ok) {
90         setDocumentFormat(format);
91     } else {
92         setDocumentErrorString(writer.errorString());
93     }
94     return ok;
95 }
96 
save(const QUrl & url,const QByteArray & format)97 DocumentJob *DocumentLoadedImpl::save(const QUrl &url, const QByteArray &format)
98 {
99     return new SaveJob(this, url, format);
100 }
101 
editor()102 AbstractDocumentEditor *DocumentLoadedImpl::editor()
103 {
104     return this;
105 }
106 
setImage(const QImage & image)107 void DocumentLoadedImpl::setImage(const QImage &image)
108 {
109     setDocumentImage(image);
110     Q_EMIT imageRectUpdated(image.rect());
111 }
112 
applyTransformation(Orientation orientation)113 void DocumentLoadedImpl::applyTransformation(Orientation orientation)
114 {
115     QImage image = document()->image();
116     QTransform matrix = ImageUtils::transformMatrix(orientation);
117     image = image.transformed(matrix);
118     setDocumentImage(image);
119     Q_EMIT imageRectUpdated(image.rect());
120 }
121 
rawData() const122 QByteArray DocumentLoadedImpl::rawData() const
123 {
124     return d->mRawData;
125 }
126 
127 } // namespace
128