File indexing completed on 2025-03-09 04:09:35

0001 /*
0002  * SPDX-FileCopyrightText: 2019 Agata Cacko <cacko.azh@gmail.com>
0003  * SPDX-FileCopyrightText: 2021 Wolthera van Hövell tot Westerflier <griffinvalley@gmail.com>
0004  *
0005  *  SPDX-License-Identifier: GPL-2.0-or-later
0006  */
0007 
0008 #include "KisHeifTest.h"
0009 
0010 
0011 #include <simpletest.h>
0012 #include <QCoreApplication>
0013 #include <KoColorSpaceEngine.h>
0014 
0015 #include "filestest.h"
0016 
0017 #ifndef FILES_DATA_DIR
0018 #error "FILES_DATA_DIR not set. A directory with the data used for testing the importing of files in krita"
0019 #endif
0020 
0021 
0022 const QString HeifMimetype = "image/heic";
0023 const QString AvifMimetype = "image/avif";
0024 
0025 
0026 
0027 void KisHeifTest::testImportFromWriteonly()
0028 {
0029     TestUtil::testImportFromWriteonly(HeifMimetype);
0030     TestUtil::testImportFromWriteonly(AvifMimetype);
0031 }
0032 
0033 
0034 void KisHeifTest::testExportToReadonly()
0035 {
0036     TestUtil::testExportToReadonly(HeifMimetype);
0037     TestUtil::testExportToReadonly(AvifMimetype);
0038 }
0039 
0040 
0041 void KisHeifTest::testImportIncorrectFormat()
0042 {
0043     TestUtil::testImportIncorrectFormat(HeifMimetype);
0044     TestUtil::testImportIncorrectFormat(AvifMimetype);
0045 }
0046 
0047 void KisHeifTest::testLoadMonochrome(int bitDepth)
0048 {
0049     {
0050         QString file = QString("test_monochrome_%1.").arg(bitDepth);
0051         int error = 2;
0052         if (bitDepth == 10) {
0053             file = QString(FILES_DATA_DIR) + file;
0054             error = 25;
0055         }
0056         qDebug() << "Loading test for" << file;
0057         QScopedPointer<KisDocument> doc_png(KisPart::instance()->createDocument());
0058         doc_png->setFileBatchMode(true);
0059         QScopedPointer<KisDocument> doc_heif(KisPart::instance()->createDocument());
0060         doc_heif->setFileBatchMode(true);
0061         QScopedPointer<KisDocument> doc_avif(KisPart::instance()->createDocument());
0062         doc_avif->setFileBatchMode(true);
0063 
0064         KisImportExportManager manager(doc_png.data());
0065 
0066         KisImportExportErrorCode loadingStatus = manager.importDocument(file + "png", QString());
0067         QVERIFY(loadingStatus.isOk());
0068         loadingStatus = KisImportExportManager(doc_heif.data()).importDocument(file + "heif", QString());
0069         QVERIFY(loadingStatus.isOk());
0070         loadingStatus = KisImportExportManager(doc_avif.data()).importDocument(file + "avif", QString());
0071         QVERIFY(loadingStatus.isOk());
0072 
0073         KisImageSP png_image = doc_png->image().toStrongRef();
0074         KisImageSP heif_image = doc_heif->image().toStrongRef();
0075         KisImageSP avif_image = doc_avif->image().toStrongRef();
0076 
0077         png_image->initialRefreshGraph();
0078         heif_image->initialRefreshGraph();
0079         avif_image->initialRefreshGraph();
0080 
0081         KoColor pngColor;
0082         KoColor heifColor;
0083         KoColor avifColor;
0084 
0085         for (int y = 0; y<png_image->height(); y++) {
0086             for (int x = 0; x<png_image->width(); x++) {
0087                 png_image->projection()->pixel(x, y, &pngColor);
0088                 heif_image->projection()->pixel(x, y, &heifColor);
0089                 avif_image->projection()->pixel(x, y, &avifColor);
0090 
0091                 QVERIFY2(pngColor.colorSpace()->differenceA(pngColor.data(), heifColor.data()) < error,
0092                          QString("Heif %5 gray color doesn't match PNG color, (%1, %2) %3 %4")
0093                          .arg(x).arg(y).arg(KoColor::toQString(pngColor)).arg(KoColor::toQString(heifColor)).arg(bitDepth).toLatin1());
0094                 QVERIFY2(pngColor.colorSpace()->differenceA(pngColor.data(), avifColor.data()) < error,
0095                          QString("Avif %5 gray color doesn't match PNG color, (%1, %2) %3 %4")
0096                          .arg(x).arg(y).arg(pngColor.toXML()).arg(avifColor.toXML()).arg(bitDepth).toLatin1());
0097                 QVERIFY2(avifColor.colorSpace()->differenceA(avifColor.data(), heifColor.data()) < error,
0098                          QString("Heif %5 gray color doesn't match Avif color, (%1, %2) %3 %4")
0099                          .arg(x).arg(y).arg(heifColor.toXML()).arg(heifColor.toXML()).arg(bitDepth).toLatin1());
0100             }
0101         }
0102     }
0103 }
0104 
0105 void KisHeifTest::testLoadRGB(int bitDepth)
0106 {
0107     {
0108         QString file = QString("test_rgba_%1.").arg(bitDepth);
0109         int error = 2;
0110         if (bitDepth == 10) {
0111             file = QString(FILES_DATA_DIR) + file;
0112             error = 25;
0113         }
0114         qDebug() << "Loading test for" << file;
0115         QScopedPointer<KisDocument> doc_png(KisPart::instance()->createDocument());
0116         doc_png->setFileBatchMode(true);
0117         QScopedPointer<KisDocument> doc_heif(KisPart::instance()->createDocument());
0118         doc_heif->setFileBatchMode(true);
0119         QScopedPointer<KisDocument> doc_avif(KisPart::instance()->createDocument());
0120         doc_avif->setFileBatchMode(true);
0121 
0122         KisImportExportManager manager(doc_png.data());
0123 
0124         KisImportExportErrorCode loadingStatus = manager.importDocument(file + "png", QString());
0125         QVERIFY(loadingStatus.isOk());
0126         loadingStatus = KisImportExportManager(doc_heif.data()).importDocument(file + "heif", QString());
0127         QVERIFY(loadingStatus.isOk());
0128         loadingStatus = KisImportExportManager(doc_avif.data()).importDocument(file + "avif", QString());
0129         QVERIFY(loadingStatus.isOk());
0130 
0131         KisImageSP png_image = doc_png->image().toStrongRef();
0132         KisImageSP heif_image = doc_heif->image().toStrongRef();
0133         KisImageSP avif_image = doc_avif->image().toStrongRef();
0134 
0135         png_image->initialRefreshGraph();
0136         heif_image->initialRefreshGraph();
0137         avif_image->initialRefreshGraph();
0138 
0139         KoColor pngColor(png_image->colorSpace());
0140         KoColor heifColor(png_image->colorSpace());
0141         KoColor avifColor(png_image->colorSpace());
0142 
0143         for (int y = 0; y<png_image->height(); y++) {
0144             for (int x = 0; x<png_image->width(); x++) {
0145                 png_image->projection()->pixel(x, y, &pngColor);
0146                 heif_image->projection()->pixel(x, y, &heifColor);
0147                 avif_image->projection()->pixel(x, y, &avifColor);
0148 
0149                 QVERIFY2(pngColor.colorSpace() == heifColor.colorSpace(), QString("%1 RGBA colorspace mismatch between png and heif").toLatin1());
0150                 QVERIFY2(pngColor.colorSpace() == avifColor.colorSpace(), QString("%1 RGBA colorspace mismatch between png and avif").toLatin1());
0151                 QVERIFY2(avifColor.colorSpace() == heifColor.colorSpace(), QString("%1 RGBA colorspace mismatch between avif and heif").toLatin1());
0152 
0153                 QVERIFY2(pngColor.colorSpace()->differenceA(pngColor.data(), heifColor.data()) < error, QString("%5 RGBA Heif color doesn't match PNG color, (%1, %2) %3 %4")
0154                          .arg(x).arg(y).arg(pngColor.toXML()).arg(heifColor.toXML()).arg(bitDepth).toLatin1());
0155                 QVERIFY2(pngColor.colorSpace()->differenceA(pngColor.data(), avifColor.data()) < error, QString("%5 RGBA Avif color doesn't match PNG color, (%1, %2) %3 %4")
0156                          .arg(x).arg(y).arg(pngColor.toXML()).arg(avifColor.toXML()).arg(bitDepth).toLatin1());
0157                 QVERIFY2(avifColor.colorSpace()->differenceA(avifColor.data(), heifColor.data()) < error, QString("%5 RGBA Heif color doesn't match Avif color, (%1, %2) %3 %4")
0158                          .arg(x).arg(y).arg(heifColor.toXML()).arg(heifColor.toXML()).arg(bitDepth).toLatin1());
0159             }
0160         }
0161     }
0162 }
0163 
0164 void KisHeifTest::testSaveHDR()
0165 {
0166     const KoColorSpace * cs =
0167         KoColorSpaceRegistry::instance()->colorSpace(
0168             RGBAColorModelID.id(),
0169             Float32BitsColorDepthID.id(),
0170                 KoColorSpaceRegistry::instance()->p2020G10Profile());
0171 
0172     KoColor fillColor(cs);
0173 
0174     int blockSize = 32;
0175     int width  = blockSize * 2;
0176     int height = blockSize * 2;
0177 
0178     {
0179         QScopedPointer<KisDocument> doc(KisPart::instance()->createDocument());
0180 
0181         KisImageSP image = new KisImage(0, width, height, cs, "png test");
0182         KisPaintLayerSP paintLayer0 = new KisPaintLayer(image, "paint0", OPACITY_OPAQUE_U8);
0183         QVector<float> channelValues(4);
0184 
0185         float total = float((blockSize-1) * (blockSize-1));
0186 
0187         for (int y=0; y<blockSize; y++) {
0188             for (int x=0; x<blockSize; x++) {
0189                 float value = float(x * y);
0190 
0191                 channelValues[0] = value;
0192                 channelValues[1] = total-value;
0193                 channelValues[2] = total-value;
0194                 channelValues[3] = 1.0;
0195                 cs->fromNormalisedChannelsValue(fillColor.data(), channelValues);
0196                 paintLayer0->paintDevice()->setPixel(x, y, fillColor);
0197 
0198                 channelValues[1] = value;
0199                 channelValues[0] = total-value;
0200                 channelValues[2] = total-value;
0201                 channelValues[3] = 1.0;
0202                 cs->fromNormalisedChannelsValue(fillColor.data(), channelValues);
0203                 paintLayer0->paintDevice()->setPixel(width - (x+1), y, fillColor);
0204 
0205                 channelValues[2] = value;
0206                 channelValues[0] = total-value;
0207                 channelValues[1] = total-value;
0208                 channelValues[3] = 1.0;
0209                 cs->fromNormalisedChannelsValue(fillColor.data(), channelValues);
0210                 paintLayer0->paintDevice()->setPixel(x, height - (y+1), fillColor);
0211 
0212                 channelValues[3] = value/total;
0213                 channelValues[0] = 0.5;
0214                 channelValues[1] = 0.5;
0215                 channelValues[2] = 0.5;
0216                 cs->fromNormalisedChannelsValue(fillColor.data(), channelValues);
0217                 paintLayer0->paintDevice()->setPixel(width - (x+1), height - (y+1), fillColor);
0218             }
0219         }
0220 
0221         image->addNode(paintLayer0, image->root());
0222 
0223         image->waitForDone();
0224 
0225         KisImportExportManager manager(doc.data());
0226         doc->setFileBatchMode(true);
0227         doc->setCurrentImage(image);
0228 
0229         qDebug() << "Saving HDR PNG";
0230 
0231         KisPropertiesConfigurationSP pngExportConfiguration = new KisPropertiesConfiguration();
0232         pngExportConfiguration->setProperty("saveAsHDR", true);
0233         pngExportConfiguration->setProperty("saveSRGBProfile", true);
0234         pngExportConfiguration->setProperty("forceSRGB", false);
0235         QVERIFY(doc->exportDocumentSync(QString("test_rgba_hdr.png"), "image/png", pngExportConfiguration));
0236 
0237         qDebug() << "Saving HDR heif and avif for PQ";
0238         KisPropertiesConfigurationSP heifExportConfiguration = new KisPropertiesConfiguration();
0239         heifExportConfiguration->setProperty("quality", 100);
0240         heifExportConfiguration->setProperty("lossless", true);
0241         heifExportConfiguration->setProperty("chroma", "444");
0242         heifExportConfiguration->setProperty("floatingPointConversionOption", "Rec2100PQ");
0243         QVERIFY(doc->exportDocumentSync(QString("test_rgba_hdr_pq.heif"), "image/heic", heifExportConfiguration));
0244         QVERIFY(doc->exportDocumentSync(QString("test_rgba_hdr_pq.avif"), "image/avif", heifExportConfiguration));
0245 
0246         qDebug() << "Saving HDR heif and avif for HLG";
0247         heifExportConfiguration->setProperty("HLGnominalPeak", 1000.0);
0248         heifExportConfiguration->setProperty("HLGgamma", 1.2);
0249         heifExportConfiguration->setProperty("removeHGLOOTF", true);
0250         heifExportConfiguration->setProperty("floatingPointConversionOption", "Rec2100HLG");
0251         QVERIFY(doc->exportDocumentSync(QString("test_rgba_hdr_hlg.heif"), "image/heic", heifExportConfiguration));
0252         QVERIFY(doc->exportDocumentSync(QString("test_rgba_hdr_hlg.avif"), "image/avif", heifExportConfiguration));
0253 
0254         qDebug() << "Saving HDR heif and avif for SMPTE 428";
0255         heifExportConfiguration->setProperty("floatingPointConversionOption", "ApplySMPTE428");
0256         QVERIFY(doc->exportDocumentSync(QString("test_rgba_hdr_smpte428.heif"), "image/heic", heifExportConfiguration));
0257         QVERIFY(doc->exportDocumentSync(QString("test_rgba_hdr_smpte428.avif"), "image/avif", heifExportConfiguration));
0258     }
0259 }
0260 
0261 void KisHeifTest::testLoadHDR()
0262 {
0263     {
0264         QScopedPointer<KisDocument> doc_png(KisPart::instance()->createDocument());
0265         doc_png->setFileBatchMode(true);
0266         QScopedPointer<KisDocument> doc_avif_pq(KisPart::instance()->createDocument());
0267         doc_avif_pq->setFileBatchMode(true);
0268         QScopedPointer<KisDocument> doc_heif_pq(KisPart::instance()->createDocument());
0269         doc_heif_pq->setFileBatchMode(true);
0270 
0271         QScopedPointer<KisDocument> doc_avif_hlg(KisPart::instance()->createDocument());
0272         doc_avif_hlg->setFileBatchMode(true);
0273         QScopedPointer<KisDocument> doc_heif_hlg(KisPart::instance()->createDocument());
0274         doc_heif_hlg->setFileBatchMode(true);
0275 
0276         QScopedPointer<KisDocument> doc_avif_smpte428(KisPart::instance()->createDocument());
0277         doc_avif_smpte428->setFileBatchMode(true);
0278         QScopedPointer<KisDocument> doc_heif_smpte428(KisPart::instance()->createDocument());
0279         doc_heif_smpte428->setFileBatchMode(true);
0280 
0281         KisImportExportErrorCode loadingStatus =
0282             KisImportExportManager(doc_png.data()).importDocument(QString("test_rgba_hdr.png"), QString());
0283         QVERIFY(loadingStatus.isOk());
0284 
0285         qDebug() << "Loading test for PQ files";
0286         loadingStatus =
0287             KisImportExportManager(doc_avif_pq.data()).importDocument(QString("test_rgba_hdr_pq.avif"), QString());
0288         QVERIFY(loadingStatus.isOk());
0289         loadingStatus =
0290             KisImportExportManager(doc_heif_pq.data()).importDocument(QString("test_rgba_hdr_pq.heif"), QString());
0291         QVERIFY(loadingStatus.isOk());
0292 
0293         qDebug() << "Loading test for HLG files";
0294         loadingStatus =
0295             KisImportExportManager(doc_avif_hlg.data()).importDocument(QString("test_rgba_hdr_hlg.avif"), QString());
0296         QVERIFY(loadingStatus.isOk());
0297         loadingStatus =
0298             KisImportExportManager(doc_heif_hlg.data()).importDocument(QString("test_rgba_hdr_hlg.heif"), QString());
0299         QVERIFY(loadingStatus.isOk());
0300 
0301         qDebug() << "Loading test for smpte428 files";
0302         loadingStatus = KisImportExportManager(doc_avif_smpte428.data())
0303                             .importDocument(QString("test_rgba_hdr_smpte428.avif"), QString());
0304         QVERIFY(loadingStatus.isOk());
0305         loadingStatus = KisImportExportManager(doc_heif_smpte428.data())
0306                             .importDocument(QString("test_rgba_hdr_smpte428.heif"), QString());
0307         QVERIFY(loadingStatus.isOk());
0308 
0309         QVERIFY(doc_png->image());
0310         QVERIFY(doc_heif_pq->image());
0311         QVERIFY(doc_avif_pq->image());
0312         QVERIFY(doc_avif_smpte428->image());
0313         QVERIFY(doc_heif_smpte428->image());
0314         QVERIFY(doc_avif_hlg->image());
0315         QVERIFY(doc_heif_hlg->image());
0316 
0317         KisImageSP png_image = doc_png->image().toStrongRef();
0318         KisImageSP heif_image_pq = doc_heif_pq->image().toStrongRef();
0319         KisImageSP avif_image_pq = doc_avif_pq->image().toStrongRef();
0320         KisImageSP avif_image_smpte428 = doc_avif_smpte428->image().toStrongRef();
0321         KisImageSP heif_image_smpte428 = doc_heif_smpte428->image().toStrongRef();
0322         KisImageSP avif_image_hlg = doc_avif_hlg->image().toStrongRef();
0323         KisImageSP heif_image_hlg = doc_heif_hlg->image().toStrongRef();
0324 
0325         png_image->initialRefreshGraph();
0326         avif_image_pq->initialRefreshGraph();
0327         heif_image_pq->initialRefreshGraph();
0328 
0329         avif_image_hlg->initialRefreshGraph();
0330         heif_image_hlg->initialRefreshGraph();
0331 
0332         avif_image_smpte428->initialRefreshGraph();
0333         heif_image_smpte428->initialRefreshGraph();
0334 
0335         const KoColorSpace * cs =
0336             KoColorSpaceRegistry::instance()->colorSpace(
0337                 RGBAColorModelID.id(),
0338                 Float32BitsColorDepthID.id(),
0339                     KoColorSpaceRegistry::instance()->p2020G10Profile());
0340         png_image->convertImageColorSpace(cs, KoColorConversionTransformation::internalRenderingIntent(), KoColorConversionTransformation::internalConversionFlags());
0341         png_image->waitForDone();
0342 
0343         KoColor pngColor(cs);
0344         KoColor heifColor(cs);
0345         KoColor avifColor(cs);
0346 
0347         for (int y = 0; y<png_image->height(); y++) {
0348             for (int x = 0; x<png_image->width(); x++) {
0349                 png_image->projection()->pixel(x, y, &pngColor);
0350                 heif_image_pq->projection()->pixel(x, y, &heifColor);
0351                 avif_image_pq->projection()->pixel(x, y, &avifColor);
0352 
0353                 // PNG file experiences alpha sampling to 16i-bits, so use differenceA for comparison
0354                 QVERIFY2(cs->differenceA(pngColor.data(), avifColor.data()) <1, QString("Avif PQ color doesn't match PNG color, (%1, %2) %3 %4")
0355                          .arg(x).arg(y).arg(pngColor.toXML()).arg(avifColor.toXML()).toLatin1());
0356 
0357                 // PNG file experiences alpha sampling to 16i-bits, so use differenceA for comparison
0358                 QVERIFY2(cs->differenceA(pngColor.data(), heifColor.data()) <1, QString("Heif PQ color doesn't match PNG color, (%1, %2) %3 %4")
0359                          .arg(x).arg(y).arg(pngColor.toXML()).arg(heifColor.toXML()).toLatin1());
0360 
0361                 // compare HEIF and AVIF strictly
0362                 QVERIFY2(cs->difference(heifColor.data(), avifColor.data()) <1, QString("Heif PQ color doesn't match AVIF color, (%1, %2) %3 %4")
0363                          .arg(x).arg(y).arg(heifColor.toXML()).arg(avifColor.toXML()).toLatin1());
0364 
0365 
0366                 heif_image_hlg->projection()->pixel(x, y, &heifColor);
0367                 avif_image_hlg->projection()->pixel(x, y, &avifColor);
0368 
0369                 QVERIFY2(cs->difference(heifColor.data(), avifColor.data()) <1, QString("Avif HLG color doesn't match heif color, (%1, %2) %3 %4")
0370                          .arg(x).arg(y).arg(heifColor.toXML()).arg(avifColor.toXML()).toLatin1());
0371 
0372                 heif_image_smpte428->projection()->pixel(x, y, &heifColor);
0373                 avif_image_smpte428->projection()->pixel(x, y, &avifColor);
0374 
0375                 QVERIFY2(cs->difference(heifColor.data(), avifColor.data()) <1, QString("Avif smpte428 color doesn't match heif color, (%1, %2) %3 %4")
0376                          .arg(x).arg(y).arg(heifColor.toXML()).arg(avifColor.toXML()).toLatin1());
0377             }
0378         }
0379     }
0380 }
0381 
0382 void KisHeifTest::testSaveMonochrome(int bitDepth)
0383 {
0384     qDebug() << "Testing saving monochrome for" << bitDepth;
0385     QString depth = Integer8BitsColorDepthID.id();
0386     if (bitDepth != 8) {
0387         depth = Integer16BitsColorDepthID.id();
0388     }
0389 
0390     const KoColorSpace * cs =
0391         KoColorSpaceRegistry::instance()->colorSpace(
0392             GrayAColorModelID.id(),
0393             depth);
0394 
0395     KoColor fillColor(cs);
0396 
0397     int blockSize = 32;
0398     int width  = blockSize * 2;
0399     int height = blockSize;
0400 
0401     {
0402         QScopedPointer<KisDocument> doc(KisPart::instance()->createDocument());
0403 
0404         KisImageSP image = new KisImage(0, width, height, cs, "png test");
0405         KisPaintLayerSP paintLayer0 = new KisPaintLayer(image, "paint0", OPACITY_OPAQUE_U8);
0406         QVector<float> channelValues(2);
0407 
0408         for (int y=0; y<blockSize; y++) {
0409             for (int x=0; x<blockSize; x++) {
0410                 float value = float(x * y) / float((blockSize-1) * (blockSize-1));
0411 
0412                 channelValues[0] = value;
0413                 channelValues[1] = 1.0;
0414                 cs->fromNormalisedChannelsValue(fillColor.data(), channelValues);
0415 
0416                 paintLayer0->paintDevice()->setPixel(x, y, fillColor);
0417                 channelValues[1] = value;
0418                 channelValues[0] = 0.5;
0419                 cs->fromNormalisedChannelsValue(fillColor.data(), channelValues);
0420                 paintLayer0->paintDevice()->setPixel(width - (x+1), y, fillColor);
0421             }
0422         }
0423 
0424         image->addNode(paintLayer0, image->root());
0425 
0426         image->waitForDone();
0427 
0428         KisImportExportManager manager(doc.data());
0429         doc->setFileBatchMode(true);
0430         doc->setCurrentImage(image);
0431 
0432         KisPropertiesConfigurationSP pngExportConfiguration = new KisPropertiesConfiguration();
0433         pngExportConfiguration->setProperty("saveAsHDR", false);
0434         pngExportConfiguration->setProperty("saveSRGBProfile", false);
0435         pngExportConfiguration->setProperty("forceSRGB", false);
0436 
0437         KisPropertiesConfigurationSP heifExportConfiguration = new KisPropertiesConfiguration();
0438         heifExportConfiguration->setProperty("quality", 100);
0439         heifExportConfiguration->setProperty("lossless", true);
0440         doc->exportDocumentSync(QString("test_monochrome_%1.png").arg(bitDepth), "image/png", pngExportConfiguration);
0441         doc->exportDocumentSync(QString("test_monochrome_%1.heif").arg(bitDepth), "image/heic", heifExportConfiguration);
0442         doc->exportDocumentSync(QString("test_monochrome_%1.avif").arg(bitDepth), "image/avif", heifExportConfiguration);
0443 
0444     }
0445 }
0446 
0447 void KisHeifTest::testSaveRGB(int bitDepth)
0448 {
0449     qDebug() << "Testing saving RGBA for" << bitDepth;
0450     QString depth = Integer8BitsColorDepthID.id();
0451     if (bitDepth != 8) {
0452         depth = Integer16BitsColorDepthID.id();
0453     }
0454 
0455     QString profileName;
0456 
0457     QVector<double> colorants;
0458     const KoColorProfile *testProfile = KoColorSpaceRegistry::instance()->profileFor(colorants
0459                                                                                      , PRIMARIES_SMPTE_240M
0460                                                                                      , TRC_SMPTE_240M);
0461     if (testProfile) {
0462         profileName = testProfile->name();
0463     }
0464 
0465     const KoColorSpace * cs =
0466         KoColorSpaceRegistry::instance()->colorSpace(
0467             RGBAColorModelID.id(),
0468             depth, profileName);
0469 
0470     KoColor fillColor(cs);
0471 
0472     int blockSize = 32;
0473     int width  = blockSize * 2;
0474     int height = blockSize * 2;
0475 
0476     {
0477         QScopedPointer<KisDocument> doc(KisPart::instance()->createDocument());
0478 
0479         KisImageSP image = new KisImage(0, width, height, cs, "png test");
0480         KisPaintLayerSP paintLayer0 = new KisPaintLayer(image, "paint0", OPACITY_OPAQUE_U8);
0481         QVector<float> channelValues(4);
0482 
0483         for (int y=0; y<blockSize; y++) {
0484             for (int x=0; x<blockSize; x++) {
0485                 float value = float(x * y) / float((blockSize-1) * (blockSize-1));
0486 
0487                 channelValues[0] = value;
0488                 channelValues[1] = 1.0-value;
0489                 channelValues[2] = 1.0-value;
0490                 channelValues[3] = 1.0;
0491                 cs->fromNormalisedChannelsValue(fillColor.data(), channelValues);
0492                 paintLayer0->paintDevice()->setPixel(x, y, fillColor);
0493 
0494                 channelValues[1] = value;
0495                 channelValues[0] = 1.0-value;
0496                 channelValues[2] = 1.0-value;
0497                 channelValues[3] = 1.0;
0498                 cs->fromNormalisedChannelsValue(fillColor.data(), channelValues);
0499                 paintLayer0->paintDevice()->setPixel(width - (x+1), y, fillColor);
0500 
0501                 channelValues[2] = value;
0502                 channelValues[0] = 1.0-value;
0503                 channelValues[1] = 1.0-value;
0504                 channelValues[3] = 1.0;
0505                 cs->fromNormalisedChannelsValue(fillColor.data(), channelValues);
0506                 paintLayer0->paintDevice()->setPixel(x, height - (y+1), fillColor);
0507 
0508                 channelValues[3] = value;
0509                 channelValues[0] = 0.5;
0510                 channelValues[1] = 0.5;
0511                 channelValues[2] = 0.5;
0512                 cs->fromNormalisedChannelsValue(fillColor.data(), channelValues);
0513                 paintLayer0->paintDevice()->setPixel(width - (x+1), height - (y+1), fillColor);
0514             }
0515         }
0516 
0517         image->addNode(paintLayer0, image->root());
0518 
0519         image->waitForDone();
0520 
0521         KisImportExportManager manager(doc.data());
0522         doc->setFileBatchMode(true);
0523         doc->setCurrentImage(image);
0524 
0525         KisPropertiesConfigurationSP pngExportConfiguration = new KisPropertiesConfiguration();
0526         pngExportConfiguration->setProperty("saveAsHDR", false);
0527         pngExportConfiguration->setProperty("saveSRGBProfile", true);
0528         pngExportConfiguration->setProperty("forceSRGB", false);
0529         doc->exportDocumentSync(QString("test_rgba_%1.png").arg(bitDepth), "image/png", pngExportConfiguration);
0530 
0531         KisPropertiesConfigurationSP heifExportConfiguration = new KisPropertiesConfiguration();
0532         heifExportConfiguration->setProperty("quality", 100);
0533         heifExportConfiguration->setProperty("lossless", true);
0534         heifExportConfiguration->setProperty("chroma", "444");
0535         doc->exportDocumentSync(QString("test_rgba_%1.heif").arg(bitDepth), "image/heic", heifExportConfiguration);
0536         doc->exportDocumentSync(QString("test_rgba_%1.avif").arg(bitDepth), "image/avif", heifExportConfiguration);
0537     }
0538 }
0539 
0540 void KisHeifTest::testImages()
0541 {
0542     testSaveMonochrome(8);
0543     testSaveMonochrome(12);
0544     testSaveRGB(8);
0545     testSaveRGB(12);
0546     testLoadRGB(8);
0547     testLoadRGB(10);
0548     testLoadRGB(12);
0549     testLoadMonochrome(8);
0550     testLoadMonochrome(10);
0551     testLoadMonochrome(12);
0552 }
0553 
0554 
0555 
0556 KISTEST_MAIN(KisHeifTest)
0557 
0558