1 | /* -*- C++ -*- |
2 | This file is part of ThreadWeaver. |
3 | |
4 | SPDX-FileCopyrightText: 2005-2014 Mirko Boehm <mirko@kde.org> |
5 | |
6 | SPDX-License-Identifier: LGPL-2.0-or-later |
7 | */ |
8 | |
9 | #include <QBuffer> |
10 | #include <QFile> |
11 | #include <QFileInfo> |
12 | #include <QImageReader> |
13 | #include <QLocale> |
14 | #include <QtDebug> |
15 | |
16 | #include <ThreadWeaver/Exception> |
17 | #include <ThreadWeaver/ThreadWeaver> |
18 | |
19 | #include "Image.h" |
20 | #include "Model.h" |
21 | |
22 | // const int Image::ThumbHeight = 75; |
23 | // const int Image::ThumbWidth = 120; |
24 | const int Image::ThumbHeight = 60; |
25 | const int Image::ThumbWidth = 80; |
26 | QReadWriteLock Image::Lock; |
27 | int Image::ProcessingOrder; |
28 | |
29 | Image::Image(const QString inputFileName, const QString outputFileName, Model *model, int id) |
30 | : m_inputFileName(inputFileName) |
31 | , m_outputFileName(outputFileName) |
32 | , m_model(model) |
33 | , m_id(id) |
34 | { |
35 | } |
36 | |
37 | Progress Image::progress() const |
38 | { |
39 | return qMakePair(value1: m_progress.loadRelaxed(), value2: Step_NumberOfSteps); |
40 | } |
41 | |
42 | QString Image::description() const |
43 | { |
44 | QReadLocker l(&Lock); |
45 | return m_description; |
46 | } |
47 | |
48 | QString Image::details() const |
49 | { |
50 | QReadLocker l(&Lock); |
51 | return m_details; |
52 | } |
53 | |
54 | QString Image::details2() const |
55 | { |
56 | QReadLocker l(&Lock); |
57 | return m_details2; |
58 | } |
59 | |
60 | int Image::processingOrder() const |
61 | { |
62 | return m_processingOrder.loadAcquire(); |
63 | } |
64 | |
65 | const QString Image::inputFileName() const |
66 | { |
67 | return m_inputFileName; |
68 | } |
69 | |
70 | const QString Image::outputFileName() const |
71 | { |
72 | return m_outputFileName; |
73 | } |
74 | |
75 | QImage Image::thumbNail() const |
76 | { |
77 | QReadLocker r(&Lock); |
78 | return m_thumbnail; |
79 | } |
80 | |
81 | void Image::loadFile() |
82 | { |
83 | m_processingOrder.storeRelease(newValue: ProcessingOrder++); |
84 | QFile file(m_inputFileName); |
85 | if (!file.open(flags: QIODevice::ReadOnly)) { |
86 | error(step: Step_LoadFile, message: tr(sourceText: "Unable to load input file!" )); |
87 | } |
88 | m_imageData = file.readAll(); |
89 | QFileInfo fi(file); |
90 | QLocale locale; |
91 | QString details2 = tr(sourceText: "%1kB" ).arg(a: locale.toString(i: fi.size() / 1024)); |
92 | { |
93 | QWriteLocker l(&Lock); |
94 | m_description = fi.fileName(); |
95 | m_details2 = details2; |
96 | } |
97 | announceProgress(step: Step_LoadFile); |
98 | } |
99 | |
100 | void Image::loadImage() |
101 | { |
102 | m_processingOrder.storeRelease(newValue: ProcessingOrder++); |
103 | QBuffer in(&m_imageData); |
104 | in.open(openMode: QIODevice::ReadOnly); |
105 | QImageReader reader(&in); |
106 | m_image = reader.read(); |
107 | m_imageData.clear(); |
108 | if (m_image.isNull()) { |
109 | QWriteLocker l(&Lock); |
110 | m_details = tr(sourceText: "%1!" ).arg(a: reader.errorString()); |
111 | error(step: Step_LoadImage, message: m_details); |
112 | } |
113 | QString details = tr(sourceText: "%1x%2 pixels" ).arg(a: m_image.width()).arg(a: m_image.height()); |
114 | { |
115 | QWriteLocker l(&Lock); |
116 | m_details = details; |
117 | } |
118 | announceProgress(step: Step_LoadImage); |
119 | } |
120 | |
121 | void Image::computeThumbNail() |
122 | { |
123 | m_processingOrder.storeRelease(newValue: ProcessingOrder++); |
124 | QImage thumb = m_image.scaled(w: ThumbWidth, h: ThumbHeight, aspectMode: Qt::KeepAspectRatioByExpanding, mode: Qt::SmoothTransformation); |
125 | if (thumb.isNull()) { |
126 | error(step: Step_ComputeThumbNail, message: tr(sourceText: "Unable to compute thumbnail!" )); |
127 | } |
128 | { // thumb is implicitly shared, no copy: |
129 | QWriteLocker l(&Lock); |
130 | m_thumbnail = thumb; |
131 | } |
132 | |
133 | m_image = QImage(); |
134 | announceProgress(step: Step_ComputeThumbNail); |
135 | } |
136 | |
137 | void Image::saveThumbNail() |
138 | { |
139 | QImage thumb; |
140 | { |
141 | QReadLocker r(&Lock); |
142 | thumb = m_thumbnail; |
143 | } |
144 | if (!thumb.save(fileName: m_outputFileName)) { |
145 | error(step: Step_SaveThumbNail, message: tr(sourceText: "Unable to save output file!" )); |
146 | } |
147 | announceProgress(step: Step_SaveThumbNail); |
148 | } |
149 | |
150 | void Image::announceProgress(Steps step) |
151 | { |
152 | m_progress.storeRelease(newValue: step); |
153 | if (m_model) { |
154 | m_model->progressChanged(); |
155 | m_model->elementChanged(id: m_id); |
156 | } |
157 | } |
158 | |
159 | void Image::error(Image::Steps step, const QString &message) |
160 | { |
161 | m_failedStep.storeRelaxed(newValue: step); |
162 | announceProgress(step: Step_Complete); |
163 | throw ThreadWeaver::JobFailed(message); |
164 | } |
165 | |