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

#include <kis_tiff_export.h>

+ Inheritance diagram for KisTIFFExport:

Public Member Functions

KisImportExportErrorCode convert (KisDocument *document, QIODevice *io, KisPropertiesConfigurationSP configuration=0) override
 
KisConfigWidgetcreateConfigurationWidget (QWidget *parent, const QByteArray &from="", const QByteArray &to="") const override
 createConfigurationWidget creates a widget that can be used to define the settings for a given import/export filter
 
KisPropertiesConfigurationSP defaultConfiguration (const QByteArray &from="", const QByteArray &to="") const override
 defaultConfiguration defines the default settings for the given import export filter
 
void initializeCapabilities () override
 
 KisTIFFExport (QObject *parent, const QVariantList &)
 
bool supportsIO () const override
 Override and return false for the filters that use a library that cannot handle file handles, only file names.
 
 ~KisTIFFExport () override
 
- Public Member Functions inherited from KisImportExportFilter
virtual QMap< QString, KisExportCheckBase * > exportChecks ()
 generate and return the list of capabilities of this export filter. The list
 
virtual bool exportSupportsGuides () const
 exportSupportsGuides Because guides are in the document and not the image, checking for guides cannot be made an exportCheck.
 
KisPropertiesConfigurationSP lastSavedConfiguration (const QByteArray &from="", const QByteArray &to="") const
 lastSavedConfiguration return the last saved configuration for this filter
 
 Private ()
 
void setBatchMode (bool batchmode)
 
void setFilename (const QString &filename)
 
void setImportUserFeedBackInterface (KisImportUserFeedbackInterface *interface)
 
void setMimeType (const QString &mime)
 
void setRealFilename (const QString &filename)
 
void setUpdater (QPointer< KoUpdater > updater)
 
QPointer< KoUpdaterupdater ()
 
virtual QString verify (const QString &fileName) const
 Verify whether the given file is correct and readable.
 
 ~KisImportExportFilter () override
 
 ~Private ()
 

Private Attributes

TIFFErrorHandler oldErrHandler = nullptr
 
TIFFErrorHandler oldWarnHandler = nullptr
 

Additional Inherited Members

- Public Attributes inherited from KisImportExportFilter
bool batchmode
 
QMap< QString, KisExportCheckBase * > capabilities
 
QString filename
 
KisImportUserFeedbackInterfaceimportUserFeedBackInterface {nullptr}
 
QByteArray mime
 
QString realFilename
 
QPointer< KoUpdaterupdater
 
- Static Public Attributes inherited from KisImportExportFilter
static const QString CICPPrimariesTag = "CICPCompatiblePrimaries"
 
static const QString CICPTransferCharacteristicsTag = "CICPCompatibleTransferFunction"
 
static const QString ColorDepthIDTag = "ColorDepthID"
 
static const QString ColorModelIDTag = "ColorModelID"
 
static const QString HDRTag = "HDRSupported"
 
static const QString ImageContainsTransparencyTag = "ImageContainsTransparency"
 
static const QString sRGBTag = "sRGB"
 
- Protected Member Functions inherited from KisImportExportFilter
void addCapability (KisExportCheckBase *capability)
 
void addSupportedColorModels (QList< QPair< KoID, KoID > > supportedColorModels, const QString &name, KisExportCheckBase::Level level=KisExportCheckBase::PARTIALLY)
 
bool batchMode () const
 
QString filename () const
 
KisImportUserFeedbackInterfaceimportUserFeedBackInterface () const
 
 KisImportExportFilter (QObject *parent=0)
 
QByteArray mimeType () const
 
QString realFilename () const
 
void setProgress (int value)
 
QString verifyZiPBasedFiles (const QString &fileName, const QStringList &filesToCheck) const
 

Detailed Description

Definition at line 17 of file kis_tiff_export.h.

Constructor & Destructor Documentation

◆ KisTIFFExport()

