1 /*
2 Scan Tailor - Interactive post-processing tool for scanned pages.
3 Copyright (C) Joseph Artsimovich <joseph.artsimovich@gmail.com>
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include "Settings.h"
20 #include "../../Utils.h"
21 #include "AbstractRelinker.h"
22 #include "FillColorProperty.h"
23 #include "RelinkablePath.h"
24
25 namespace output {
Settings()26 Settings::Settings()
27 : m_defaultPictureZoneProps(initialPictureZoneProps()), m_defaultFillZoneProps(initialFillZoneProps()) {}
28
29 Settings::~Settings() = default;
30
clear()31 void Settings::clear() {
32 const QMutexLocker locker(&m_mutex);
33
34 initialPictureZoneProps().swap(m_defaultPictureZoneProps);
35 initialFillZoneProps().swap(m_defaultFillZoneProps);
36 m_perPageParams.clear();
37 m_perPageOutputParams.clear();
38 m_perPagePictureZones.clear();
39 m_perPageFillZones.clear();
40 m_perPageOutputProcessingParams.clear();
41 }
42
performRelinking(const AbstractRelinker & relinker)43 void Settings::performRelinking(const AbstractRelinker& relinker) {
44 const QMutexLocker locker(&m_mutex);
45
46 PerPageParams new_params;
47 PerPageOutputParams new_output_params;
48 PerPageZones new_picture_zones;
49 PerPageZones new_fill_zones;
50 PerPageOutputProcessingParams new_output_processing_params;
51
52 for (const PerPageParams::value_type& kv : m_perPageParams) {
53 const RelinkablePath old_path(kv.first.imageId().filePath(), RelinkablePath::File);
54 PageId new_page_id(kv.first);
55 new_page_id.imageId().setFilePath(relinker.substitutionPathFor(old_path));
56 new_params.insert(PerPageParams::value_type(new_page_id, kv.second));
57 }
58
59 for (const PerPageOutputParams::value_type& kv : m_perPageOutputParams) {
60 const RelinkablePath old_path(kv.first.imageId().filePath(), RelinkablePath::File);
61 PageId new_page_id(kv.first);
62 new_page_id.imageId().setFilePath(relinker.substitutionPathFor(old_path));
63 new_output_params.insert(PerPageOutputParams::value_type(new_page_id, kv.second));
64 }
65
66 for (const PerPageZones::value_type& kv : m_perPagePictureZones) {
67 const RelinkablePath old_path(kv.first.imageId().filePath(), RelinkablePath::File);
68 PageId new_page_id(kv.first);
69 new_page_id.imageId().setFilePath(relinker.substitutionPathFor(old_path));
70 new_picture_zones.insert(PerPageZones::value_type(new_page_id, kv.second));
71 }
72
73 for (const PerPageZones::value_type& kv : m_perPageFillZones) {
74 const RelinkablePath old_path(kv.first.imageId().filePath(), RelinkablePath::File);
75 PageId new_page_id(kv.first);
76 new_page_id.imageId().setFilePath(relinker.substitutionPathFor(old_path));
77 new_fill_zones.insert(PerPageZones::value_type(new_page_id, kv.second));
78 }
79
80 for (const PerPageOutputProcessingParams::value_type& kv : m_perPageOutputProcessingParams) {
81 const RelinkablePath old_path(kv.first.imageId().filePath(), RelinkablePath::File);
82 PageId new_page_id(kv.first);
83 new_page_id.imageId().setFilePath(relinker.substitutionPathFor(old_path));
84 new_output_processing_params.insert(PerPageOutputProcessingParams::value_type(new_page_id, kv.second));
85 }
86
87 m_perPageParams.swap(new_params);
88 m_perPageOutputParams.swap(new_output_params);
89 m_perPagePictureZones.swap(new_picture_zones);
90 m_perPageFillZones.swap(new_fill_zones);
91 m_perPageOutputProcessingParams.swap(new_output_processing_params);
92 } // Settings::performRelinking
93
getParams(const PageId & page_id) const94 Params Settings::getParams(const PageId& page_id) const {
95 const QMutexLocker locker(&m_mutex);
96
97 const auto it(m_perPageParams.find(page_id));
98 if (it != m_perPageParams.end()) {
99 return it->second;
100 } else {
101 return Params();
102 }
103 }
104
setParams(const PageId & page_id,const Params & params)105 void Settings::setParams(const PageId& page_id, const Params& params) {
106 const QMutexLocker locker(&m_mutex);
107 Utils::mapSetValue(m_perPageParams, page_id, params);
108 }
109
setColorParams(const PageId & page_id,const ColorParams & prms)110 void Settings::setColorParams(const PageId& page_id, const ColorParams& prms) {
111 const QMutexLocker locker(&m_mutex);
112
113 const auto it(m_perPageParams.find(page_id));
114 if (it == m_perPageParams.end()) {
115 Params params;
116 params.setColorParams(prms);
117 m_perPageParams.insert(it, PerPageParams::value_type(page_id, params));
118 } else {
119 it->second.setColorParams(prms);
120 }
121 }
122
setPictureShapeOptions(const PageId & page_id,PictureShapeOptions picture_shape_options)123 void Settings::setPictureShapeOptions(const PageId& page_id, PictureShapeOptions picture_shape_options) {
124 const QMutexLocker locker(&m_mutex);
125
126 const auto it(m_perPageParams.find(page_id));
127 if (it == m_perPageParams.end()) {
128 Params params;
129 params.setPictureShapeOptions(picture_shape_options);
130 m_perPageParams.insert(it, PerPageParams::value_type(page_id, params));
131 } else {
132 it->second.setPictureShapeOptions(picture_shape_options);
133 }
134 }
135
setDpi(const PageId & page_id,const Dpi & dpi)136 void Settings::setDpi(const PageId& page_id, const Dpi& dpi) {
137 const QMutexLocker locker(&m_mutex);
138
139 const auto it(m_perPageParams.find(page_id));
140 if (it == m_perPageParams.end()) {
141 Params params;
142 params.setOutputDpi(dpi);
143 m_perPageParams.insert(it, PerPageParams::value_type(page_id, params));
144 } else {
145 it->second.setOutputDpi(dpi);
146 }
147 }
148
setDewarpingOptions(const PageId & page_id,const DewarpingOptions & opt)149 void Settings::setDewarpingOptions(const PageId& page_id, const DewarpingOptions& opt) {
150 const QMutexLocker locker(&m_mutex);
151
152 const auto it(m_perPageParams.find(page_id));
153 if (it == m_perPageParams.end()) {
154 Params params;
155 params.setDewarpingOptions(opt);
156 m_perPageParams.insert(it, PerPageParams::value_type(page_id, params));
157 } else {
158 it->second.setDewarpingOptions(opt);
159 }
160 }
161
setSplittingOptions(const PageId & page_id,const SplittingOptions & opt)162 void Settings::setSplittingOptions(const PageId& page_id, const SplittingOptions& opt) {
163 const QMutexLocker locker(&m_mutex);
164
165 const auto it(m_perPageParams.find(page_id));
166 if (it == m_perPageParams.end()) {
167 Params params;
168 params.setSplittingOptions(opt);
169 m_perPageParams.insert(it, PerPageParams::value_type(page_id, params));
170 } else {
171 it->second.setSplittingOptions(opt);
172 }
173 }
174
setDistortionModel(const PageId & page_id,const dewarping::DistortionModel & model)175 void Settings::setDistortionModel(const PageId& page_id, const dewarping::DistortionModel& model) {
176 const QMutexLocker locker(&m_mutex);
177
178 const auto it(m_perPageParams.find(page_id));
179 if (it == m_perPageParams.end()) {
180 Params params;
181 params.setDistortionModel(model);
182 m_perPageParams.insert(it, PerPageParams::value_type(page_id, params));
183 } else {
184 it->second.setDistortionModel(model);
185 }
186 }
187
setDepthPerception(const PageId & page_id,const DepthPerception & depth_perception)188 void Settings::setDepthPerception(const PageId& page_id, const DepthPerception& depth_perception) {
189 const QMutexLocker locker(&m_mutex);
190
191 const auto it(m_perPageParams.find(page_id));
192 if (it == m_perPageParams.end()) {
193 Params params;
194 params.setDepthPerception(depth_perception);
195 m_perPageParams.insert(it, PerPageParams::value_type(page_id, params));
196 } else {
197 it->second.setDepthPerception(depth_perception);
198 }
199 }
200
setDespeckleLevel(const PageId & page_id,double level)201 void Settings::setDespeckleLevel(const PageId& page_id, double level) {
202 const QMutexLocker locker(&m_mutex);
203
204 const auto it(m_perPageParams.find(page_id));
205 if (it == m_perPageParams.end()) {
206 Params params;
207 params.setDespeckleLevel(level);
208 m_perPageParams.insert(it, PerPageParams::value_type(page_id, params));
209 } else {
210 it->second.setDespeckleLevel(level);
211 }
212 }
213
getOutputParams(const PageId & page_id) const214 std::unique_ptr<OutputParams> Settings::getOutputParams(const PageId& page_id) const {
215 const QMutexLocker locker(&m_mutex);
216
217 const auto it(m_perPageOutputParams.find(page_id));
218 if (it != m_perPageOutputParams.end()) {
219 return std::make_unique<OutputParams>(it->second);
220 } else {
221 return nullptr;
222 }
223 }
224
removeOutputParams(const PageId & page_id)225 void Settings::removeOutputParams(const PageId& page_id) {
226 const QMutexLocker locker(&m_mutex);
227 m_perPageOutputParams.erase(page_id);
228 }
229
setOutputParams(const PageId & page_id,const OutputParams & params)230 void Settings::setOutputParams(const PageId& page_id, const OutputParams& params) {
231 const QMutexLocker locker(&m_mutex);
232 Utils::mapSetValue(m_perPageOutputParams, page_id, params);
233 }
234
pictureZonesForPage(const PageId & page_id) const235 ZoneSet Settings::pictureZonesForPage(const PageId& page_id) const {
236 const QMutexLocker locker(&m_mutex);
237
238 const auto it(m_perPagePictureZones.find(page_id));
239 if (it != m_perPagePictureZones.end()) {
240 return it->second;
241 } else {
242 return ZoneSet();
243 }
244 }
245
fillZonesForPage(const PageId & page_id) const246 ZoneSet Settings::fillZonesForPage(const PageId& page_id) const {
247 const QMutexLocker locker(&m_mutex);
248
249 const auto it(m_perPageFillZones.find(page_id));
250 if (it != m_perPageFillZones.end()) {
251 return it->second;
252 } else {
253 return ZoneSet();
254 }
255 }
256
setPictureZones(const PageId & page_id,const ZoneSet & zones)257 void Settings::setPictureZones(const PageId& page_id, const ZoneSet& zones) {
258 const QMutexLocker locker(&m_mutex);
259 Utils::mapSetValue(m_perPagePictureZones, page_id, zones);
260 }
261
setFillZones(const PageId & page_id,const ZoneSet & zones)262 void Settings::setFillZones(const PageId& page_id, const ZoneSet& zones) {
263 const QMutexLocker locker(&m_mutex);
264 Utils::mapSetValue(m_perPageFillZones, page_id, zones);
265 }
266
defaultPictureZoneProperties() const267 PropertySet Settings::defaultPictureZoneProperties() const {
268 const QMutexLocker locker(&m_mutex);
269
270 return m_defaultPictureZoneProps;
271 }
272
defaultFillZoneProperties() const273 PropertySet Settings::defaultFillZoneProperties() const {
274 const QMutexLocker locker(&m_mutex);
275
276 return m_defaultFillZoneProps;
277 }
278
setDefaultPictureZoneProperties(const PropertySet & props)279 void Settings::setDefaultPictureZoneProperties(const PropertySet& props) {
280 const QMutexLocker locker(&m_mutex);
281 m_defaultPictureZoneProps = props;
282 }
283
setDefaultFillZoneProperties(const PropertySet & props)284 void Settings::setDefaultFillZoneProperties(const PropertySet& props) {
285 const QMutexLocker locker(&m_mutex);
286 m_defaultFillZoneProps = props;
287 }
288
initialPictureZoneProps()289 PropertySet Settings::initialPictureZoneProps() {
290 PropertySet props;
291 props.locateOrCreate<PictureLayerProperty>()->setLayer(PictureLayerProperty::PAINTER2);
292
293 return props;
294 }
295
initialFillZoneProps()296 PropertySet Settings::initialFillZoneProps() {
297 PropertySet props;
298 props.locateOrCreate<FillColorProperty>()->setColor(Qt::white);
299
300 return props;
301 }
302
getOutputProcessingParams(const PageId & page_id) const303 OutputProcessingParams Settings::getOutputProcessingParams(const PageId& page_id) const {
304 const QMutexLocker locker(&m_mutex);
305
306 const auto it(m_perPageOutputProcessingParams.find(page_id));
307 if (it != m_perPageOutputProcessingParams.end()) {
308 return it->second;
309 } else {
310 return OutputProcessingParams();
311 }
312 }
313
setOutputProcessingParams(const PageId & page_id,const OutputProcessingParams & output_processing_params)314 void Settings::setOutputProcessingParams(const PageId& page_id,
315 const OutputProcessingParams& output_processing_params) {
316 const QMutexLocker locker(&m_mutex);
317 Utils::mapSetValue(m_perPageOutputProcessingParams, page_id, output_processing_params);
318 }
319
isParamsNull(const PageId & page_id) const320 bool Settings::isParamsNull(const PageId& page_id) const {
321 const QMutexLocker locker(&m_mutex);
322
323 return m_perPageParams.find(page_id) == m_perPageParams.end();
324 }
325
setBlackOnWhite(const PageId & page_id,const bool black_on_white)326 void Settings::setBlackOnWhite(const PageId& page_id, const bool black_on_white) {
327 const QMutexLocker locker(&m_mutex);
328
329 const auto it(m_perPageParams.find(page_id));
330 if (it == m_perPageParams.end()) {
331 Params params;
332 params.setBlackOnWhite(black_on_white);
333 m_perPageParams.insert(it, PerPageParams::value_type(page_id, params));
334 } else {
335 it->second.setBlackOnWhite(black_on_white);
336 }
337 }
338 } // namespace output