1
/* ============================================================
3
* This file is a part of digiKam project
4
* http://www.digikam.org
7
* Description : DImg interface for image editor
9
* Copyright (C) 2004-2012 by Gilles Caulier <caulier dot gilles at gmail dot com>
11
* This program is free software; you can redistribute it
12
* and/or modify it under the terms of the GNU General
13
* Public License as published by the Free Software Foundation;
14
* either version 2, or (at your option)
17
* This program is distributed in the hope that it will be useful,
18
* but WITHOUT ANY WARRANTY; without even the implied warranty of
19
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
* GNU General Public License for more details.
22
* ============================================================ */
34
class EditorCore::Private
43
bool setExifOrientationTag;
48
QString intendedFilePath;
50
QMap<QString, QVariant> ioAttributes;
58
rotatedOrFlipped(false),
60
doSoftProofing(false),
81
QMap<QString, QVariant> ioAttributes(IOFileSettings* const iofileSettings, const QString& givenMimeType) const;
83
void applyBuiltinFilter(const DImgBuiltinFilter& filter, UndoAction* const action);
84
void applyReversibleBuiltinFilter(const DImgBuiltinFilter& filter);
85
void putImageData(uchar* const data, int w, int h, bool sixteenBit);
89
void load(const LoadingDescription& description);
90
void saveAs(const QString& file, IOFileSettings* const iofileSettings,
91
bool setExifOrientationTag, const QString& givenMimeType,
92
const VersionFileOperation& operation, const QString& intendedFilePath);
97
bool rotatedOrFlipped;
116
QWidget* displayingWidget;
118
QList<FileToSave> filesToSave;
119
int currentFileToSave;
122
DImageHistory resolvedInitialHistory;
123
UndoManager* undoMan;
125
ICCSettingsContainer cmSettings;
127
ExposureSettingsContainer* expoSettings;
129
SharedLoadSaveThread* thread;
130
LoadingDescription currentDescription;
131
LoadingDescription nextRawDescription;
133
IccTransform monitorICCtrans;
136
void EditorCore::Private::putImageData(uchar* const data, int w, int h, bool sixteenBit)
140
kWarning() << "d->image is NULL";
146
kWarning() << "New image is NULL";
150
if (w == -1 && h == -1)
158
// New image size == original size
163
image.putImageData(w, h, sixteenBit, image.hasAlpha(), data);
166
void EditorCore::Private::resetValues()
169
currentDescription = LoadingDescription();
181
resolvedInitialHistory = DImageHistory();
185
void EditorCore::Private::saveNext()
187
if (filesToSave.isEmpty() || currentFileToSave >= filesToSave.size())
192
FileToSave& file = filesToSave[currentFileToSave];
193
kDebug() << "Saving file" << file.filePath << "at" << file.historyStep;
195
if (file.historyStep != -1)
197
// intermediate. Need to get data from undo manager
198
int currentStep = EditorCore::defaultInstance()->getImageHistory().size() - 1;
199
//kDebug() << "Requesting from undo manager data" << currentStep - file.historyStep << "steps back";
200
undoMan->putImageDataAndHistory(&file.image, currentStep - file.historyStep);
203
QMap<QString, QVariant>::const_iterator it;
205
for (it = file.ioAttributes.constBegin(); it != file.ioAttributes.constEnd(); ++it)
207
file.image.setAttribute(it.key(), it.value());
210
file.image.prepareMetadataToSave(file.intendedFilePath, file.mimeType, file.setExifOrientationTag);
211
//kDebug() << "Adjusting image" << file.mimeType << file.fileName << file.setExifOrientationTag << file.ioAttributes
212
// << "image:" << file.image.size() << file.image.isNull();
214
thread->save(file.image, file.filePath, file.mimeType);
217
void EditorCore::Private::applyReversibleBuiltinFilter(const DImgBuiltinFilter& filter)
219
applyBuiltinFilter(filter, new UndoActionReversible(EditorCore::defaultInstance(), filter));
222
void EditorCore::Private::applyBuiltinFilter(const DImgBuiltinFilter& filter, UndoAction* const action)
224
undoMan->addAction(action);
227
image.addFilterAction(filter.filterAction());
229
// many operations change the image size
230
origWidth = image.width();
231
origHeight = image.height();
233
EditorCore::defaultInstance()->setModified();
236
QMap<QString, QVariant> EditorCore::Private::ioAttributes(IOFileSettings* const iofileSettings,
237
const QString& mimeType) const
239
QMap<QString, QVariant> attributes;
242
if (mimeType.toUpper() == QString("JPG") || mimeType.toUpper() == QString("JPEG") ||
243
mimeType.toUpper() == QString("JPE"))
245
attributes.insert("quality", iofileSettings->JPEGCompression);
246
attributes.insert("subsampling", iofileSettings->JPEGSubSampling);
250
if (mimeType.toUpper() == QString("PNG"))
252
attributes.insert("quality", iofileSettings->PNGCompression);
256
if (mimeType.toUpper() == QString("TIFF") || mimeType.toUpper() == QString("TIF"))
258
attributes.insert("compress", iofileSettings->TIFFCompression);
261
// JPEG 2000 file format.
262
if (mimeType.toUpper() == QString("JP2") || mimeType.toUpper() == QString("JPX") ||
263
mimeType.toUpper() == QString("JPC") || mimeType.toUpper() == QString("PGX") ||
264
mimeType.toUpper() == QString("J2K"))
266
if (iofileSettings->JPEG2000LossLess)
268
attributes.insert("quality", 100); // LossLess compression
272
attributes.insert("quality", iofileSettings->JPEG2000Compression);
277
if (mimeType.toUpper() == QString("PGF"))
279
if (iofileSettings->PGFLossLess)
281
attributes.insert("quality", 0); // LossLess compression
285
attributes.insert("quality", iofileSettings->PGFCompression);
292
void EditorCore::Private::saveAs(const QString& filePath, IOFileSettings* const iofileSettings,
293
bool setExifOrientationTag, const QString& givenMimeType,
294
const VersionFileOperation& op, const QString& intendedFilePath)
296
// No need to toggle off undo, redo or save action during saving using
297
// signalUndoStateChanged(), this is will done by GUI implementation directly.
299
EditorCore::defaultInstance()->emit signalSavingStarted(filePath);
302
currentFileToSave = 0;
304
QString mimeType = givenMimeType;
306
// This is possibly empty
307
if (mimeType.isEmpty())
309
mimeType = EditorCore::defaultInstance()->getImageFormat();
312
if (op.tasks & VersionFileOperation::MoveToIntermediate ||
313
op.tasks & VersionFileOperation::SaveAndDelete)
315
// The current file will stored away at a different name. Adjust history.
316
image.getImageHistory().moveCurrentReferredImage(op.intermediateForLoadedFile.path,
317
op.intermediateForLoadedFile.fileName);
320
if (op.tasks & VersionFileOperation::Replace)
322
// The current file will be replaced. Remove hint at file path (file path will be a different image)
323
image.getImageHistory().purgePathFromReferredImages(op.saveFile.path, op.saveFile.fileName);
326
QMap<int, VersionFileInfo>::const_iterator it;
328
for (it = op.intermediates.begin(); it != op.intermediates.end(); ++it)
331
file.fileName = it.value().fileName;
332
file.filePath = it.value().filePath();
333
file.intendedFilePath = file.filePath;
334
file.mimeType = it.value().format;
335
file.ioAttributes = ioAttributes(iofileSettings, it.value().format);
336
file.historyStep = it.key();
337
file.setExifOrientationTag = setExifOrientationTag;
338
file.image = image.copyMetaData();
340
kDebug() << "Saving intermediate at history step" << file.historyStep
341
<< "to" << file.filePath << "(" << file.mimeType << ")";
344
// This shall be the last in the list. If not, adjust slotImageSaved
346
primary.fileName = op.saveFile.fileName;
347
primary.filePath = filePath; // can be temporary file path
348
primary.intendedFilePath = intendedFilePath;
349
primary.mimeType = mimeType;
350
primary.ioAttributes = ioAttributes(iofileSettings, mimeType);
351
primary.historyStep = -1; // special value
352
primary.setExifOrientationTag = setExifOrientationTag;
353
primary.image = image;
354
filesToSave << primary;
356
kDebug() << "Saving to :" << primary.filePath << "(" << primary.mimeType << ")";
361
void EditorCore::Private::loadCurrent()
363
thread->load(currentDescription,
364
SharedLoadSaveThread::AccessModeReadWrite,
365
SharedLoadSaveThread::LoadingPolicyFirstRemovePrevious);
367
EditorCore::defaultInstance()->emit signalLoadingStarted(currentDescription.filePath);
370
void EditorCore::Private::load(const LoadingDescription& description)
372
if (EditorToolIface::editorToolIface())
374
EditorToolIface::editorToolIface()->unLoadTool();
377
if (description != currentDescription)
380
currentDescription = description;
385
EditorCore::defaultInstance()->emit signalLoadingStarted(currentDescription.filePath);
386
EditorCore::defaultInstance()->emit signalImageLoaded(currentDescription.filePath, true);
390
} // namespace Digikam