KisTIFFExport::KisTIFFExport ( QObject * parent,
const QVariantList &  )

Definition at line 45 of file kis_tiff_export.cc.

46 : KisImportExportFilter(parent)
47 , oldErrHandler(TIFFSetErrorHandler(&KisTiffErrorHandler))
48 , oldWarnHandler(TIFFSetWarningHandler(&KisTiffWarningHandler))
49{
50}
KisImportExportFilter(QObject *parent=0)
TIFFErrorHandler oldErrHandler
TIFFErrorHandler oldWarnHandler
void KisTiffWarningHandler(const char *module, const char *fmt, va_list args)
void KisTiffErrorHandler(const char *module, const char *fmt, va_list args)

◆ ~KisTIFFExport()

KisTIFFExport::~KisTIFFExport ( )
override

Definition at line 52 of file kis_tiff_export.cc.

53{
54 TIFFSetErrorHandler(oldErrHandler);
55 TIFFSetWarningHandler(oldWarnHandler);
56}

References oldErrHandler, and oldWarnHandler.

Member Function Documentation

◆ convert()

KisImportExportErrorCode KisTIFFExport::convert ( KisDocument * document,
QIODevice * io,
KisPropertiesConfigurationSP configuration = 0 )
overridevirtual

The filter chain calls this method to perform the actual conversion. The passed mimetypes should be a pair of those you specified in your .desktop file. You have to implement this method to make the filter work.

Returns
The error status, see the #ConversionStatus enum. KisImportExportFilter::OK means that everything is alright.

Implements KisImportExportFilter.

Definition at line 58 of file kis_tiff_export.cc.

