Krita Source Code Documentation
Loading...
Searching...
No Matches
EXRConverter Class Reference

#include <exr_converter.h>

+ Inheritance diagram for EXRConverter:

Classes

struct  Private
 

Public Slots

virtual void cancel ()
 

Public Member Functions

KisImportExportErrorCode buildFile (const QString &filename, KisGroupLayerSP layer, bool flatten=false)
 
KisImportExportErrorCode buildFile (const QString &filename, KisPaintLayerSP layer)
 
KisImportExportErrorCode buildImage (const QString &filename)
 
QString errorMessage () const
 
 EXRConverter (KisDocument *doc, bool showNotifications)
 
KisImageSP image ()
 
 ~EXRConverter () override
 

Private Member Functions

KisImportExportErrorCode decode (const QString &filename)
 

Private Attributes

const QScopedPointer< Privated
 

Detailed Description

Definition at line 19 of file exr_converter.h.

Constructor & Destructor Documentation

◆ EXRConverter()

EXRConverter::EXRConverter ( KisDocument * doc,
bool showNotifications )

Definition at line 159 of file exr_converter.cc.

160 : d(new Private)
161{
162 d->doc = doc;
163 d->showNotifications = showNotifications;
164
165 // Set thread count for IlmImf library
166 Imf::setGlobalThreadCount(QThread::idealThreadCount());
167 dbgFile << "EXR Threadcount was set to: " << QThread::idealThreadCount();
168}
const QScopedPointer< Private > d
#define dbgFile
Definition kis_debug.h:53

References d, and dbgFile.

◆ ~EXRConverter()

EXRConverter::~EXRConverter ( )
override

Definition at line 170 of file exr_converter.cc.

171{
172}

Member Function Documentation

◆ buildFile() [1/2]

KisImportExportErrorCode EXRConverter::buildFile ( const QString & filename,
KisGroupLayerSP layer,
bool flatten = false )

Definition at line 1398 of file exr_converter.cc.

1399{
1401
1402 KisImageSP image = layer->image();
1404
1405 qint32 height = image->height();
1406 qint32 width = image->width();
1407 Imf::Header header(width, height);
1408
1409 if (flatten) {
1411 KisPaintLayerSP l = new KisPaintLayer(image, "projection", OPACITY_OPAQUE_U8, pd);
1412 return buildFile(filename, l);
1413 }
1414 else {
1415 QList<ExrPaintLayerSaveInfo> informationObjects;
1416 d->recBuildPaintLayerSaveInfo(informationObjects, "", layer);
1417
1418 if(informationObjects.isEmpty()) {
1420 }
1421 d->makeLayerNamesUnique(informationObjects);
1422
1423 QByteArray extraLayersInfo = d->fetchExtraLayersInfo(informationObjects).toUtf8();
1424 if (!extraLayersInfo.isNull()) {
1425 header.insert(EXR_KRITA_LAYERS, Imf::StringAttribute(extraLayersInfo.constData()));
1426 }
1427 dbgFile << informationObjects.size() << " layers to save";
1428 Q_FOREACH (const ExrPaintLayerSaveInfo& info, informationObjects) {
1429 if (info.pixelType < Imf::NUM_PIXELTYPES) {
1430 Q_FOREACH (const QString& channel, info.channels) {
1431 dbgFile << channel << " " << info.pixelType;
1432 header.channels().insert(channel.toUtf8().data(), Imf::Channel(info.pixelType));
1433 }
1434 }
1435 }
1436
1437 // Open file for writing
1438 try {
1439 Imf::OutputFile file(filename.toUtf8(), header);
1440 encodeData(file, informationObjects, width, height);
1441 return ImportExportCodes::OK;
1442 } catch(std::exception &e) {
1443 dbgFile << "Exception while writing to exr file: " << e.what();
1444 if (!KisImportExportAdditionalChecks::isFileWritable(filename.toUtf8())) {
1446 }
1448 }
1449
1450 }
1451}
const quint8 OPACITY_OPAQUE_U8
KisImportExportErrorCode buildFile(const QString &filename, KisPaintLayerSP layer)
KisImageSP image()
KisPaintDeviceSP projection() const
qint32 width() const
qint32 height() const
void encodeData(Imf::OutputFile &file, const QList< ExrPaintLayerSaveInfo > &informationObjects, int width, int height)
const char EXR_KRITA_LAYERS[]
#define KIS_ASSERT_RECOVER_RETURN_VALUE(cond, val)
Definition kis_assert.h:85
QList< QString > channels
Imf::PixelType pixelType
KisImageWSP image

