From 1bf5692d3f2215e7e147a529aec07b009cf19587 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 15 Aug 2025 12:43:12 +0200 Subject: [PATCH] HEIF: Resolve primary image index from image source The primary image, in the case of multi-image sources, may not necessarily be the first image. Test images produced with patched version of enc-heif that allowed overriding the primary image. The correct primary image is green, while the other image is red. Pick-to: 6.10 Change-Id: Iba26b13fdb4898d7babc5fb173ad38b16f864e80 Reviewed-by: Volker Hilsheimer --- .../imageformats/shared/qiiofhelpers.cpp | 9 +++++--- tests/auto/heif/CMakeLists.txt | 2 ++ tests/auto/heif/tst_qheif.cpp | 20 ++++++++++++++++++ tests/shared/images/heif/primary-index-0.heic | Bin 0 -> 3275 bytes tests/shared/images/heif/primary-index-1.heic | Bin 0 -> 3275 bytes 5 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 tests/shared/images/heif/primary-index-0.heic create mode 100644 tests/shared/images/heif/primary-index-1.heic diff --git a/src/plugins/imageformats/shared/qiiofhelpers.cpp b/src/plugins/imageformats/shared/qiiofhelpers.cpp index 312f64e8..b96fc079 100644 --- a/src/plugins/imageformats/shared/qiiofhelpers.cpp +++ b/src/plugins/imageformats/shared/qiiofhelpers.cpp @@ -114,8 +114,10 @@ bool QIIOFHelper::initRead() cgImageSource = CGImageSourceCreateWithDataProvider(cgDataProvider, nullptr); - if (cgImageSource) - cfImageDict = CGImageSourceCopyPropertiesAtIndex(cgImageSource, 0, nullptr); + if (cgImageSource) { + auto primaryIndex = CGImageSourceGetPrimaryImageIndex(cgImageSource); + cfImageDict = CGImageSourceCopyPropertiesAtIndex(cgImageSource, primaryIndex, nullptr); + } return (cgImageSource); } @@ -125,7 +127,8 @@ bool QIIOFHelper::readImage(QImage *out) if (!out || !initRead()) return false; - QCFType cgImage = CGImageSourceCreateImageAtIndex(cgImageSource, 0, nullptr); + auto primaryIndex = CGImageSourceGetPrimaryImageIndex(cgImageSource); + QCFType cgImage = CGImageSourceCreateImageAtIndex(cgImageSource, primaryIndex, nullptr); if (!cgImage) return false; diff --git a/tests/auto/heif/CMakeLists.txt b/tests/auto/heif/CMakeLists.txt index 3fc310ee..48e97be1 100644 --- a/tests/auto/heif/CMakeLists.txt +++ b/tests/auto/heif/CMakeLists.txt @@ -16,6 +16,8 @@ qt_internal_add_test(tst_qheif set(heif_resource_files "../../shared/images/heif/col320x480.heic" "../../shared/images/heif/newlogoCCW.heic" + "../../shared/images/heif/primary-index-0.heic" + "../../shared/images/heif/primary-index-1.heic" ) qt_internal_add_resource(tst_qheif "heif" diff --git a/tests/auto/heif/tst_qheif.cpp b/tests/auto/heif/tst_qheif.cpp index 7c90d91f..be0af576 100644 --- a/tests/auto/heif/tst_qheif.cpp +++ b/tests/auto/heif/tst_qheif.cpp @@ -15,6 +15,9 @@ private slots: void readProperties_data(); void readProperties(); void writeImage(); + + void primaryIndex_data(); + void primaryIndex(); }; void tst_qheif::initTestCase() @@ -123,5 +126,22 @@ void tst_qheif::writeImage() } } +void tst_qheif::primaryIndex_data() +{ + QTest::addColumn("primaryIndex"); + + QTest::newRow("0 (first/default)") << 0; + QTest::newRow("1 (second)") << 1; +} + +void tst_qheif::primaryIndex() +{ + QFETCH(int, primaryIndex); + + QImage image(QString(":/heif/primary-index-%1.heic").arg(primaryIndex)); + QVERIFY(!image.isNull()); + QCOMPARE(image.pixelColor(50, 50), QColor(Qt::green)); +} + QTEST_MAIN(tst_qheif) #include "tst_qheif.moc" diff --git a/tests/shared/images/heif/primary-index-0.heic b/tests/shared/images/heif/primary-index-0.heic new file mode 100644 index 0000000000000000000000000000000000000000..f2a86b9d583235907d135b486dfba4b366cd58cb GIT binary patch literal 3275 zcmeHIU1%It6uz^wN!MV1un|E;#ucTs-JRJ@woQiJZE&~hOEAsS*-)F(IXP$ZC$M_)G zgXVsBY6<{}GWWG9O};O{PJ30OX4Tc23-XFQi#4Zo9X7sBuD)85Uuu6W)b%5Rkq77O2R%)@tS<(=i=d&BlF z?>OS!_;UTFALdp9+^zYw;G4Vl*wnd4-<&9&{r%hA<;k%pSHCG9{AKn8JowKNyK0`F zWTWvFL_|hM$$l6Tq?fw~AHqKkcR$Nm%>L)N2b%L2xqX2RBp;VywXhd#s;4PCHQK{Y ztUU!iuGu(7U9F}oj$sL7mLUwJ4}&JY5N96xVgA`7%Uyr>#aPo@Wsz^q!H#65Y)+Pj zfR}97;=R zDOv0j1R)P4A|ES15x`+pNKQMBDT`vG(MUH2(uVc2m>C`(7NxA1&8EO2WzW_f#ZA@i zM|>xtpR#7F7B#W-1oW#+88c2HnZ%8n&5zTe)z(gRJI#VltA;M3M$Duou^UW-vTp{s z35J^6!r+d&qg=)GLF_X881oo`JaJ63joJ*JrFb|iK@&6B=UIT8)UD(B(D6G%qw02O z3;ArFI>l_TTbsBY^|VDbco7zBCV)g`5qrEQndRg}8Q8LJ6;$j4WLS;GJ}B6b^FEpIycKU|Y9`_ zzjpDjIq%Z?$nG0U>qoBKI?ouh(PGRCC;sQW{|@JElf1S`m0RPyuGRl9^8(}9lA)WH zW-}hj1>6;tMQWGXN7=IrFGtnw&^8wR=gIYN{Ba=fMLA~+yafMR`3~Cbpx6N^N{*Z8 QIC4+TFt$mtTjR(-0rB5>^#A|> literal 0 HcmV?d00001 diff --git a/tests/shared/images/heif/primary-index-1.heic b/tests/shared/images/heif/primary-index-1.heic new file mode 100644 index 0000000000000000000000000000000000000000..4014136b0cb23e70459bee6301743faafddc91c9 GIT binary patch literal 3275 zcmeHI-D@0G6u+~xN!MUMun|E;#ucTs-JO|DwoQiJZE&~hOEAb^yHO%Y5xhG) z_ug~P@0@c#&Tj}Ik5=4SYg(rsfo9N(jAMhU6+&Vk8M>>Y9NOd4<*FSF39+c=hU2i` zWl`5)lQ_KJqE%DFS!smy5)MbPuYw+iXGsht{L!Xlh43he?+hjU6@q@qj;o;rP(3I~ z(57Ssd_%iW4ki4jFg;Ic4bq2(+6Q5xvv82b^qZQDicrX5B1b*S%=b4eIn2eNhE7z= zs!~mLsaX^4a^-+$R1w{TL&DvBLYkdEA(y}O`4hEl3w$q8OEaOLg!;wkw*0|T<9WyN zudR*jzO%S?!9K3PP`Z4P1RYP@6TNtxVVIX}NH1YX3^Ux3DFBjO|4Wci^n%>F_d}|DLBqL?A ziZrCiSwWVRY(^P8L~@?u85Wkj0QbD+C|*9Pmdz<$fia53q`*wvH}c8x(J`TD+PZKk zEv2Pop-&Km9F&N1tn^F+4zql6+I1~O6zlbRx;~IL?bk(lcz9TpGGZo^0*jP0TXR(} zRdb#QoP>T#x}(|D!qOAauR3MUxcOuf12tQarw;Yoj8t>dEa|jn8X{^$IW39ZU@om} z0YlA}FxaE+!93LpKx{LD9CMg~!p?1?1dLL1U_Av{l5#A!4oz!y5#;!m$cQF_#PpS- zX;`-Iuz1;=*dc4TA3vr$W_1SlyKp!oK@%ZOOq4;R>UL-g`C^T_g-ip|CT>SPZ&MwP zo&}T}kf^NPexl{CTY^z_1PZ666m1=A=D2BA3!NpD6WeXt;G=N$fq2xC>gok7oRl<_ zlC#ILa0ZkC>420`aG%i4CfhbYEDgPz7c9T1mxyJHy1D^d%yqp9C>}m5&zCNYp?wIgBN@R&>$eO4MAebH>foj>(0fW<_k#aBh^T|KHq*_&MOyF)%(Zjt KHu!gYocAXb@p*^< literal 0 HcmV?d00001