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

#include <kis_webp_export.h>

+ Inheritance diagram for KisWebPExport:

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
 
 KisWebPExport (QObject *parent, const QVariantList &)
 
 ~KisWebPExport () 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)
 
virtual bool supportsIO () const
 Override and return false for the filters that use a library that cannot handle file handles, only file names.
 
QPointer< KoUpdaterupdater ()
 
virtual QString verify (const QString &fileName) const
 Verify whether the given file is correct and readable.
 
 ~KisImportExportFilter () override
 
 ~Private ()
 

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 16 of file kis_webp_export.h.

Constructor & Destructor Documentation

◆ KisWebPExport()

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

Definition at line 44 of file kis_webp_export.cpp.

45 : KisImportExportFilter(parent)
46{
47}
KisImportExportFilter(QObject *parent=0)

◆ ~KisWebPExport()

KisWebPExport::~KisWebPExport ( )
overridedefault

Member Function Documentation

◆ convert()

KisImportExportErrorCode KisWebPExport::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 141 of file kis_webp_export.cpp.

142{
143 using WebPMuxSP = std::unique_ptr<WebPMux, decltype(&WebPMuxDelete)>;
144 using WebPAnimEncoderSP =
145 std::unique_ptr<WebPAnimEncoder, decltype(&WebPAnimEncoderDelete)>;
146
149
150 KisImageSP image = document->savingImage();
151 const QRect bounds = document->savingImage()->bounds();
152 const KoColorSpace *cs =
153 document->savingImage()->projection()->colorSpace();
154
155 const bool needSrgbConversion = [&]() {
156 if (!cfg->getBool("force_srgb", false)) {
157 return false;
158 }
159
160 if (cs->colorModelId() != RGBAColorModelID) {
161 return true;
162 }
163
164 const bool hasPrimaries = cs->profile()->hasColorants();
166 if (hasPrimaries) {
167 const ColorPrimaries primaries = cs->profile()->getColorPrimaries();
168 if (gamma == TRC_IEC_61966_2_1 && primaries == PRIMARIES_ITU_R_BT_709_5) {
169 return false;
170 }
171 }
172 return true;
173 }();
174
175 // Then comes the animation chunk.
176 WebPData imageChunk = {nullptr, 0};
177
178 {
179 WebPAnimEncoderOptions encodingOptions;
180 if (!WebPAnimEncoderOptionsInit(&encodingOptions)) {
181 errFile << "WebP animation configuration initialization failure";
183 }
184
185 if (cfg->getBool("lossless", true)) {
186 encodingOptions.allow_mixed = false;
187 } else {
188 encodingOptions.allow_mixed = true;
189 }
190 encodingOptions.verbose = true;
191 // XXX: should we implement background selection as in JPEG?
192 encodingOptions.anim_params.loop_count = 0;
193
194 WebPAnimEncoderSP enc(WebPAnimEncoderNew(bounds.width(),
195 bounds.height(),
196 &encodingOptions),
197 &WebPAnimEncoderDelete);
198
199 WebPConfig config;
200 {
201 if (!WebPConfigInit(&config)) {
202 errFile << "WebP config initialization failed!";
204 }
205
206 config.lossless = cfg->getBool("lossless", true) ? 1 : 0;
207 config.quality = cfg->getFloat("quality", 75.0);
208 config.method = cfg->getInt("method", 4);
209
210 config.target_size = cfg->getInt("target_size", 0);
211 config.target_PSNR = cfg->getFloat("target_PSNR", 0.0f);
212 config.segments = cfg->getInt("segments", 4);
213 config.sns_strength = cfg->getInt("sns_strength", 50);
214 config.filter_strength = cfg->getInt("filter_strength", 60);
215 config.filter_sharpness = cfg->getInt("filter_sharpness", 0);
216 config.filter_type = cfg->getInt("filter_type", 1);
217 config.autofilter = cfg->getBool("autofilter", false) ? 1 : 0;
218 config.alpha_compression = cfg->getInt("alpha_compression", 1);
219 config.alpha_filtering = cfg->getInt("alpha_filtering", 1);
220 config.alpha_quality = cfg->getInt("alpha_quality", 100);
221 config.pass = cfg->getInt("pass", 1);
222 config.show_compressed =
223 cfg->getBool("show_compressed", false) ? 1 : 0;
224 config.preprocessing = cfg->getInt("preprocessing", 0);
225 config.partitions = cfg->getInt("partitions", 0);
226 config.partition_limit = cfg->getInt("partition_limit", 0);
227 config.emulate_jpeg_size =
228 cfg->getBool("emulate_jpeg_size", false) ? 1 : 0;
229 config.thread_level = cfg->getBool("thread_level", false) ? 1 : 0;
230 config.low_memory = cfg->getBool("low_memory", false) ? 1 : 0;
231 config.near_lossless = cfg->getInt("near_lossless", 100);
232 config.exact = cfg->getBool("exact", false) ? 1 : 0;
233 config.use_sharp_yuv = cfg->getBool("use_sharp_yuv", false) ? 1 : 0;
234#if WEBP_ENCODER_ABI_VERSION >= 0x020f
235 config.qmin = cfg->getInt("qmin", 0);
236 config.qmax = cfg->getInt("qmax", 100);
237#endif
238
239 if (!WebPValidateConfig(&config)) {
240 errFile << "WebP configuration validation failure";
242 }
243 }
244
245 const bool enableDithering = cfg->getBool("dithering", true);
246
247 const bool isAnimated = [&]() {
248 if (image->animationInterface()->hasAnimation() && cfg->getBool("haveAnimation", true)) {
249 KisLayerUtils::flattenImage(image, nullptr);
250 image->waitForDone();
251
252 const KisNodeSP projection = image->rootLayer()->firstChild();
253 return projection->isAnimated() && projection->hasEditablePaintDevice();
254 }
255 return false;
256 }();
257
258 if (isAnimated) {
259 // Flatten the image, projections don't have keyframes.
260 KisLayerUtils::flattenImage(image, nullptr);
261 image->waitForDone();
262
263 const KisNodeSP projection = image->rootLayer()->firstChild();
264 if (!projection->isAnimated()) return ImportExportCodes::InternalError;
265
266 const KisRasterKeyframeChannel *frames =
267 projection->paintDevice()->keyframeChannel();
268 const auto times = [&]() -> QList<int> {
269 QList<int> t;
270 QSet<int> s = frames->allKeyframeTimes();
271 t = QList<int>(s.begin(), s.end());
272 std::sort(t.begin(), t.end());
273 return t;
274 }();
275
276 // If this is not an integral number, it must be diagnosed on
277 // export and reported to the user.
278 // THE FRAME DURATION WILL BE ROUNDED.
279 const int duration =
280 std::lround(1000.0
281 / static_cast<double>(
282 image->animationInterface()->framerate()));
283
284 for (const int i : times) {
285 const int timestamp_ms = i * duration;
286
287 WebPPictureSP currentFrame;
288 if (!WebPPictureInit(currentFrame.get())) {
289 errFile << "WebP picture initialization failure";
291 }
292
293 currentFrame.get()->width = bounds.width();
294 currentFrame.get()->height = bounds.height();
295
296 // Use ARGB in lossless mode
297 if (config.lossless == 1) {
298 currentFrame.get()->use_argb = 1;
299 }
300
301 const QImage pixels = [&]() {
302 const KisRasterKeyframeSP frameData =
303 frames->keyframeAt<KisRasterKeyframe>(i);
305 *image->projection(),
307 frameData->writeFrameToDevice(dev);
308
311 || !enableDithering) {
312 dst = dev;
313 } else {
314 // We need to use gradient painter code's:
315 // to convert to RGBA samedepth;
316 // then dither to RGBA8
317 // then convert from ARGB32 to RGBA8888
318 const KisPaintDeviceSP src = dev;
319 const KoID depthId = src->colorSpace()->colorDepthId();
321 if (cs->colorModelId() == RGBAColorModelID && !needSrgbConversion) {
322 // Preserve color profile if model is RGB and force convert sRGB is off
325 src->colorSpace()->profile());
326 }
328 depthId.id(),
329 destCs->profile());
330
332 tmp->convertTo(mixCs);
333 dst = new KisPaintDevice(destCs);
334
335 const KisDitherOp *op =
336 mixCs->ditherOp(destCs->colorDepthId().id(), enableDithering ? DITHER_BEST : DITHER_NONE);
337
338 KisRandomConstAccessorSP srcIt = tmp->createRandomConstAccessorNG();
340
341 int rows = 1;
342 int columns = 1;
343
344 for (int y = bounds.y(); y <= bounds.bottom(); y += rows) {
345 rows = qMin(srcIt->numContiguousRows(y),
346 qMin(dstIt->numContiguousRows(y), bounds.bottom() - y + 1));
347
348 for (int x = bounds.x(); x <= bounds.right(); x += columns) {
349 columns = qMin(srcIt->numContiguousColumns(x),
350 qMin(dstIt->numContiguousColumns(x), bounds.right() - x + 1));
351
352 srcIt->moveTo(x, y);
353 dstIt->moveTo(x, y);
354
355 const qint32 srcRowStride = srcIt->rowStride(x, y);
356 const qint32 dstRowStride = dstIt->rowStride(x, y);
357 const quint8 *srcPtr = srcIt->rawDataConst();
358 quint8 *dstPtr = dstIt->rawData();
359
360 op->dither(srcPtr, srcRowStride, dstPtr, dstRowStride, x, y, columns, rows);
361 }
362 }
363 }
364
365 // Convert to sRGB for non-RGBA color model
366 const KoColorProfile *imageProfile = (dst->colorSpace()->colorModelId() == RGBAColorModelID)
367 ? dst->colorSpace()->profile()
368 : nullptr;
369
370 if (needSrgbConversion) {
372 }
373
374 const QImage imageOut = dst->convertToQImage(imageProfile, 0, 0, bounds.width(), bounds.height())
375 .convertToFormat(QImage::Format_RGBA8888);
376
377 return imageOut;
378 }();
379
380 if (!WebPPictureImportRGBA(currentFrame.get(),
381 pixels.constBits(),
382 bounds.width() * 4)) {
383 errFile << "WebP picture conversion failure:"
384 << currentFrame.get()->error_code;
386 }
387
388 WebPMemoryWriter writer;
389 WebPMemoryWriterInit(&writer);
390 currentFrame.get()->writer = WebPMemoryWrite;
391 currentFrame.get()->custom_ptr = &writer;
392
393 if (!WebPEncode(&config, currentFrame.get())) {
394 errFile << "WebP encoding failure:"
395 << currentFrame.get()->error_code;
397 }
398
399 if (!WebPAnimEncoderAdd(enc.get(),
400 currentFrame.get(),
401 timestamp_ms,
402 &config)) {
403 errFile << "WebPAnimEncoderAdd failed";
405 }
406
407 dbgFile << "Added frame @" << i << timestamp_ms << "ms";
408 }
409
410 const int timestamp_ms =
412 * (1000 / image->animationInterface()->framerate());
413
414 // Insert the finish beacon.
415 WebPAnimEncoderAdd(enc.get(), nullptr, timestamp_ms, nullptr);
416
417 dbgFile << "Animation finished @" << timestamp_ms << "ms";
418 } else {
419 WebPPictureSP currentFrame;
420 if (!WebPPictureInit(currentFrame.get())) {
421 errFile << "WebP picture initialization failure";
423 }
424
425 currentFrame.get()->width = bounds.width();
426 currentFrame.get()->height = bounds.height();
427
428 // Use ARGB in lossless mode
429 if (config.lossless == 1) {
430 currentFrame.get()->use_argb = 1;
431 }
432
433 // Insert the projection itself only
434 const QImage pixels = [&]() {
437 || !enableDithering) {
438 dst = document->savingImage()->projection();
439 } else {
440 // We need to use gradient painter code's:
441 // to convert to RGBA samedepth;
442 // then dither to RGBA8
443 // then convert from ARGB32 to RGBA8888
444 const KisPaintDeviceSP src = document->savingImage()->projection();
445 const KoID depthId = src->colorSpace()->colorDepthId();
447 if (cs->colorModelId() == RGBAColorModelID && !needSrgbConversion) {
448 // Preserve color profile if model is RGB and force convert sRGB is off
451 src->colorSpace()->profile());
452 }
454 depthId.id(),
455 destCs->profile());
456
458 tmp->convertTo(mixCs);
459 dst = new KisPaintDevice(destCs);
460
461 const KisDitherOp *op =
462 mixCs->ditherOp(destCs->colorDepthId().id(), enableDithering ? DITHER_BEST : DITHER_NONE);
463
464 KisRandomConstAccessorSP srcIt = tmp->createRandomConstAccessorNG();
466
467 int rows = 1;
468 int columns = 1;
469
470 for (int y = bounds.y(); y <= bounds.bottom(); y += rows) {
471 rows = qMin(srcIt->numContiguousRows(y),
472 qMin(dstIt->numContiguousRows(y), bounds.bottom() - y + 1));
473
474 for (int x = bounds.x(); x <= bounds.right(); x += columns) {
475 columns = qMin(srcIt->numContiguousColumns(x),
476 qMin(dstIt->numContiguousColumns(x), bounds.right() - x + 1));
477
478 srcIt->moveTo(x, y);
479 dstIt->moveTo(x, y);
480
481 const qint32 srcRowStride = srcIt->rowStride(x, y);
482 const qint32 dstRowStride = dstIt->rowStride(x, y);
483 const quint8 *srcPtr = srcIt->rawDataConst();
484 quint8 *dstPtr = dstIt->rawData();
485
486 op->dither(srcPtr, srcRowStride, dstPtr, dstRowStride, x, y, columns, rows);
487 }
488 }
489 }
490
491 // Convert to sRGB for non-RGBA color model
492 const KoColorProfile *imageProfile = (dst->colorSpace()->colorModelId() == RGBAColorModelID)
493 ? dst->colorSpace()->profile()
494 : nullptr;
495
496 if (needSrgbConversion) {
498 }
499
500 const QImage imageOut = dst->convertToQImage(imageProfile, 0, 0, bounds.width(), bounds.height())
501 .convertToFormat(QImage::Format_RGBA8888);
502
503 return imageOut;
504 }();
505
506 if (!WebPPictureImportRGBA(currentFrame.get(),
507 pixels.constBits(),
508 bounds.width() * 4)) {
509 errFile << "WebP picture conversion failure:"
510 << currentFrame.get()->error_code;
512 }
513
514 WebPMemoryWriter writer;
515 WebPMemoryWriterInit(&writer);
516 currentFrame.get()->writer = WebPMemoryWrite;
517 currentFrame.get()->custom_ptr = &writer;
518
519 if (!WebPEncode(&config, currentFrame.get())) {
520 errFile << "WebP encoding failure:"
521 << currentFrame.get()->error_code;
523 }
524
525 if (!WebPAnimEncoderAdd(enc.get(),
526 currentFrame.get(),
527 0,
528 &config)) {
529 errFile << "WebPAnimEncoderAdd failed";
531 }
532 }
533
534 WebPAnimEncoderAssemble(enc.get(), &imageChunk);
535 };
536
537 // Don't copy this data, it's the biggest chunk.
538 WebPMuxSP mux(WebPMuxCreate(&imageChunk, 0), &WebPMuxDelete);
539
540 if (!mux) {
541 errFile << "WebP mux initialization failure";
543 }
544
545 // According to the standard, the ICC profile must be written first.
546 if (cfg->getBool("save_profile", true)) {
547 const QByteArray profile = needSrgbConversion
549 : image->profile()->rawData();
550
551 WebPData iccChunk = {reinterpret_cast<const uint8_t *>(profile.data()),
552 static_cast<size_t>(profile.size())};
553
554 // This data will die at the end of the scope.
555 if (WEBP_MUX_OK != WebPMuxSetChunk(mux.get(), "ICCP", &iccChunk, 1)) {
556 errFile << "WebPMuxSetChunk for the ICC profile failed";
558 }
559 }
560
561 if (cfg->getBool("storeMetaData", false)) {
562 auto metaDataStore = [&]() -> std::unique_ptr<KisMetaData::Store> {
563 KisExifInfoVisitor exivInfoVisitor;
564 exivInfoVisitor.visit(image->rootLayer().data());
565 if (exivInfoVisitor.metaDataCount() == 1) {
566 return std::make_unique<KisMetaData::Store>(
567 *exivInfoVisitor.exifInfo());
568 } else {
569 return {};
570 }
571 }();
572
573 if (metaDataStore && !metaDataStore->isEmpty()) {
575 model.setEnabledFilters(cfg->getString("filters").split(","));
576 metaDataStore->applyFilters(model.enabledFilters());
577 }
578
579 if (metaDataStore && cfg->getBool("exif", true)) {
580 const KisMetaData::IOBackend *io =
582
583 QBuffer ioDevice;
584
585 // Inject the data as any other IOBackend
586 io->saveTo(metaDataStore.get(), &ioDevice);
587
588 WebPData xmp = {
589 reinterpret_cast<const uint8_t *>(ioDevice.data().constData()),
590 static_cast<size_t>(ioDevice.data().size())};
591
592 // This data will die at the end of the scope.
593 if (WEBP_MUX_OK != WebPMuxSetChunk(mux.get(), "EXIF", &xmp, 1)) {
594 errFile << "WebPMuxSetChunk for EXIF failed";
596 }
597 }
598
599 if (metaDataStore && cfg->getBool("xmp", true)) {
600 const KisMetaData::IOBackend *io =
602
603 QBuffer ioDevice;
604
605 // Inject the data as any other IOBackend
606 io->saveTo(metaDataStore.get(), &ioDevice);
607
608 WebPData xmp = {
609 reinterpret_cast<const uint8_t *>(ioDevice.data().constData()),
610 static_cast<size_t>(ioDevice.data().size())};
611
612 // This data will die at the end of the scope.
613 if (WEBP_MUX_OK != WebPMuxSetChunk(mux.get(), "XMP ", &xmp, 1)) {
614 errFile << "WebPMuxSetChunk for XMP failed";
616 }
617 }
618 }
619
620 WebPData output;
621 WebPMuxAssemble(mux.get(), &output);
622 QDataStream s(io);
623 s.setByteOrder(QDataStream::LittleEndian);
624 s.writeRawData(reinterpret_cast<const char *>(output.bytes),
625 static_cast<int>(output.size));
626 WebPDataClear(&output);
627
629}
@ DITHER_NONE
Definition KisDitherOp.h:22
@ DITHER_BEST
Definition KisDitherOp.h:24
const KoID Integer8BitsColorDepthID("U8", ki18n("8-bit integer/channel"))
const KoID RGBAColorModelID("RGBA", ki18n("RGB/Alpha"))
ColorPrimaries
The colorPrimaries enum Enum of colorants, follows ITU H.273 for values 0 to 255, and has extra known...
@ PRIMARIES_ITU_R_BT_709_5
TransferCharacteristics
The transferCharacteristics enum Enum of transfer characteristics, follows ITU H.273 for values 0 to ...
@ TRC_IEC_61966_2_1
virtual quint8 * rawData()=0
virtual const quint8 * rawDataConst() const =0
virtual void dither(const quint8 *src, quint8 *dst, int x, int y) const =0
The KisExifInfoVisitor class looks for a layer with metadata.
KisMetaData::Store * exifInfo()
bool visit(KisNode *) override
const KisTimeSpan & documentPlaybackRange() const
documentPlaybackRange
void waitForDone()
KisGroupLayerSP rootLayer() const
KisImageAnimationInterface * animationInterface() const
KisPaintDeviceSP projection() const
QRect bounds() const override
const KoColorProfile * profile() const
QSet< int > allKeyframeTimes() const
Get a set of all integer times that map to a keyframe.
KisKeyframeSP keyframeAt(int time) const
Get a keyframe at specified time. Used primarily when the value of a given keyframe is needed.
virtual void setEnabledFilters(const QStringList &enabledFilters)
enable the filters in the given list; others will be disabled.
virtual bool saveTo(const Store *store, QIODevice *ioDevice, HeaderType headerType=NoHeader) const =0
static KisMetadataBackendRegistry * instance()
KisRasterKeyframeChannel * keyframeChannel() const
const KoColorSpace * colorSpace() const
QImage convertToQImage(const KoColorProfile *dstProfile, qint32 x, qint32 y, qint32 w, qint32 h, KoColorConversionTransformation::Intent renderingIntent=KoColorConversionTransformation::internalRenderingIntent(), KoColorConversionTransformation::ConversionFlags conversionFlags=KoColorConversionTransformation::internalConversionFlags()) const
KisRandomAccessorSP createRandomAccessorNG()
virtual qint32 rowStride(qint32 x, qint32 y) const =0
virtual qint32 numContiguousRows(qint32 y) const =0
virtual void moveTo(qint32 x, qint32 y)=0
virtual qint32 numContiguousColumns(qint32 x) const =0
The KisRasterKeyframeChannel is a concrete KisKeyframeChannel subclass that stores and manages KisRas...
The KisRasterKeyframe class is a concrete subclass of KisKeyframe that wraps a physical raster image ...
int end() const
virtual const KisDitherOp * ditherOp(const QString &depth, DitherType type) const
virtual KoID colorModelId() const =0
virtual KoID colorDepthId() const =0
virtual const KoColorProfile * profile() const =0
const T value(const QString &id) const
Definition KoID.h:30
QString id() const
Definition KoID.cpp:63
#define KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(cond, val)
Definition kis_assert.h:129
#define bounds(x, a, b)
#define errFile
Definition kis_debug.h:115
#define dbgFile
Definition kis_debug.h:53
void flattenImage(KisImageSP image, KisNodeSP activeNode, MergeFlags flags)
bool isAnimated() const
virtual KisPaintDeviceSP paintDevice() const =0
bool hasEditablePaintDevice() const
KisNodeSP firstChild() const
Definition kis_node.cpp:361
virtual QByteArray rawData() const
virtual ColorPrimaries getColorPrimaries() const
getColorPrimaries
virtual bool hasColorants() const =0
virtual TransferCharacteristics getTransferCharacteristics() const
getTransferCharacteristics This function should be subclassed at some point so we can get the value f...
const KoColorSpace * colorSpace(const QString &colorModelId, const QString &colorDepthId, const KoColorProfile *profile)
static KoColorSpaceRegistry * instance()
const KoColorProfile * p709SRGBProfile() const
const KoColorSpace * rgb8(const QString &profileName=QString())
WebPPicture * get()