References buildFile(), ExrPaintLayerSaveInfo::channels, d, dbgFile, encodeData(), ImportExportCodes::ErrorWhileWriting, EXR_KRITA_LAYERS, ImportExportCodes::FormatColorSpaceUnsupported, KisImage::height(), KisBaseNode::image, image(), ImportExportCodes::InternalError, KisImportExportAdditionalChecks::isFileWritable(), KIS_ASSERT_RECOVER_RETURN_VALUE, ImportExportCodes::NoAccessToWrite, ImportExportCodes::OK, OPACITY_OPAQUE_U8, ExrPaintLayerSaveInfo::pixelType, KisImage::projection(), and KisImage::width().

◆ buildFile() [2/2]

KisImportExportErrorCode EXRConverter::buildFile ( const QString & filename,
KisPaintLayerSP layer )

Definition at line 1131 of file exr_converter.cc.

1132{
1134
1135 KisImageSP image = layer->image();
1137
1138
1139 // Make the header
1140 qint32 height = image->height();
1141 qint32 width = image->width();
1142 Imf::Header header(width, height);
1143
1145 info.layer = layer;
1146 info.layerDevice = wrapLayerDevice(layer->paintDevice());
1147 Imf::PixelType pixelType = Imf::NUM_PIXELTYPES;
1149 pixelType = Imf::HALF;
1150 }
1152 pixelType = Imf::FLOAT;
1153 }
1154
1155 info.pixelType = pixelType;
1156
1158 header.channels().insert("R", Imf::Channel(pixelType));
1159 header.channels().insert("G", Imf::Channel(pixelType));
1160 header.channels().insert("B", Imf::Channel(pixelType));
1161 header.channels().insert("A", Imf::Channel(pixelType));
1162
1163 info.channels.push_back("R");
1164 info.channels.push_back("G");
1165 info.channels.push_back("B");
1166 info.channels.push_back("A");
1167 } else if (info.layerDevice->colorSpace()->colorModelId() == GrayAColorModelID) {
1168 header.channels().insert("Y", Imf::Channel(pixelType));
1169 header.channels().insert("A", Imf::Channel(pixelType));
1170
1171 info.channels.push_back("Y");
1172 info.channels.push_back("A");
1173 } else if (info.layerDevice->colorSpace()->colorModelId() == XYZAColorModelID) {
1174 header.channels().insert("X", Imf::Channel(pixelType));
1175 header.channels().insert("Y", Imf::Channel(pixelType));
1176 header.channels().insert("Z", Imf::Channel(pixelType));
1177 header.channels().insert("A", Imf::Channel(pixelType));
1178
1179 info.channels.push_back("X");
1180 info.channels.push_back("Y");
1181 info.channels.push_back("Z");
1182 info.channels.push_back("A");
1183 }
1184
1185 // Open file for writing
1186 try {
1187 Imf::OutputFile file(filename.toUtf8(), header);
1188
1189 QList<ExrPaintLayerSaveInfo> informationObjects;
1190 informationObjects.push_back(info);
1191 encodeData(file, informationObjects, width, height);
1192 return ImportExportCodes::OK;
1193
1194 } catch(std::exception &e) {
1195 dbgFile << "Exception while writing to exr file: " << e.what();
1198 }
1200 }
1201
1202}
const KoID Float32BitsColorDepthID("F32", ki18n("32-bit float/channel"))
const KoID GrayAColorModelID("GRAYA", ki18n("Grayscale/Alpha"))
const KoID XYZAColorModelID("XYZA", ki18n("XYZ/Alpha"))
const KoID Float16BitsColorDepthID("F16", ki18n("16-bit float/channel"))
const KoID RGBAColorModelID("RGBA", ki18n("RGB/Alpha"))
const KoColorSpace * colorSpace() const
virtual KoID colorModelId() const =0
virtual KoID colorDepthId() const =0
KisPaintDeviceSP wrapLayerDevice(KisPaintDeviceSP device)
KisPaintDeviceSP layerDevice
KisPaintLayerSP layer
KisPaintDeviceSP paintDevice

