From 219d9cb2c2fbe1097054dc59874d261bec7eec36 Mon Sep 17 00:00:00 2001 From: Mirco Miranda Date: Tue, 30 Jul 2024 22:46:52 +0000 Subject: [PATCH] JXL: added ImageTransformation option Let Qt rotate the image when the ImageAutotransform option is set to true. In tests it also solves the image size control with the value returned by the options with certain rotations. --- autotests/read/jxl/orientation6_notranfs.jxl | Bin 0 -> 13702 bytes .../read/jxl/orientation6_notranfs.jxl.json | 19 +++++ autotests/read/jxl/orientation6_notranfs.png | Bin 0 -> 22430 bytes autotests/readtest.cpp | 13 +-- autotests/templateimage.cpp | 15 ++-- autotests/templateimage.h | 17 +++- src/imageformats/jxl.cpp | 78 +++++++++++++++++- src/imageformats/jxl_p.h | 1 + 8 files changed, 126 insertions(+), 17 deletions(-) create mode 100644 autotests/read/jxl/orientation6_notranfs.jxl create mode 100644 autotests/read/jxl/orientation6_notranfs.jxl.json create mode 100644 autotests/read/jxl/orientation6_notranfs.png diff --git a/autotests/read/jxl/orientation6_notranfs.jxl b/autotests/read/jxl/orientation6_notranfs.jxl new file mode 100644 index 0000000000000000000000000000000000000000..c274d8996511e0c854332be6b7c5e133d7c6e962 GIT binary patch literal 13702 zcmV;1HF?Sa000b1SWF-d3Wo{+000zbba`-Ucx)g50001Lcx)g505xW6cx+?;3iu8_ zSs)}24+9eB0T9(#zLLhC*AdX85A z=NMgkmW)QDOV9E<$L03{AnR!B%tHRe>&%Q8GGH$+01WuQu(aYgJPdW6Si)rw6C0rg ziq@vG(%VdR7dR_Tm{uC4FEX0kTB|#V*jT16(Z22^^Z5kh~L2 z&EQT@7`Zu$D%yWhgiZi*y;pLCgx9;NzfBJv13Ys;N#zX7dd=_aE9G{mArKE$G4l)0E>kF@+}LUpJ5Fp;(z|J)aq(@+7KD z()vLGst>;M)0AADI)4)k zb1#aAQ4XDX-j<$eG$=8y1rjonuBTeqKd8D-M2_KiBZQ>WZ1FH&T*@`}bZpknmqI-O zx>tC$&mDWi9&=stZ2^vFaZaSSw{{Ye1P+=|nqm%Fy2UF9oFWCD)~dplU!2KOlYl9?z%ey8f~+o;@eHJ znjU9eV|zK9Y6b5xgcWmhz520Avl%R)su8V0KMCsg^6$yp#|Xh1m3x+pO%6bXV2`i4 zgGkhx|4R&aMLQdhq7#4P_A9?@lroVw9741tYnacFdCt5@b+-V0c3xCpSm(Q7Xirt1 ztD4UwSC5M0sf3!M0n&X;u*W=aFy7wKFtnD*@U^zsUrpZ@30stjN^u}FusA8aNFYrx zHy1U~$$gICa(76vdL!(>9vPHB6iZewQHNQw>pu6g>kAh^$}k(Jbhc7=RA!teHv}Oz zbHEL85@v|$Gw=-;`{F3gq@Yc9fR{eG8C1p=9V(}vb51s{y*TJ%#{fj8tqNGQ5)l;4 z-HYQ2SToT;n1F2zwa}i(DFudx=PvSJ)fBsw10sH@Xx4v8^@^v$6ZjMrRfLN+NhrKs zk|sb|&j9P+&`ChCzxLQG9NlUm3?l`e(APaQoQ_2P-lCO9q3MoEVM*G0I~EerlEVj z_*7eS$4W;YCJO08h*wZBy={eC@LrX5WR*GvRajvZ-xV{**8w^RL@}PsJ4R9Vl!)kR zl}x!!bVB~u?XVSv7I3gcdCk+eofWb1CHZHd@SZ`kO_AE(mDk9=C}Yn z)yx<83BcPl_sZ?41{@5`r*Ugx`aJrrNK(!$RXh4$N)&JAkmXJBDJV#CwQY})8Y$#M zBb?lr8hWXA*X1~7X?h^Wl4}l3Ny(BaUZ9uF83eayg2SkTYOYL6^GV#((1j#~sn zX!zwTSRfDps0si85DJtE1rmgLw}SIIKY}WRN*>&g9V5GuTfnDrO5>ypoNGjK&`2`_Iv2rjdX;q65#IM^@z1vJe$X7*Ta!gxal46G2-|*Pp`fk zI*4f?+2WI>?o0>LDF;eMy?+BYVAg3naDYibkr%;`2LMwdpCLXh2IO^y_TiZ470f7o z-^^~{Wu@6PsnEa;F=(-JQ$f#ZNZiH3j!>@d2{a{z;wG|aC&FYVrl5tLw;jp-sG=o> zxpO{qh^fDLkGBaxvcZ_?5Ji#vAz&dAi9{j>EU;KWBoaY{1p^ofu2hkgYuhd%N6$ze zQ)fbG*d(q1^5*Y&caz7sS7ljMRaNouxWjfK2(o$^6Zfju>q%tZWlZFuZdH|)B%-$4 zn?!B5wcBGP*sfJsZ7Yd)1!|F`Bpu@%hOO?B$K!F1kpWg!)w;F~o2bne2t$)`MM#sw zxw*Oj(mO6PDmGTGg+g2<{mte4zo`nSU8n;l@3?Mqfj$xa()mbI#>)E%H=HP_2L90^Wcun^MS2nv&)^xw36I+RV^Kl zXew~gr-nq_A7F-A)&Secftl4sTP-rXv-s~?^yR4nI;qQQH9P2fDLp7<0WbF7SfA_1 zzn3N4jmQ=>`34ZlJPCu2ZxeD8N*1k3XayrnIHGh<_9dKy`5x_^)f?odMtP8`RzbB!u_*jKa{v^bv8l#ve!}?cOs@k04 zsP|V^!uku(yq>c@CSU0iQv1yiFr(GF4H}IC!z{PXY(42h!)we2pOmJZnhLqxpR2M5Ab)Umn#(O`yHdXcGyKoFeJ@>05i<8u1*FP zd-|lWvmi^_o>#XW@|dVKvGHqgP@_?*&!c)5$!(zQPL*{u<(!KU*p#(S=F#Uijz;|> z63S*M$1^K~EA)_h2Pj0bHMJl`Xr4qxKVW+-1zDw17Gz^^_2NU3%$Z9{DywqMsh?Q< znR>WYUMsJkno@-%TcLf?ull6G#h(J34Cgx6l2g#b$a|HtS#ZZP%FSDr%VV)md9klE zd&f?7=ew!3V166KVK?j+@_?|eB^6$7{8}84GL%{H@hyKF#`VrqEky?H(bK`#45Jr7 zB9K|8>`{Q-h53S1QbB2bctT=q)I0+nzhU%N`dtPRkt7m?fEnT{4er6GGH-Ol|Kqtz ztm4)zH#br~Vekv{H*mUg4G+eL7^8q3>!$J4Q@zfIUHoVpoSGF9bHCIcR!DM23q!D{ z#;jIyIY(xYt~9Z{T3DLddDcrw_aO=8C3fWj9e>nnEevNpTE@{VBs&&}?$#dD<1`Cs zb6#!4`*7+eo_>1pF=xi;EA{;GtZzfSKx2sPU{2B~C;C}Vb|kB7wxDT2xd(IvF3B0BqbP9QNE{F~Fa zYm4?{MbP|BrV`xcklYX?G+u@Zsv}n{=ACP{;DwbcxBdZSjaPFLIz%ykLAbNE^4AL5 zZ~`$IFoYAM$WF*j9g!%k}<z#o0MnpM_9*Tr6eWqOT0EA zVf@mb%FBQs%nacIKO+S=0{oJZ-T|IqPG(>{1&saE#`-ypCIU=(-FPv8tOD|U(-KNr zULRu#P9`vmDW~cvF|FBFKul6sXUcOmlN=CGsuds=U&g(rY*@J=>>QpeCIOfwbDOxx zFfz4NAzYSQuN%r*W_vxHSiB{+)~CbGB7f`H$!i}+ayQ0KK9YU#yD|8fzy7=kubT43 zI+?&)mCD}1Hef8P{Fi@scvRkRYb!bg8JGLHWX!@;Qo!EpPJp(3 zNQ7UqK);WSI~`de9oLXAZGD+oOc~!F2v^rn7dDv9`5=c@aWAsY;rdc8&*4`ox#5%= z!{X6`-0;AJ>-XK~QWv71%N^NA!L^+LR9<}M~TYrb!#p9hDeM_`?}0tZl?V`K`ojG;7dmWtGM zf~=9Tzn+2c=v)NNkG{r=7(tvBtgZ_}6IVnzuDZMA7%tlYbOQ|&MASEQs!PT8wfUf2 zX7Rx;>04oODJ0bFjsta1nX^I1#R+V0# zafbpC3in$KCD%>lUaAPBEiSBTVoJ~e19|_t`=MN~qy`(_I~63%Da+6hdu&srbPn00 z<6-h_2c;rTmR=*AZ*?{wHzh|Qh5Pv6V%%_I1zn{C1(TwUC#>4DmNA=tBJ}atitA=J zowp!hF|u`faoMnb55x$wLY9z6pCTxO&>W`ud9U5AM?~m$<&%OFSI#QSUjNjNAF?ct z%AmqN!Yl7s!3IX6Gy^LB99;Be9T5zcJYeUAEK15=781CH*hMJ9F0035ZJZr|$`*b{ z^Zx>@1QAEQK;qOk92@P!&<4ihUa^hR>N&si$s~oK+6OJx9jZt|bZZbl47wLV&9zo! zVj;1Z1uE68<6q<-H))%0rFSQXoD&`9nvX;;Bc|rZYH}x`dmGM5N>Al}P|$r?R0zq_ z{a*$|g>o^&T`bL-n`q2bLNNUa%g_m<6q;_(X_f1~IMS{Y5)&6kF|PEw<;aKEHwP2} z4G=)rk*E|F{FWI|Q_zSwjbK0LX#1iYYR&3nSlim^-qm?;hiFb<-+;e+CNV}x6cwZw ziU^4d!znLrLJ;$O7TlsaJlgQQ9 z8p_<=sk*vDBHJLW7~v^un1c^yKhGwvb+Ela)!Diu3K;!RPURe4I3YTA=}=5eD%R1` z2d`mv%x}Vrr3ABL)wo{^1>kdJc{UIPo&B+(KiB@`(VnG8Y2uRoNh|IW{;}B1!qh)A9 zBmThhCG~G&&rUOhAp24ZNx~tgrpn_{CoW!@y~l`KRUb9Iy7}O48>@TqP+A#kBAgfF zkN?9{0pRy&Wl~4}eMGy*@F5!KbACm#-Dux9Dq=$b01Z95yz9pUhy+In*)V6b(945# zyv`evLmAt5f-vm_4VPV^xwBv9_Iq!q+aN_9W`I;(rKlDZf~}P^jB$E>XkoAHDAwWM z{9IF-l8yUZz=gHP1X9AYjS$r6FY9(=mZEHc1rr9gtZlpm8SITT#8iyUm4O~dFLODe!Zhpc6ULQQQ0f-6=d0e~?7;DL2 z)vfrRpWmoa(rdU6jtr$}F>yk5oNu?#3!;Y@?uHfHqffBe`3J{ujAh=A{=_f5&jPm; zbg2SFN^(>Le$b{Um7gN?Ul#+Y|&k9Tu?nR<|tp0nkz98a=ZVzw%=95a_ z=apRah(=%aqoZOUIl%)D$`GS>$#f{*nQtagwxz;CatN7v1l;JQcsp5u#c7qSANQC_puSi|JEaz|mgm+ERI-6#xha~9>2O-71tQ5c0-ztLXB z0KDF9PK0tm7;SlchtT)i4_Q*B(X2oeIcPV^R#Q-RF+cxL> zV%NOTuiQoQ#q3jpBGT^0f)}n)(5qfYI~D-`oWLgFx2z1s;^duXj1y({0Ac$GF~ccD zy{PB&CP-o39cDaa>1ieWZD+)!x+k+1>Ae;EVugVzv9W8Z7gdA%9kV*jKz-`rU(Dz8 zMBeZE0_IFDgh#vjq*1VK*af|yoh*1KAM(B=8{6UXr5fPSlcugh@-aibG8WqBuOZ(lv z_&RreyBNLRpTuW_L;#AKuOMz}4h`z2*_$KP0U2&^x0}W1h=SeR9%~vFj}L&A)ln*z zgPaFS+7?TtauNnXQA6jT@;MS*l3hR{KnX8Ta6g zKtWgOq>gG$M4XqP;29UWB~`951)^WEWiXNHnKgC?MihA=Ei;@22_kivKx*5Ug57Iu zzUAdVSq*5f-bX|TF{2jg3QsAQF0Rl)UJnTMAd9_S>HKB%^seZGTpS z6-@WT5H)}k9g|Q=mMjwpWPMz;Hn3W=MdBM~5uQh{-4HHL$qmBAY3JaD*Or@9RS&aj0s*!pB=k!Xuq%k`pO=@H=)e0jWz#KiCk4&N!xuxS5J;j{H# zMt~5Tml%`cH$Ks=UNr>+l{qBuBcVJ`=d^+|ln3g=ZPhvS*Msa{H=GDV0+>WNv|J8Sct|O()NOKmS-fGmiEze9)obG3$N-ysrqv~PBU_j<1$rksZ@~OW(k{+(zx(ifa5Uj%RRg=ifW|bF%3f__UH*GgBIYmAMCGD@zXa8#qc8Y7mVW(okgd@* zdjOTrqzbU{u#;Rpda)9fE=G1pxNy}4l>*l^PPo2MpRVd&jD86}*IEiiY~`Rct5DUF zRi-bJwWtTBh_uuftFfx1+1Z0q6YOGXm;Zte`lQ@;^9&}z|9NxJ6e6mXClheuA;I&p ziGKusSj-`Nx%Vw#F|@Cn1v@C2i3sQABW(!!2ffNc7%0(62E_zg`0sfdib9|$j|;na zjD&??N_97-A<{@%rV@)AF3W!YF@Tb!h=mdr*+Q;Jt6jo3S}p2Rz4#9lg)~>DDA;L- z!iUl`zj9hIedOK<=wR@{9a4=TSup5X0EOjK9QGV!C#VfRePEbSj{w0Mm_?0DS-o); zo>M;F`^7p_XE_4yqn^#gH(UxDDk$cbs>5m6K`UW@tBbpUkxP~_O(qK&I$&lZ%!Cv{ zaOZo${3g{>6}T2qkf}}hGqe+}EDS4xmD!R7rxD-Wza()f1@2I9pgKytQI@V2V&o$t z)vn-B*>WSUmpcotX}XTXZE=%a=+Io!fgU>E2ZSI2U_GeUq)Wn>agC&|mYR)0z>5&p z^a>yPM=Hx=4+vQ%Gg(%#nV-RsvI7Ct7?!Zz&tMIYMr0oc*aM^#w7@S(&|4}e3lfl7 z#K6>yrEqHw1py|nq}%rHO`emkXK2)Hbij_0!VKc`OL={IU4lG{1R|u+bg7k`C7k4P zBT$U7F^U>%_8KbXPm${occ8jvp_iICpfB7al}>Ccab)>pKub#|si-ANy-kMVfy$S) zG>izJh&jW#bcjvN(q>_M7rZWMhf(MA)02|m-*wK5w1pYv<13yYkAn~cQjWvPUEe9o zp$9apxc-y={I?NgVAiYKR-Au=Ie%gp65d!kZAA>JcC=XrpCI<7ODKe+SICVdB$ruu zWIQnX+D)8Mt}8H7clz&)x5{Ja*G}5fDWcH|O4u7nQOFh_TLm$j!<;sJF=ttQXOVPv zD9K~C(8r?)3JSj+R5gpMXH7+A4^zNIkkG-mGFdZP-L7n?!B*MWYy*=(Uhx{xp=ng& zviBHDe5S^r-NZc)!6s#q^_dk?ih>|joKuwk5C?xw?In;f!2*L&wzIT?*?Zd02KG$u zdGrYpiPO_lCx)c{^?UtYexBg3G@l8BYE1FV1b>V~*kQ1>i&29^y!N|x^fC5Lx=|-8 z^uZlMq%QyN;U?$#na18_Tt*#;c*wrOh#1Z#_&;Kv<=PHeW6(3?*}AB9Dk5i$cv-=< z4*;)leghs1mB+2&QHZzxn!Otx`c3Jp;_y4~O^Y=2h`Gtopw#%YjAgy(F<|rhCuIWv z8KY%$B|p(Zm#iRcThSeXjoEgeVXm*O#PEcSLNMlF#Ye|D^;noQ0zA4+c51PB4Ppfx zAK;ELA7N_Q!?p$uPny`P-gZSoL-sjs(qR&ktRV{MARwKF!M$B=5AWVPTpz{G=YKzK zhLI7FA1S_>xa{<13S5dGX-6H{Bo*y%4H2tH$b@xKAVgigHK{QfNZeGHNJZ%rK!a~e zQpn(xRQmy!&dT1awcDakHzELWc#LCX4x@!nF=wn&k}3@`8akypGlxq(-Z0?$_}E|K zbgT4uY>0OiBblmY*B7$hoq{tE*2t}o&k3m_9_=CM$=0|F$}-b zC(G~mn*jag2?4nBuVUc|6N137B!yvJc8;d#cmtpRhsNhy@T6%YQkY$sC=(UlEW?N} zdwi(zZVg1Q>(B)eQ8eyqT1%_&yZ&;K@y(){aL<$t8bdXML`-t5j!8cxaD@UMEPNdD6yrDY zuvL<@8uzRb5UWPHXOrP=7q}8m@&Nf>(e(tgI4+dX1<9uOW3K7xvSel~bclmpRPm6O z@xMjGw<&?}`;Ai%w$st93 zlj5*CCHv?Iao0#a|rOLZO-FJ7-7|C&PFS7EL&~&DoY(U9*c*&dH}34oq7=3)G8Fz3n-M z6}DH$7Lm%O0ehxHf!Hw~#>@wmzdm5OZG}XFNkP}0NWO^K5MJPX)FD&rCFVsO+&|13 z;A0p=b;sc$lfqF&D1SGs2Erw#7*S2(Byg&01`iiQHL0a9{8E!G=B3h+ptBnXXArUT z(2+eGqqm;fNc`p4swFIfcYbn(+_J_~_Ol$Qb__J*n<<;TqDqgx)MO;t4^%8*vWIzN+zO6Y1)8677}q4tvXls`Mb}@=K-+8 z-#DeN376zm>f|IslA}JNX<CwE;zd{4$dJ$2&)obS$uY2eDoYwgTN|I8?VH6`pN|Vzyw8XS zm5(AXYu&vJfU;{PR+r89aNZMIrlagas+G`?EmhKcX^Jyx4=DQsp&x^ZqF^n?Dgvg# z59ykw3l&f^7DW-8+Kd`Bt94F31sH?JoS&S*gc`8?fU$F_p05)C-$6ZAv z)+KSh01PoeY_>R__S~1*Q&OP&LU+VhhUA&g|AasKn8wdM101Gh{Hft$%;S1rv+U34nt{6*C4|m zWcr?Lt6VaTsi{D^5hvlBxOk{-S%GFs-`HZ#x?EYAtaEwR_+Fjlhq;jIWrocd={<#U z&;bCg-A4cz*L)1D2*t_*#wZhoV!#uD4>{RSVACuHaA8m%?@=wN;J86}ujA;e%3m5$ z$F0zrWVrDOj3-?^)E0rRKw))IwmNaEys4{ZQ{FtzAWNqyLHS=Q})5=04 zHq5b>@dp5imR(Yf9xDirP*JztT9Iwaa771lcW1$!IHuiT!7ws*4bF0p0kZkY?+Ogg5$gM1j|AcVqMA9VH)UpgIL43t8r`E)eVR{X?n13TbwAN8Pg@+nPBbfj;Lm&-I zyO3Iu7v*FKf}d2Gw`@ZI{CpmLuICY=&IM%xf~$@G-<%+FK;nfk=n#B1#5Pv>IBUYS zd;l~WKaQHwfVHB%*%(b6>IF_>5=tRmMHfkS*gfFBCXX$f#>66A3eS-bGm!cunzwDG zQ*47kUIzKrY@;{ZUXfHlZsJsGC1s^m~9L?JLl1Mrc}cVVbkUOd^xQx zH&awp<|FHinT!R}2atgBBn&Tt{8qT38Y-hP74qSjKZ2uc(1;9OI@Gc-Ax<%9SGQXK z042{BlwRfX1FrAQqJv)l&EPe(I~@~JAsk>Z!Db-=E2wwE#%4+;r(c5&)GK8z2G|-D z2D*xh&liOrwj_XaWpMvIko}k#ALS(BRCJIr5oX3jg3-ZR=_UIIt6LT*JRhKPY3R*y zS0QUx_`d0{(v2Au&5TIgF!IFm)sed_#P~LYd;Xpu`T*;(gO{;TF_qOWz5TtlAh*`- z-^hr)XcGt}g+0-_C$lm-+w$zB@zHNV=T3T-WvqV8RT-j)Fc@ffc+qp=#uFKRDgnp4?x>MW}t;J*i9Z*hJN^(gO;bq z$1!Yj33AUB^jYb=tKQsDo*&c#SIqW*VbLH)r4rw=iWr{L}@-X zTDZwjGKohCP#MZAW?rq9-J!G(RMCg0ZTvGFb1vSN9YXc|zt7R>aZL2yHlwEV%nc)g zE(DbZm}qodJgn-p8bwR2m81x8$bow4_k-7nLCRMSq=MuqVlMhMn+nS{KgriH^l5}CIYBCP57@OplG z$)g(ig}ginHzc(`GDvZ4O$`V$8Vv6_Ix3`L+>nHHx6%BE%FtMkw1uyDX<5y6l`P~nsxg4;rIGiWtkY1V zy`6IAHpxxA-&VwMn#@yr&L$HGAWaJWQ9O`g1&N>W7+HxADh${chKNoO8 z<*A6r!ZXeCJZYcaEaK8@EH)SrP{AY1HhWB9m2L4xi=@WJ3d4ukSi>lh#Koz^EE?y2 zWkHd+I4}cwlir?=kugt#d2$%dnHlcSCyZ$LSXrqyCNjQur7F-ZQv@J3l8}4_Y~^8( z);)}Cd5$aZ9!sm)BXQYQ_vY~QVuP5(kX%M2pGQP`807%`(1$wU;{=4r$u-15RJVhU zE~rPzId{bIF>bR3ZhdTt!U-sE#{AxGl&$v$Pzc18)0Yw9kRFeA<0!7kT#us@9{x`A z$aiE_n>6)7e9$p7xb!Py7X{lxxrmhnk85Zv$T{|Aj)gM(-BL#{T~PWi)UW-)Um)oi z(k0nr1zzA6M`trU&t*%jgCnvmc(qlgWieeZ{!&}MGKDhsXY5m+nj|o(-F`}cmDtb~ z3Vrt@zw=f^na?pO0T}{Pit-?hk8HRkVs^e(x80pM%m88lYV8$6Ns=LgCAHYMxy7_J^ z#Nzz{OU9W37TSWM_aU-}hq4VYSPlw^$&_$I;3e|8Z8c{z%-|539p|6xz*X${^c(`@ z9VyVkpf>{{057!7AJOKWFLr+TRMRIpU|!b>&--?K6bVt%HB;$m#ta06YM- zJ5tXgp>NbUL^S48P3EBkp4iO0o+?Qz-uerewGYoE>H>No4gQDouIfO!-+1YQZ8*c>Wx6z&x}(34 zJ0QPVJ{KUpk&i}()hts?L=Ootd)oDRHM@s$;K#Ca6>fceD;KVBko%gQOY;vgZH{v< zfTfgSbJT;&&ME+u!Ig;=D#!3;o6V+x$lAGwbX4ws)&)WlgefUj$C$_xO=c{D7bt`) zA?@;TK!-43E+(`=0#VjDSNB*PM{qEcA%Y_8Q@ocD&0S9>tA(6!jyH76ulM@R9jk)V zo2&(W9WnQ5@{WO*AU!1C(S3~R9wv#ZKUPya{=$ChJ}?`hN%Qf|0H!6mAR1MN_rY0k zNlT=3|bc}HO-)ka=)g|L5fL=nlXR4I|PT3Mf1c#BbPTAeTV^35r z1LsBt$hjMDq0wSfq%*ks*Vo?WT5w1aqJdnEt>N)1PfTm-8%($k)vn87Vkk-Q$k8t@ zlh=$LetelDZ{kvF&v}i3?2;CEn}2g0)9jeR2cZ

f|db-rM0S>NYhAo=F>JSuU2+!D}gCS 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 literal 0 HcmV?d00001 diff --git a/autotests/readtest.cpp b/autotests/readtest.cpp index a92dca2..07f030a 100644 --- a/autotests/readtest.cpp +++ b/autotests/readtest.cpp @@ -267,10 +267,13 @@ int main(int argc, char **argv) continue; } - bool skipTest = false; - QFileInfo expFileInfo = timg.compareImage(skipTest); - if (skipTest) { - QTextStream(stdout) << "SKIP : " << fi.fileName() << ": image format not supported by current Qt version!\n"; + TemplateImage::TestFlags flags = TemplateImage::None; + QString comment; + QFileInfo expFileInfo = timg.compareImage(flags, comment); + if ((flags & TemplateImage::SkipTest) == TemplateImage::SkipTest) { + if(comment.isEmpty()) + comment = QStringLiteral("image format not supported by current Qt version!"); + QTextStream(stdout) << "SKIP : " << fi.fileName() << QStringLiteral(": %1\n").arg(comment); ++skipped; continue; } @@ -291,7 +294,7 @@ int main(int argc, char **argv) QImage expImage; // inputImage is auto-rotated to final orientation - inputReader.setAutoTransform(true); + inputReader.setAutoTransform((flags & TemplateImage::DisableAutotransform) != TemplateImage::DisableAutotransform); if (!expReader.read(&expImage)) { QTextStream(stdout) << "ERROR: " << fi.fileName() << ": could not load " << expfilename << ": " << expReader.errorString() << "\n"; diff --git a/autotests/templateimage.cpp b/autotests/templateimage.cpp index 4aef330..0a29710 100644 --- a/autotests/templateimage.cpp +++ b/autotests/templateimage.cpp @@ -28,10 +28,10 @@ bool TemplateImage::isTemplate() const return false; } -QFileInfo TemplateImage::compareImage(bool &skipTest) const +QFileInfo TemplateImage::compareImage(TestFlags &flags, QString& comment) const { - auto fi = jsonImage(skipTest); - if (skipTest) { + auto fi = jsonImage(flags, comment); + if ((flags & TestFlag::SkipTest) == TestFlag::SkipTest) { return {}; } if (fi.exists()) { @@ -58,8 +58,9 @@ QFileInfo TemplateImage::legacyImage() const return {}; } -QFileInfo TemplateImage::jsonImage(bool &skipTest) const +QFileInfo TemplateImage::jsonImage(TestFlags &flags, QString& comment) const { + flags = TestFlag::None; auto fi = QFileInfo(QStringLiteral("%1.json").arg(m_fi.filePath())); if (!fi.exists()) { return {}; @@ -86,6 +87,10 @@ QFileInfo TemplateImage::jsonImage(bool &skipTest) const auto maxQt = QVersionNumber::fromString(obj.value("maxQtVersion").toString()); auto name = obj.value("fileName").toString(); auto unsupportedFormat = obj.value("unsupportedFormat").toBool(); + comment = obj.value("comment").toString(); + + if(obj.value("disableAutoTransform").toBool()) + flags |= TestFlag::DisableAutotransform; // filter if (name.isEmpty() && !unsupportedFormat) @@ -95,7 +100,7 @@ QFileInfo TemplateImage::jsonImage(bool &skipTest) const if (!maxQt.isNull() && currentQt > maxQt) continue; if (unsupportedFormat) { - skipTest = true; + flags |= TestFlag::SkipTest; break; } return QFileInfo(QStringLiteral("%1/%2").arg(fi.path(), name)); diff --git a/autotests/templateimage.h b/autotests/templateimage.h index b6bf350..1674c29 100644 --- a/autotests/templateimage.h +++ b/autotests/templateimage.h @@ -16,6 +16,13 @@ class TemplateImage { public: + enum TestFlag { + None = 0x0, + SkipTest = 0x1, + DisableAutotransform = 0x2 + }; + Q_DECLARE_FLAGS(TestFlags, TestFlag) + /*! * \brief TemplateImage * \param fi The image to test. @@ -42,10 +49,10 @@ public: /*! * \brief compareImage - * \param skipTest True if the test should be skipped (e.g. image format not supported by current Qt version). + * \param flags Flags for modifying test behavior (e.g. image format not supported by current Qt version). * \return The template image to use for the comparison. */ - QFileInfo compareImage(bool &skipTest) const; + QFileInfo compareImage(TestFlags &flags, QString& comment) const; /*! * \brief suffixes @@ -62,13 +69,15 @@ private: /*! * \brief jsonImage - * \param skipTest True if the test should be skipped (not supported). + * \param flags Flags for modifying test behavior. * \return The template image read from the corresponding JSON. */ - QFileInfo jsonImage(bool &skipTest) const; + QFileInfo jsonImage(TestFlags &flags, QString& comment) const; private: QFileInfo m_fi; }; +Q_DECLARE_OPERATORS_FOR_FLAGS(TemplateImage::TestFlags) + #endif // TEMPLATEIMAGE_H diff --git a/src/imageformats/jxl.cpp b/src/imageformats/jxl.cpp index 25220d1..ec021e6 100644 --- a/src/imageformats/jxl.cpp +++ b/src/imageformats/jxl.cpp @@ -16,11 +16,19 @@ #include #include +// Avoid rotation on buggy Qts (see also https://bugreports.qt.io/browse/QTBUG-126575) +#if (QT_VERSION >= QT_VERSION_CHECK(6, 5, 7) && QT_VERSION < QT_VERSION_CHECK(6, 6, 0)) || (QT_VERSION >= QT_VERSION_CHECK(6, 7, 3)) +#ifndef JXL_QT_AUTOTRANSFORM +#define JXL_QT_AUTOTRANSFORM +#endif +#endif + QJpegXLHandler::QJpegXLHandler() : m_parseState(ParseJpegXLNotParsed) , m_quality(90) , m_currentimage_index(0) , m_previousimage_index(-1) + , m_transformations(QImageIOHandler::TransformationNone) , m_decoder(nullptr) , m_runner(nullptr) , m_next_image_delay(0) @@ -129,6 +137,11 @@ bool QJpegXLHandler::ensureDecoder() return false; } +#ifdef JXL_QT_AUTOTRANSFORM + // Let Qt handle the orientation. + JxlDecoderSetKeepOrientation(m_decoder, true); +#endif + int num_worker_threads = QThread::idealThreadCount(); if (!m_runner && num_worker_threads >= 4) { /* use half of the threads because plug-in is usually used in environment @@ -568,10 +581,25 @@ bool QJpegXLHandler::write(const QImage &image) pixel_format.endianness = JXL_NATIVE_ENDIAN; pixel_format.align = 0; - output_info.orientation = JXL_ORIENT_IDENTITY; output_info.num_color_channels = 3; output_info.animation.tps_numerator = 10; output_info.animation.tps_denominator = 1; + output_info.orientation = JXL_ORIENT_IDENTITY; + if (m_transformations == QImageIOHandler::TransformationMirror) { + output_info.orientation = JXL_ORIENT_FLIP_HORIZONTAL; + } else if (m_transformations == QImageIOHandler::TransformationRotate180) { + output_info.orientation = JXL_ORIENT_ROTATE_180; + } else if (m_transformations == QImageIOHandler::TransformationFlip) { + output_info.orientation = JXL_ORIENT_FLIP_VERTICAL; + } else if (m_transformations == QImageIOHandler::TransformationFlipAndRotate90) { + output_info.orientation = JXL_ORIENT_TRANSPOSE; + } else if (m_transformations == QImageIOHandler::TransformationRotate90) { + output_info.orientation = JXL_ORIENT_ROTATE_90_CW; + } else if (m_transformations == QImageIOHandler::TransformationMirrorAndRotate90) { + output_info.orientation = JXL_ORIENT_ANTI_TRANSPOSE; + } else if (m_transformations == QImageIOHandler::TransformationRotate270) { + output_info.orientation = JXL_ORIENT_ROTATE_90_CCW; + } if (save_depth > 8) { // 16bit depth pixel_format.data_type = JXL_TYPE_UINT16; @@ -777,14 +805,24 @@ bool QJpegXLHandler::write(const QImage &image) QVariant QJpegXLHandler::option(ImageOption option) const { + if (!supportsOption(option)) { + return QVariant(); + } + if (option == Quality) { return m_quality; } - if (!supportsOption(option) || !ensureParsed()) { + if (!ensureParsed()) { +#ifdef JXL_QT_AUTOTRANSFORM + if (option == ImageTransformation) { + return int(m_transformations); + } +#endif return QVariant(); } + switch (option) { case Size: return QSize(m_basicinfo.xsize, m_basicinfo.ysize); @@ -794,9 +832,31 @@ QVariant QJpegXLHandler::option(ImageOption option) const } else { return false; } +#ifdef JXL_QT_AUTOTRANSFORM + case ImageTransformation: + if (m_basicinfo.orientation == JXL_ORIENT_IDENTITY) { + return int(QImageIOHandler::TransformationNone); + } else if (m_basicinfo.orientation == JXL_ORIENT_FLIP_HORIZONTAL) { + return int(QImageIOHandler::TransformationMirror); + } else if (m_basicinfo.orientation == JXL_ORIENT_ROTATE_180) { + return int(QImageIOHandler::TransformationRotate180); + } else if (m_basicinfo.orientation == JXL_ORIENT_FLIP_VERTICAL) { + return int(QImageIOHandler::TransformationFlip); + } else if (m_basicinfo.orientation == JXL_ORIENT_TRANSPOSE) { + return int(QImageIOHandler::TransformationFlipAndRotate90); + } else if (m_basicinfo.orientation == JXL_ORIENT_ROTATE_90_CW) { + return int(QImageIOHandler::TransformationRotate90); + } else if (m_basicinfo.orientation == JXL_ORIENT_ANTI_TRANSPOSE) { + return int(QImageIOHandler::TransformationMirrorAndRotate90); + } else if (m_basicinfo.orientation == JXL_ORIENT_ROTATE_90_CCW) { + return int(QImageIOHandler::TransformationRotate270); + } +#endif default: return QVariant(); } + + return QVariant(); } void QJpegXLHandler::setOption(ImageOption option, const QVariant &value) @@ -810,6 +870,14 @@ void QJpegXLHandler::setOption(ImageOption option, const QVariant &value) m_quality = 90; } return; +#ifdef JXL_QT_AUTOTRANSFORM + case ImageTransformation: + if (auto t = value.toInt()) { + if (t > 0 && t < 8) + m_transformations = QImageIOHandler::Transformations(t); + } + break; +#endif default: break; } @@ -818,7 +886,11 @@ void QJpegXLHandler::setOption(ImageOption option, const QVariant &value) bool QJpegXLHandler::supportsOption(ImageOption option) const { - return option == Quality || option == Size || option == Animation; + auto supported = option == Quality || option == Size || option == Animation; +#ifdef JXL_QT_AUTOTRANSFORM + supported = supported || option == ImageTransformation; +#endif + return supported; } int QJpegXLHandler::imageCount() const diff --git a/src/imageformats/jxl_p.h b/src/imageformats/jxl_p.h index 3e93808..1563012 100644 --- a/src/imageformats/jxl_p.h +++ b/src/imageformats/jxl_p.h @@ -64,6 +64,7 @@ private: int m_quality; int m_currentimage_index; int m_previousimage_index; + QImageIOHandler::Transformations m_transformations; QByteArray m_rawData;