59{
60 // If a configuration object was passed to the convert method, we use that, otherwise we load from the settings
62 if (configuration) {
63 cfg->fromXML(configuration->toXML());
64 }
65 else {
67 }
68
69 KisTIFFOptions options;
70 options.fromProperties(configuration);
71
72 if (!options.flatten && !options.saveAsPhotoshop) {
73 const bool hasGroupLayers =
74 KisLayerUtils::recursiveFindNode(document->savingImage()->root(),
75 [] (KisNodeSP node) {
76 return node->parent() && node->inherits("KisGroupLayer");
77 });
78 options.flatten = hasGroupLayers;
79 }
80
81 KisImageSP kisimage = [&]() {
82 if (options.flatten) {
83 KisImageSP image =
84 new KisImage(nullptr,
85 document->savingImage()->width(),
86 document->savingImage()->height(),
87 document->savingImage()->colorSpace(),
88 "");
89 image->setResolution(document->savingImage()->xRes(),
90 document->savingImage()->yRes());
92 new KisPaintDevice(*document->savingImage()->projection()));
95 "projection",
97 pd));
98 image->addNode(KisNodeSP(l.data()), image->rootLayer().data());
99 return image;
100 } else {
101 return document->savingImage();
102 }
103 }();
104
105 dbgFile << "Start writing TIFF File";
107
108 QFile file(filename());
109 if (!file.open(QFile::ReadWrite | QFile::Truncate)) {
110 return {KisImportExportErrorCannotRead(file.error())};
111 }
112
113 // Open file for writing
114 const QByteArray encodedFilename = QFile::encodeName(filename());
115
116 // https://gitlab.com/libtiff/libtiff/-/issues/173
117#ifdef Q_OS_WIN
118 const int handle = (int)(_get_osfhandle(file.handle()));
119#else
120 const int handle = file.handle();
121#endif
122
123 // NOLINTNEXTLINE(bugprone-narrowing-conversions, cppcoreguidelines-narrowing-conversions)
124 std::unique_ptr<TIFF, decltype(&TIFFCleanup)> image(TIFFFdOpen(handle, encodedFilename.data(), "w"), &TIFFCleanup);
125
126 if (!image) {
127 dbgFile << "Could not open the file for writing" << filename();
129 }
130
131 // Set the document information
132 KoDocumentInfo *info = document->documentInfo();
133 QString title = info->aboutInfo("title");
134 if (!title.isEmpty()) {
135 if (!TIFFSetField(image.get(),
136 TIFFTAG_DOCUMENTNAME,
137 title.toLatin1().constData())) {
139 }
140 }
141 QString abstract = info->aboutInfo("description");
142 if (!abstract.isEmpty()) {
143 if (!TIFFSetField(image.get(),
144 TIFFTAG_IMAGEDESCRIPTION,
145 abstract.toLatin1().constData())) {
147 }
148 }
149 QString author = info->authorInfo("creator");
150 if (!author.isEmpty()) {
151 if (!TIFFSetField(image.get(),
152 TIFFTAG_ARTIST,
153 author.toLatin1().constData())) {
155 }
156 }
157
158 dbgFile << "xres: " << INCH_TO_POINT(kisimage->xRes())
159 << " yres: " << INCH_TO_POINT(kisimage->yRes());
160 if (!TIFFSetField(
161 image.get(),
162 TIFFTAG_XRESOLUTION,
163 INCH_TO_POINT(kisimage->xRes()))) { // It is the "invert" macro
164 // because we convert from
165 // pointer-per-inch to points
167 }
168 if (!TIFFSetField(image.get(),
169 TIFFTAG_YRESOLUTION,
170 INCH_TO_POINT(kisimage->yRes()))) {
172 }
173
174 if (!TIFFSetField(image.get(), TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH)) {
176 }
177
178 KisGroupLayer *root =
179 dynamic_cast<KisGroupLayer *>(kisimage->rootLayer().data());
182
183#ifdef TIFF_CAN_WRITE_PSD_TAGS
184 if (options.saveAsPhotoshop) {
185 KisTiffPsdWriter writer(image.get(), &options);
186 KisImportExportErrorCode result = writer.writeImage(root);
187 if (!result.isOk()) {
188 return result;
189 }
190 } else
191#endif // TIFF_CAN_WRITE_PSD_TAGS
192 {
193 KisTIFFWriterVisitor visitor(image.get(), &options);
194 if (!(visitor.visit(root))) {
196 }
197 }
198
199 image.reset();
200 file.close();
201
202 if (!options.flatten && !options.saveAsPhotoshop) {
203 // HACK!! Externally inject the Exif metadata
204 // libtiff has no way to access the fields wholesale
205 try {
207
208#if EXIV2_TEST_VERSION(0,28,0)
209 const std::unique_ptr<Exiv2::Image> img = Exiv2::ImageFactory::open(std::move(basicIoDevice));
210#else
211 const std::unique_ptr<Exiv2::Image> img(Exiv2::ImageFactory::open(basicIoDevice).release());
212#endif
213
214 img->readMetadata();
215
216 Exiv2::ExifData &data = img->exifData();
217
218 const KisMetaData::IOBackend *io =
220
221 // All IFDs are paint layer children of root
222 KisNodeSP node = root->firstChild();
223
224 QBuffer ioDevice;
225
226 // Get layer
227 KisLayer *layer = qobject_cast<KisLayer *>(node.data());
228 Q_ASSERT(layer);
229
230 // Inject the data as any other IOBackend
231 io->saveTo(layer->metaData(), &ioDevice);
232
233 Exiv2::ExifData dataToInject;
234
235 // Reinterpret the blob we just got and inject its contents into
236 // tempData
237 Exiv2::ExifParser::decode(
238 dataToInject,
239 reinterpret_cast<const Exiv2::byte *>(ioDevice.data().data()),
240 static_cast<uint32_t>(ioDevice.size()));
241
242 for (const auto &v : dataToInject) {
243 data[v.key()] = v.value();
244 }
245 // Write metadata
246 img->writeMetadata();
247#if EXIV2_TEST_VERSION(0,28,0)
248 } catch (Exiv2::Error &e) {
249 errFile << "Failed injecting TIFF metadata:" << Exiv2::Error(e.code()).what();
250#else
251 } catch (Exiv2::AnyError &e) {
252 errFile << "Failed injecting TIFF metadata:" << e.code()
253 << e.what();
254#endif
255 }
256 }
258}
qreal v
const quint8 OPACITY_OPAQUE_U8
constexpr qreal INCH_TO_POINT(qreal inch)
Definition KoUnit.h:38
static QByteArray nativeFormatMimeType()
Exiv2::BasicIo::AutoPtr ptr_type
KisGroupLayerSP rootLayer() const
double xRes() const
double yRes() const
void setResolution(double xres, double yres)
KisPropertiesConfigurationSP lastSavedConfiguration(const QByteArray &from="", const QByteArray &to="") const
lastSavedConfiguration return the last saved configuration for this filter
virtual bool saveTo(const Store *store, QIODevice *ioDevice, HeaderType headerType=NoHeader) const =0
static KisMetadataBackendRegistry * instance()
The class containing all meta information about a document.
QString authorInfo(const QString &info) const
QString aboutInfo(const QString &info) const
const T value(const QString &id) const
#define KIS_ASSERT_RECOVER_RETURN_VALUE(cond, val)
Definition kis_assert.h:85
#define KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(cond, val)
Definition kis_assert.h:129
#define errFile
Definition kis_debug.h:115
#define dbgFile
Definition kis_debug.h:53
KisSharedPtr< KisPaintLayer > KisPaintLayerSP
KisSharedPtr< KisPaintDevice > KisPaintDeviceSP
Definition kis_types.h:73
KisSharedPtr< KisNode > KisNodeSP
Definition kis_types.h:86
KisNodeSP recursiveFindNode(KisNodeSP node, std::function< bool(KisNodeSP)> func)
KisMetaData::Store * metaData()
bool addNode(KisNodeSP node, KisNodeSP parent=KisNodeSP(), KisNodeAdditionFlags flags=KisNodeAdditionFlag::None)
KisNodeSP firstChild() const
Definition kis_node.cpp:361
void fromProperties(KisPropertiesConfigurationSP cfg)