References ExrPaintLayerSaveInfo::channels, KoColorSpace::colorDepthId(), KoColorSpace::colorModelId(), KisPaintDevice::colorSpace(), dbgFile, encodeData(), ImportExportCodes::ErrorWhileWriting, Float16BitsColorDepthID, Float32BitsColorDepthID, GrayAColorModelID, KisImage::height(), KisBaseNode::image, image(), ImportExportCodes::InternalError, KisImportExportAdditionalChecks::isFileWritable(), KIS_ASSERT_RECOVER_RETURN_VALUE, ExrPaintLayerSaveInfo::layer, ExrPaintLayerSaveInfo::layerDevice, ImportExportCodes::NoAccessToWrite, ImportExportCodes::OK, KisPaintLayer::paintDevice, ExrPaintLayerSaveInfo::pixelType, RGBAColorModelID, KisImage::width(), wrapLayerDevice(), and XYZAColorModelID.

◆ buildImage()

KisImportExportErrorCode EXRConverter::buildImage ( const QString & filename)

Definition at line 954 of file exr_converter.cc.

955{
956 return decode(filename);
957
958}
KisImportExportErrorCode decode(const QString &filename)

References decode().

◆ cancel

void EXRConverter::cancel ( )
virtualslot

Definition at line 1453 of file exr_converter.cc.

1454{
1455 warnKrita << "WARNING: Cancelling of an EXR loading is not supported!";
1456}
#define warnKrita
Definition kis_debug.h:87

References warnKrita.

◆ decode()

KisImportExportErrorCode EXRConverter::decode ( const QString & filename)
private

EXR semi-transparent images are expected to be rendered on black to ensure correctness of the light model

NOTE: We cannot do that automatically, because the EXR may be imported into the image as a layer, in which case the default color will create major issues. See https://bugs.kde.org/show_bug.cgi?id=427720

Definition at line 567 of file exr_converter.cc.