References KisKeyframeChannel::allKeyframeTimes(), KisImage::animationInterface(), KisImage::bounds(), bounds, KoColorSpace::colorDepthId(), KoColorSpace::colorModelId(), KisPaintDevice::colorSpace(), KoColorSpaceRegistry::colorSpace(), KisPaintDevice::convertToQImage(), KritaUtils::CopySnapshot, KisPaintDevice::createRandomAccessorNG(), KisSharedPtr< T >::data(), dbgFile, KisDitherOp::dither(), DITHER_BEST, DITHER_NONE, KoColorSpace::ditherOp(), KisImageAnimationInterface::documentPlaybackRange(), KisMetaData::FilterRegistryModel::enabledFilters(), KisTimeSpan::end(), errFile, ImportExportCodes::ErrorWhileWriting, KisExifInfoVisitor::exifInfo(), KisNode::firstChild(), KisLayerUtils::flattenImage(), KisImageAnimationInterface::framerate(), WebPPictureSP::get(), KoColorProfile::getColorPrimaries(), KoColorProfile::getTransferCharacteristics(), KisImageAnimationInterface::hasAnimation(), KoColorProfile::hasColorants(), KisBaseNode::hasEditablePaintDevice(), KoID::id(), KisMetadataBackendRegistry::instance(), KoColorSpaceRegistry::instance(), Integer8BitsColorDepthID, ImportExportCodes::InternalError, KisBaseNode::isAnimated(), KisKeyframeChannel::keyframeAt(), KisPaintDevice::keyframeChannel(), KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE, KisExifInfoVisitor::metaDataCount(), KisRandomConstAccessorNG::moveTo(), ImportExportCodes::NoAccessToWrite, KisRandomConstAccessorNG::numContiguousColumns(), KisRandomConstAccessorNG::numContiguousRows(), ImportExportCodes::OK, KoColorSpaceRegistry::p709SRGBProfile(), KisBaseNode::paintDevice(), PRIMARIES_ITU_R_BT_709_5, KisImage::profile(), KoColorSpace::profile(), KisImage::projection(), KoColorProfile::rawData(), KisBaseAccessor::rawData(), KisBaseConstAccessor::rawDataConst(), KoColorSpaceRegistry::rgb8(), RGBAColorModelID, KisImage::rootLayer(), KisRandomConstAccessorNG::rowStride(), KisMetaData::IOBackend::saveTo(), KisMetaData::FilterRegistryModel::setEnabledFilters(), TRC_IEC_61966_2_1, KoGenericRegistry< T >::value(), KisExifInfoVisitor::visit(), and KisImage::waitForDone().

