File indexing completed on 2024-05-19 04:29:14

0001 /*
0002  *  SPDX-FileCopyrightText: 2017 Dmitry Kazakov <dimula73@gmail.com>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #include "KisImportExportUtils.h"
0008 
0009 #include <KoColorSpaceRegistry.h>
0010 #include <KoColorSpace.h>
0011 #include <KoColorProfile.h>
0012 #include "kis_image.h"
0013 #include "KisImportUserFeedbackInterface.h"
0014 #include "dialogs/KisColorSpaceConversionDialog.h"
0015 
0016 namespace KritaUtils {
0017 
0018 KisImportExportErrorCode workaroundUnsuitableImageColorSpace(KisImageSP image,
0019                                                              KisImportUserFeedbackInterface *feedbackInterface,
0020                                                              KisImageBarrierLock &lock)
0021 {
0022     const KoColorSpace *replacementColorSpace = 0;
0023     KoColorConversionTransformation::Intent replacementColorSpaceIntent = KoColorConversionTransformation::internalRenderingIntent();
0024     KoColorConversionTransformation::ConversionFlags replacementColorSpaceConversionFlags = KoColorConversionTransformation::internalConversionFlags();
0025 
0026     const KoColorSpace *colorSpace = image->colorSpace();
0027     const KoColorProfile *profile = colorSpace->profile();
0028 
0029     if (profile && !profile->isSuitableForOutput()) {
0030         /// The profile has no reverse mapping into for the descriped color space,
0031         /// so we cannot use it in Krita. We need to ask the user to convert the image
0032         /// right on loading
0033 
0034         KIS_SAFE_ASSERT_RECOVER_NOOP(feedbackInterface);
0035         if (feedbackInterface) {
0036             KisImportUserFeedbackInterface::Result result =
0037                 feedbackInterface->askUser([&] (QWidget *parent) {
0038 
0039                     KisColorSpaceConversionDialog * dlgColorSpaceConversion = new KisColorSpaceConversionDialog(parent, "ColorSpaceConversion");
0040                     Q_CHECK_PTR(dlgColorSpaceConversion);
0041 
0042                     const KoColorSpace* fallbackColorSpace =
0043                         KoColorSpaceRegistry::instance()->colorSpace(
0044                             colorSpace->colorModelId().id(),
0045                             colorSpace->colorDepthId().id(),
0046                             nullptr);
0047 
0048                     dlgColorSpaceConversion->setCaption(i18n("Convert image color space on import"));
0049                     dlgColorSpaceConversion->m_page->lblHeadlineWarning->setText(
0050                         i18nc("the argument is the ICC profile name",
0051                               "The image has a profile attached that Krita cannot edit images "
0052                               "in (\"%1\"), please select a space to convert to for editing: \n"
0053                               , profile->name()));
0054                     dlgColorSpaceConversion->m_page->lblHeadlineWarning->setVisible(true);
0055 
0056                     dlgColorSpaceConversion->setInitialColorSpace(fallbackColorSpace, 0);
0057 
0058                     if (dlgColorSpaceConversion->exec() == QDialog::Accepted) {
0059 
0060                         replacementColorSpace = dlgColorSpaceConversion->colorSpace();
0061                         replacementColorSpaceIntent = dlgColorSpaceConversion->conversionIntent();
0062                         replacementColorSpaceConversionFlags= dlgColorSpaceConversion->conversionFlags();
0063                     } else {
0064                         return false;
0065                     }
0066 
0067                     return true;
0068                 });
0069 
0070             if (result == KisImportUserFeedbackInterface::SuppressedByBatchMode) {
0071                 return ImportExportCodes::FormatColorSpaceUnsupported;
0072             } else if (result == KisImportUserFeedbackInterface::UserCancelled) {
0073                 return ImportExportCodes::Cancelled;
0074             }
0075         }
0076     }
0077 
0078     if (replacementColorSpace) {
0079         /**
0080          * Here is an extremely tricky part! First we start the conversion
0081          * stroke, and only **after that** we unlock the image. The point is
0082          * that KisDelayedUpdateNodeInterface-based nodes are forbidden to
0083          * start their update jobs while the image is locked, so this
0084          * guarantees that no stroke will be started before we actually convert
0085          * the image into something usable
0086          */
0087         image->convertImageColorSpace(replacementColorSpace,
0088                                         replacementColorSpaceIntent,
0089                                         replacementColorSpaceConversionFlags);
0090         lock.unlock();
0091         image->waitForDone();
0092     }
0093 
0094     return ImportExportCodes::OK;
0095 }
0096 
0097 }