568{
569 try {
570 Imf::InputFile file(filename.toUtf8());
571
572 Imath::Box2i dw = file.header().dataWindow();
573 Imath::Box2i displayWindow = file.header().displayWindow();
574
575 int width = dw.max.x - dw.min.x + 1;
576 int height = dw.max.y - dw.min.y + 1;
577 int dx = dw.min.x;
578 int dy = dw.min.y;
579
580 // Display the attributes of a file
581 for (Imf::Header::ConstIterator it = file.header().begin();
582 it != file.header().end(); ++it) {
583 dbgFile << "Attribute: " << it.name() << " type: " << it.attribute().typeName();
584 }
585
586 // fetch Krita's extra layer info, which might have been stored previously
587 QDomDocument extraLayersInfo = d->loadExtraLayersInfo(file.header());
588
589 // Construct the list of LayerInfo
590
591 QList<ExrPaintLayerInfo> informationObjects;
593
594 ImageType imageType = IT_UNKNOWN;
595
596 const Imf::ChannelList &channels = file.header().channels();
597 std::set<std::string> layerNames;
598 channels.layers(layerNames);
599
600 if (!extraLayersInfo.isNull() &&
601 !d->checkExtraLayersInfoConsistent(extraLayersInfo, layerNames)) {
602
603 // it is inconsistent anyway
604 extraLayersInfo = QDomDocument();
605 }
606
607 // Check if there are A, R, G, B channels
608
609 dbgFile << "Checking for ARGB channels, they can occur in single-layer _or_ multi-layer images:";
611 bool topLevelRGBFound = false;
612 info.name = HDR_LAYER;
613
614 QStringList topLevelChannelNames = QStringList() << "A"
615 << "R"
616 << "G"
617 << "B"
618 << ".A"
619 << ".R"
620 << ".G"
621 << ".B"
622 << "A."
623 << "R."
624 << "G."
625 << "B."
626 << "A."
627 << "R."
628 << "G."
629 << "B."
630 << ".alpha"
631 << ".red"
632 << ".green"
633 << ".blue"
634 << "X"
635 << "Y"
636 << "Z"
637 << ".X"
638 << ".Y"
639 << ".Z"
640 << "X."
641 << "Y."
642 << "Z.";
643
644 for (Imf::ChannelList::ConstIterator i = channels.begin(); i != channels.end(); ++i) {
645 const Imf::Channel &channel = i.channel();
646 dbgFile << "Channel name = " << i.name() << " type = " << channel.type;
647
648 QString qname = i.name();
649 if (topLevelChannelNames.contains(qname)) {
650 topLevelRGBFound = true;
651 dbgFile << "Found top-level channel" << qname;
652 info.channelMap[qname] = qname;
653 info.updateImageType(imfTypeToKisType(channel.type));
654 }
655 // Channel names that don't contain a "." or that contain a
656 // "." only at the beginning or at the end are not considered
657 // to be part of any layer.
658 else if (!qname.contains('.')
659 || !qname.mid(1).contains('.')
660 || !qname.left(qname.size() - 1).contains('.')) {
661 warnFile << "Found a top-level channel that is not part of the rendered image" << qname << ". Krita will not load this channel.";
662 }
663 }
664 if (topLevelRGBFound) {
665 dbgFile << "Toplevel layer" << info.name << ":Image type:" << imageType << "Layer type" << info.imageType;
666 informationObjects.push_back(info);
667 imageType = info.imageType;
668 }
669
670 dbgFile << "Extra layers:" << layerNames.size();
671
672 for (std::set<std::string>::const_iterator i = layerNames.begin();i != layerNames.end(); ++i) {
673
674 info = ExrPaintLayerInfo();
675
676 dbgFile << "layer name = " << i->c_str();
677 info.name = i->c_str();
678 Imf::ChannelList::ConstIterator layerBegin, layerEnd;
679 channels.channelsInLayer(*i, layerBegin, layerEnd);
680 for (Imf::ChannelList::ConstIterator j = layerBegin;
681 j != layerEnd; ++j) {
682 const Imf::Channel &channel = j.channel();
683
684 info.updateImageType(imfTypeToKisType(channel.type));
685
686 QString qname = j.name();
687 QStringList list = qname.split('.');
688 QString layersuffix = list.last();
689
690 dbgFile << "\tchannel " << j.name() << "suffix" << layersuffix << " type = " << channel.type;
691
692 // Nuke writes the channels for sublayers as .red instead of .R, so convert those.
693 // See https://bugs.kde.org/show_bug.cgi?id=393771
694 if (topLevelChannelNames.contains("." + layersuffix)) {
695 layersuffix = layersuffix.at(0).toUpper();
696 }
697 dbgFile << "\t\tsuffix" << layersuffix;
698
699
700 if (list.size() > 1) {
701 info.name = list[list.size()-2];
702 info.parent = searchGroup(&groups, list, 0, list.size() - 3);
703 }
704
705 info.channelMap[layersuffix] = qname;
706 }
707
708 if (info.imageType != IT_UNKNOWN && info.imageType != IT_UNSUPPORTED) {
709 informationObjects.push_back(info);
710 if (imageType < info.imageType) {
711 imageType = info.imageType;
712 }
713 }
714 }
715
716 dbgFile << "File has" << informationObjects.size() << "layer(s)";
717
718 // Set the colorspaces
719 for (int i = 0; i < informationObjects.size(); ++i) {
720 ExrPaintLayerInfo& info = informationObjects[i];
721 QString modelId;
722
723 if (info.channelMap.size() == 1) {
724 modelId = GrayAColorModelID.id();
725 QString key = info.channelMap.begin().key();
726 if (key != "Y") {
727 info.remappedChannels.push_back(ExrPaintLayerInfo::Remap(key, "Y"));
728 QString channel = info.channelMap.begin().value();
729 info.channelMap.clear();
730 info.channelMap["Y"] = channel;
731 }
732 }
733 else if (info.channelMap.size() == 2) {
734 modelId = GrayAColorModelID.id();
735
736 QMap<QString,QString>::const_iterator it = info.channelMap.constBegin();
737 QMap<QString,QString>::const_iterator end = info.channelMap.constEnd();
738
739 QString failingChannelKey;
740
741 for (; it != end; ++it) {
742 // BUG: 461975
743 if (it.key() != "A") {
744 failingChannelKey = it.key();
745 break;
746 }
747 }
748
749 info.remappedChannels.push_back(ExrPaintLayerInfo::Remap(failingChannelKey, "Y"));
750
751 QString failingChannelValue = info.channelMap[failingChannelKey];
752 info.channelMap.remove(failingChannelKey);
753 info.channelMap["Y"] = failingChannelValue;
754 }
755 else if (info.channelMap.size() == 3 || info.channelMap.size() == 4) {
756
757 if (info.channelMap.contains("R") && info.channelMap.contains("G") && info.channelMap.contains("B")) {
758 modelId = RGBAColorModelID.id();
759 }
760 else if (info.channelMap.contains("X") && info.channelMap.contains("Y") && info.channelMap.contains("Z")) {
761 modelId = XYZAColorModelID.id();
762 QMap<QString, QString> newChannelMap;
763 if (info.channelMap.contains("W")) {
764 newChannelMap["A"] = info.channelMap["W"];
765 info.remappedChannels.push_back(ExrPaintLayerInfo::Remap("W", "A"));
766 info.remappedChannels.push_back(ExrPaintLayerInfo::Remap("X", "X"));
767 info.remappedChannels.push_back(ExrPaintLayerInfo::Remap("Y", "Y"));
768 info.remappedChannels.push_back(ExrPaintLayerInfo::Remap("Z", "Z"));
769 } else if (info.channelMap.contains("A")) {
770 newChannelMap["A"] = info.channelMap["A"];
771 }
772 // The decode function expect R, G, B in the channel map
773 newChannelMap["R"] = info.channelMap["X"];
774 newChannelMap["G"] = info.channelMap["Y"];
775 newChannelMap["B"] = info.channelMap["Z"];
776 info.channelMap = newChannelMap;
777 }
778 else {
779 modelId = RGBAColorModelID.id();
780 QMap<QString, QString> newChannelMap;
781 QMap<QString, QString>::iterator it = info.channelMap.begin();
782 newChannelMap["R"] = it.value();
783 info.remappedChannels.push_back(ExrPaintLayerInfo::Remap(it.key(), "R"));
784 ++it;
785 newChannelMap["G"] = it.value();
786 info.remappedChannels.push_back(ExrPaintLayerInfo::Remap(it.key(), "G"));
787 ++it;
788 newChannelMap["B"] = it.value();
789 info.remappedChannels.push_back(ExrPaintLayerInfo::Remap(it.key(), "B"));
790 if (info.channelMap.size() == 4) {
791 ++it;
792 newChannelMap["A"] = it.value();
793 info.remappedChannels.push_back(ExrPaintLayerInfo::Remap(it.key(), "A"));
794 }
795
796 info.channelMap = newChannelMap;
797 }
798 }
799 else {
800 dbgFile << info.name << "has" << info.channelMap.size() << "channels, and we don't know what to do.";
801 }
802 if (!modelId.isEmpty()) {
803 info.colorSpace = kisTypeToColorSpace(modelId, info.imageType);
804 }
805 }
806
807 // Get colorspace
808 dbgFile << "Image type = " << imageType;
809 const KoColorSpace* colorSpace = kisTypeToColorSpace(RGBAColorModelID.id(), imageType);
810
812 dbgFile << "Color space: " << colorSpace->name();
813
814 // Set the colorspace on all groups
815 for (int i = 0; i < groups.size(); ++i) {
816 ExrGroupLayerInfo& info = groups[i];
817 info.colorSpace = colorSpace;
818 }
819
820 // Create the image
821 // Make sure the created image is the same size as the displayWindow since
822 // the dataWindow can be cropped in some cases.
823 int displayWidth = displayWindow.max.x - displayWindow.min.x + 1;
824 int displayHeight = displayWindow.max.y - displayWindow.min.y + 1;
825 d->image = new KisImage(d->doc->createUndoStore(), displayWidth, displayHeight, colorSpace, "");
826
827 if (!d->image) {
829 }
830
839 //d->image->setDefaultProjectionColor(KoColor(Qt::black, colorSpace));
840
841 // Create group layers
842 for (int i = 0; i < groups.size(); ++i) {
843 ExrGroupLayerInfo& info = groups[i];
844 Q_ASSERT(info.parent == 0 || info.parent->groupLayer);
845 KisGroupLayerSP groupLayerParent = (info.parent) ? info.parent->groupLayer : d->image->rootLayer();
846 info.groupLayer = new KisGroupLayer(d->image, info.name, OPACITY_OPAQUE_U8);
847 d->image->addNode(info.groupLayer, groupLayerParent);
848 }
849
850 // Load the layers
851 for (int i = informationObjects.size() - 1; i >= 0; --i) {
852 ExrPaintLayerInfo& info = informationObjects[i];
853 if (info.colorSpace) {
854 dbgFile << "Decoding " << info.name << " with " << info.channelMap.size() << " channels, and color space " << info.colorSpace->id();
855 KisPaintLayerSP layer = new KisPaintLayer(d->image, info.name, OPACITY_OPAQUE_U8, info.colorSpace);
856
857 if (!layer) {
859 }
860
862
863 switch (info.channelMap.size()) {
864 case 1:
865 case 2:
866 // Decode the data
867 switch (info.imageType) {
868 case IT_FLOAT16:
869 d->decodeData1<half>(file, info, layer, width, dx, dy, height, Imf::HALF);
870 break;
871 case IT_FLOAT32:
872 d->decodeData1<float>(file, info, layer, width, dx, dy, height, Imf::FLOAT);
873 break;
874 case IT_UNKNOWN:
875 case IT_UNSUPPORTED:
876 qFatal("Impossible error");
877 }
878 break;
879 case 3:
880 case 4:
881 // Decode the data
882 switch (info.imageType) {
883 case IT_FLOAT16:
884 d->decodeData4<half>(file, info, layer, width, dx, dy, height, Imf::HALF);
885 break;
886 case IT_FLOAT32:
887 d->decodeData4<float>(file, info, layer, width, dx, dy, height, Imf::FLOAT);
888 break;
889 case IT_UNKNOWN:
890 case IT_UNSUPPORTED:
891 qFatal("Impossible error");
892 }
893 break;
894 default:
895 qFatal("Invalid number of channels: %i", info.channelMap.size());
896 }
897 // Check if should set the channels
898 if (!info.remappedChannels.isEmpty()) {
900 Q_FOREACH (const ExrPaintLayerInfo::Remap& remap, info.remappedChannels) {
901 QMap<QString, KisMetaData::Value> map;
902 map["original"] = KisMetaData::Value(remap.original);
903 map["current"] = KisMetaData::Value(remap.current);
904 values.append(map);
905 }
906 layer->metaData()->addEntry(KisMetaData::Entry(KisMetaData::SchemaRegistry::instance()->create("http://krita.org/exrchannels/1.0/" , "exrchannels"), "channelsmap", values));
907 }
908 // Add the layer
909 KisGroupLayerSP groupLayerParent = (info.parent) ? info.parent->groupLayer : d->image->rootLayer();
910 d->image->addNode(layer, groupLayerParent);
911 } else {
912 dbgFile << "No decoding " << info.name << " with " << info.channelMap.size() << " channels, and lack of a color space";
913 }
914 }
915
916 // After reading the image, notify the user about changed alpha.
917 if (d->alphaWasModified) {
918 QString msg =
919 i18nc("@info",
920 "The image contains pixels with zero alpha channel and non-zero "
921 "color channels. Krita has modified those pixels to have "
922 "at least some alpha. The initial values will <i>not</i> "
923 "be reverted on saving the image back."
924 "<br/><br/>"
925 "This will hardly make any visual difference just keep it in mind.");
926 if (d->showNotifications) {
927 QMessageBox::information(qApp->activeWindow(), i18nc("@title:window", "EXR image has been modified"), msg);
928 } else {
929 warnKrita << "WARNING:" << msg;
930 }
931 }
932
933 if (!extraLayersInfo.isNull()) {
934 KisExrLayersSorter sorter(extraLayersInfo, d->image);
935 }
936
938
939 } catch (std::exception &e) {
940 dbgFile << "Error while reading from the exr file: " << e.what();
941
946 } else {
948 }
949 }
950
952}
QList< QString > QStringList
const QString COMPOSITE_OVER
static KisMetaData::SchemaRegistry * instance()
bool addEntry(const Entry &entry)
QString id() const
Definition KoID.cpp:63
ImageType
@ IT_FLOAT32
@ IT_UNKNOWN
@ IT_FLOAT16
@ IT_UNSUPPORTED
QString remap(const QMap< QString, QString > &current2original, const QString &current)
#define HDR_LAYER
const KoColorSpace * kisTypeToColorSpace(QString colorModelID, ImageType imageType)
ExrGroupLayerInfo * searchGroup(QList< ExrGroupLayerInfo > *groups, QStringList list, int idx1, int idx2)
ImageType imfTypeToKisType(Imf::PixelType type)
#define warnFile
Definition kis_debug.h:95
QPainterPath create(const char32_t codepoint, double height)
Creates a tofu missing glyph indicator representing the provided Unicode codepoint.
KisGroupLayerSP groupLayer
const KoColorSpace * colorSpace
const ExrGroupLayerInfo * parent
QMap< QString, QString > channelMap
first is either R, G, B or A second is the EXR channel name
void updateImageType(ImageType channelType)
QList< Remap > remappedChannels
this is used to store in the metadata the mapping between exr channel name, and channels used in Krit...
void setCompositeOpId(const QString &compositeOpId)
KisMetaData::Store * metaData()
bool addNode(KisNodeSP node, KisNodeSP parent=KisNodeSP(), KisNodeAdditionFlags flags=KisNodeAdditionFlag::None)