References KoDocumentInfo::aboutInfo(), KisNodeFacade::addNode(), KoDocumentInfo::authorInfo(), KisSharedPtr< T >::data(), dbgFile, errFile, ImportExportCodes::ErrorWhileWriting, ImportExportCodes::Failure, KisImportExportFilter::filename, KisNode::firstChild(), KisTIFFOptions::flatten, KisTIFFOptions::fromProperties(), INCH_TO_POINT(), KisMetadataBackendRegistry::instance(), ImportExportCodes::InternalError, KisImportExportErrorCode::isOk(), KIS_ASSERT_RECOVER_RETURN_VALUE, KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE, KisImportExportFilter::lastSavedConfiguration(), KisLayer::metaData(), KisDocument::nativeFormatMimeType(), ImportExportCodes::NoAccessToWrite, ImportExportCodes::OK, OPACITY_OPAQUE_U8, KisLayerUtils::recursiveFindNode(), KisImage::rootLayer(), KisTIFFOptions::saveAsPhotoshop, KisMetaData::IOBackend::saveTo(), KisImage::setResolution(), v, KoGenericRegistry< T >::value(), KisTIFFWriterVisitor::visit(), KisTiffPsdWriter::writeImage(), KisImage::xRes(), and KisImage::yRes().

◆ createConfigurationWidget()

KisConfigWidget * KisTIFFExport::createConfigurationWidget ( QWidget * parent,
const QByteArray & from = "",
const QByteArray & to = "" ) const
overridevirtual

createConfigurationWidget creates a widget that can be used to define the settings for a given import/export filter

Parameters
parentthe owner of the widget; the caller is responsible for deleting
fromThe mimetype of the source file/document
toThe mimetype of the destination file/document
Returns
the widget

Reimplemented from KisImportExportFilter.

Definition at line 266 of file kis_tiff_export.cc.

267{
268 return new KisTIFFOptionsWidget(parent);
269}

◆ defaultConfiguration()

KisPropertiesConfigurationSP KisTIFFExport::defaultConfiguration ( const QByteArray & from = "",
const QByteArray & to = "" ) const
overridevirtual

defaultConfiguration defines the default settings for the given import export filter

Parameters
fromThe mimetype of the source file/document
toThe mimetype of the destination file/document
Returns
a serializable KisPropertiesConfiguration object

Reimplemented from KisImportExportFilter.

Definition at line 260 of file kis_tiff_export.cc.

261{
262 KisTIFFOptions options;
263 return options.toProperties();
264}
KisPropertiesConfigurationSP toProperties() const

References KisTIFFOptions::toProperties().

◆ initializeCapabilities()

void KisTIFFExport::initializeCapabilities ( )
overridevirtual

Reimplemented from KisImportExportFilter.

Definition at line 271 of file kis_tiff_export.cc.

272{
278 ->get("TiffExifCheck")
282
283 QList<QPair<KoID, KoID>> supportedColorModels = {
284 {},
301 addSupportedColorModels(supportedColorModels, "TIFF");
302
303}
VertexDescriptor get(PredecessorMap const &m, VertexDescriptor v)
const KoID Float32BitsColorDepthID("F32", ki18n("32-bit float/channel"))
const KoID YCbCrAColorModelID("YCbCrA", ki18n("YCbCr/Alpha"))
const KoID GrayAColorModelID("GRAYA", ki18n("Grayscale/Alpha"))
const KoID Float16BitsColorDepthID("F16", ki18n("16-bit float/channel"))
const KoID Integer8BitsColorDepthID("U8", ki18n("8-bit integer/channel"))
const KoID Integer16BitsColorDepthID("U16", ki18n("16-bit integer/channel"))
const KoID CMYKAColorModelID("CMYKA", ki18n("CMYK/Alpha"))
const KoID LABAColorModelID("LABA", ki18n("L*a*b*/Alpha"))
const KoID RGBAColorModelID("RGBA", ki18n("RGB/Alpha"))
static KisExportCheckRegistry * instance()
void addSupportedColorModels(QList< QPair< KoID, KoID > > supportedColorModels, const QString &name, KisExportCheckBase::Level level=KisExportCheckBase::PARTIALLY)
void addCapability(KisExportCheckBase *capability)
QPainterPath create(const char32_t codepoint, double height)
Creates a tofu missing glyph indicator representing the provided Unicode codepoint.

References KisImportExportFilter::addCapability(), KisImportExportFilter::addSupportedColorModels(), CMYKAColorModelID, Float16BitsColorDepthID, Float32BitsColorDepthID, get(), GrayAColorModelID, KisExportCheckRegistry::instance(), Integer16BitsColorDepthID, Integer8BitsColorDepthID, LABAColorModelID, KisExportCheckBase::PARTIALLY, RGBAColorModelID, KisExportCheckBase::SUPPORTED, and YCbCrAColorModelID.

◆ supportsIO()

bool KisTIFFExport::supportsIO ( ) const
inlineoverridevirtual

Override and return false for the filters that use a library that cannot handle file handles, only file names.

Reimplemented from KisImportExportFilter.

Definition at line 23 of file kis_tiff_export.h.

23{ return false; }

Member Data Documentation

◆ oldErrHandler

TIFFErrorHandler KisTIFFExport::oldErrHandler = nullptr
private

Definition at line 30 of file kis_tiff_export.h.

◆ oldWarnHandler

TIFFErrorHandler KisTIFFExport::oldWarnHandler = nullptr
private

Definition at line 31 of file kis_tiff_export.h.


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