◆ createConfigurationWidget()

KisConfigWidget * KisWebPExport::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 116 of file kis_webp_export.cpp.

117{
118 return new KisWdgOptionsWebP(parent);
119}

◆ defaultConfiguration()

KisPropertiesConfigurationSP KisWebPExport::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 51 of file kis_webp_export.cpp.

52{
54 WebPConfig preset {};
55
56 if (!WebPConfigInit(&preset)) {
57 return cfg;
58 }
59
60 if (!WebPConfigLosslessPreset(&preset, 6)) {
61 return cfg;
62 }
63
64 preset.thread_level = 1;
65
66 if (!WebPValidateConfig(&preset)) {
67 return cfg;
68 }
69
70 cfg->setProperty("haveAnimation", true);
71
72 cfg->setProperty("preset", 0);
73 cfg->setProperty("lossless", preset.lossless == 1);
74 cfg->setProperty("quality", preset.quality);
75 cfg->setProperty("method", preset.method);
76 cfg->setProperty("dithering", true);
77 cfg->setProperty("force_srgb", false);
78 cfg->setProperty("save_profile", true);
79
80 cfg->setProperty("target_size", preset.target_size);
81 cfg->setProperty("target_PSNR", preset.target_PSNR);
82 cfg->setProperty("segments", preset.segments);
83 cfg->setProperty("sns_strength", preset.sns_strength);
84 cfg->setProperty("filter_strength", preset.filter_strength);
85 cfg->setProperty("filter_sharpness", preset.filter_sharpness);
86 cfg->setProperty("filter_type", preset.filter_type);
87 cfg->setProperty("autofilter", preset.autofilter == 1);
88 cfg->setProperty("alpha_compression", preset.alpha_compression);
89 cfg->setProperty("alpha_filtering", preset.alpha_filtering);
90 cfg->setProperty("alpha_quality", preset.alpha_quality);
91 cfg->setProperty("pass", preset.pass);
92 cfg->setProperty("show_compressed", preset.show_compressed == 1);
93 cfg->setProperty("preprocessing", preset.preprocessing);
94 cfg->setProperty("partitions", preset.partitions);
95 cfg->setProperty("partition_limit", preset.partition_limit);
96 cfg->setProperty("emulate_jpeg_size", preset.emulate_jpeg_size == 1);
97 cfg->setProperty("thread_level", preset.thread_level > 0);
98 cfg->setProperty("low_memory", preset.low_memory == 1);
99 cfg->setProperty("near_lossless", preset.near_lossless);
100 cfg->setProperty("exact", preset.exact == 1);
101 cfg->setProperty("use_sharp_yuv", preset.use_sharp_yuv == 1);
102#if WEBP_ENCODER_ABI_VERSION >= 0x020f
103 cfg->setProperty("qmin", preset.qmin);
104 cfg->setProperty("qmax", preset.qmax);
105#endif
106
107 cfg->setProperty("exif", true);
108 cfg->setProperty("xmp", true);
109 cfg->setProperty("iptc", true);
110 cfg->setProperty("storeMetaData", false);
111 cfg->setProperty("filters", "");
112
113 return cfg;
114}

◆ initializeCapabilities()

void KisWebPExport::initializeCapabilities ( )
overridevirtual

Reimplemented from KisImportExportFilter.

Definition at line 631 of file kis_webp_export.cpp.

632{
634 ->get("AnimationCheck")
637 ->get("IntegralFrameDurationCheck")
640 ->get("sRGBProfileCheck")
643 ->get("ExifCheck")
646 ->get("MultiLayerCheck")
649 ->get("TiffExifCheck")
651 // XXX: add check for IPTC metadata and mark as UNSUPPORTED by the standard.
652 QList<QPair<KoID, KoID>> supportedColorModels;
653 supportedColorModels << QPair<KoID, KoID>() << QPair<KoID, KoID>(RGBAColorModelID, Integer8BitsColorDepthID);
654 addSupportedColorModels(supportedColorModels, "WebP");
655}
VertexDescriptor get(PredecessorMap const &m, VertexDescriptor v)
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(), get(), KisExportCheckRegistry::instance(), Integer8BitsColorDepthID, KisExportCheckBase::PARTIALLY, RGBAColorModelID, and KisExportCheckBase::SUPPORTED.


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