References KisMetaData::Store::addEntry(), ExrPaintLayerInfo::channelMap, ExrLayerInfoBase::colorSpace, COMPOSITE_OVER, d, dbgFile, KisImportExportAdditionalChecks::doesFileExist(), ImportExportCodes::ErrorWhileReading, ImportExportCodes::Failure, ImportExportCodes::FileNotExist, ImportExportCodes::FormatColorSpaceUnsupported, GrayAColorModelID, ExrGroupLayerInfo::groupLayer, HDR_LAYER, KoID::id(), KoColorSpace::id, ExrPaintLayerInfo::imageType, imfTypeToKisType(), KisMetaData::SchemaRegistry::instance(), KisImportExportAdditionalChecks::isFileReadable(), IT_FLOAT16, IT_FLOAT32, IT_UNKNOWN, IT_UNSUPPORTED, kisTypeToColorSpace(), KisLayer::metaData(), KoColorSpace::name, ExrLayerInfoBase::name, ImportExportCodes::NoAccessToRead, ImportExportCodes::OK, OPACITY_OPAQUE_U8, ExrLayerInfoBase::parent, remap(), ExrPaintLayerInfo::remappedChannels, RGBAColorModelID, searchGroup(), KisBaseNode::setCompositeOpId(), ExrPaintLayerInfo::updateImageType(), warnFile, warnKrita, and XYZAColorModelID.

◆ errorMessage()

QString EXRConverter::errorMessage ( ) const

Definition at line 966 of file exr_converter.cc.

967{
968 return d->errorMessage;
969}

References d.

◆ image()

KisImageSP EXRConverter::image ( )

Retrieve the constructed image

Definition at line 961 of file exr_converter.cc.

962{
963 return d->image;
964}

References d.

Member Data Documentation

◆ d

const QScopedPointer<Private> EXRConverter::d
private

Definition at line 41 of file exr_converter.h.


The documentation for this class was generated from the following files: