From 9e6a7d974084a4d7b6be9d68b732558194d20e51 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Fri, 23 Dec 2022 17:43:18 +1100 Subject: [PATCH 1/4] Added support for uncompressed L images --- Tests/images/uncompressed_l.dds | Bin 0 -> 16512 bytes Tests/images/uncompressed_l.png | Bin 0 -> 861 bytes Tests/test_file_dds.py | 12 +++++++++-- src/PIL/DdsImagePlugin.py | 35 ++++++++++++++++++++++++-------- 4 files changed, 36 insertions(+), 11 deletions(-) create mode 100644 Tests/images/uncompressed_l.dds create mode 100644 Tests/images/uncompressed_l.png diff --git a/Tests/images/uncompressed_l.dds b/Tests/images/uncompressed_l.dds new file mode 100644 index 0000000000000000000000000000000000000000..b82282587ec30665fceafced278f1c59b3402ed1 GIT binary patch literal 16512 zcmeH}-EHGA5QLRH-P>I{2-3o};0}Uxa}TK}#ia!we>Mbmxid@IFa*O(Adcw~@eMx; zf=;LR*MHl#{rikdie4wCtD@J5$rZg$Odd=pyeTl@O@Rr&tAImS3LLsp;L!Id0QjK*;D-W$ zUsiB1AL2y-+`b5a+g}qv@T~yBw*myeRN!Df#TNl|`$YiV{(^u9=Lg$A2l~GQ{ow&5 zpBqU3+`zrxe;YskeE#v{zyA5p51_m@(gG!?cVO_^Sz~$wl>F9wR-n}<1zJu7v^@NP z24p2HAUP}$lKTZm^U(>6`arZRRKVo%R5fre zR}Gw8HE{BUpFaA4SDyNS`QJWZP6L6%3Ic}}1b$%!MXwXnRnhCjXRluPu1rA*)aOis!0Q^t@@IwK>FDp2h5Ah-ZZeIkz?XL+S_*Q`6TLFS!DsV8L z;)?*f{UU&Fe?h>5^Mmbw1o}^b{_p^j&kdx1Zs6YUzl|S%KL7afU;q5)2T)!cX@Qc{ zJ1}_dtTDX-N`7lTE70nb0xc&3S{{Bt1F{kpkQ^2W$^C+(`RD{jeIQ`uK)}f3FOCAW z$Z4Q*r-91D$yC6smsv0<#s|HT48aVmFPj7v|D_{D6`BNV-r-8s>1%bl~ z0>7|=qSuM(s_1oMaz(EblLylYZwgF!Q((gHD&WwS0*9^?IP^UV0DdR{_@MycmlYh$ zhjsv0<#s|HT4 t8aVmFPf`J1DHUKY6=0r08b||aAPuB}G>`_;KpIE`X&?=xfi!T4f&Vw%wVD6` literal 0 HcmV?d00001 diff --git a/Tests/images/uncompressed_l.png b/Tests/images/uncompressed_l.png new file mode 100644 index 0000000000000000000000000000000000000000..9d22a26a446d3dbdfd8f9c931ea466f6c6424e90 GIT binary patch literal 861 zcmeAS@N?(olHy`uVBq!ia0vp^4Is<`Bp9BB+KDqTFspdFIEGZrc^h?ls*<5Vur)JB zqlg-7P(pKyh(}`Z41qR*8_gT%*K1u(y=E67zCX-RIr5$RbYFRmk9~(3o90{0iTo?q zZokIPVc}P`n#F#$cTRI}Z`b*cHdxb-Qkj7%xN9XC&Z5~v}sUc zQF_LyDDi8i`mdSklfSkId~vT6XS8VuNn~8YHGhS2Q^L#RQrG)UyL@3X&}x&GB>;Tib{;+mb; z9E?oS*}aKX$Uxa5;eK2CjmcMXGaH^hIH47DKd5laQEeT@eua-ZO-D9&R()gjOuir% zvW=}bGBx``)z5EfnVi1_vX=2LOsg_|ey?EeT|36sB|Uh!dQU<13AVi4r5g)!U-!1I-}Y|HguFw3`xCAHw!QqqenxjbTuMSUDiOXag;?62vFzD;OU-N3|GNKs$H|s>F&hgWVD=Cdb6BTa*mH8 zSvtelvqpRLzjllcxGA-Tb?VxK$@jOLdwX91dKc*H#c{mLBht%bs(#FW&Mb`zE`Q|r X-moxli&n>DP`>eW^>bP0l+XkK*RXjv literal 0 HcmV?d00001 diff --git a/Tests/test_file_dds.py b/Tests/test_file_dds.py index 4b9f8949ef5..f579cd1c257 100644 --- a/Tests/test_file_dds.py +++ b/Tests/test_file_dds.py @@ -22,6 +22,7 @@ TEST_FILE_DX10_BC7_UNORM_SRGB = "Tests/images/DXGI_FORMAT_BC7_UNORM_SRGB.dds" TEST_FILE_DX10_R8G8B8A8 = "Tests/images/argb-32bpp_MipMaps-1.dds" TEST_FILE_DX10_R8G8B8A8_UNORM_SRGB = "Tests/images/DXGI_FORMAT_R8G8B8A8_UNORM_SRGB.dds" +TEST_FILE_UNCOMPRESSED_L = "Tests/images/uncompressed_l.dds" TEST_FILE_UNCOMPRESSED_RGB = "Tests/images/hopper.dds" TEST_FILE_UNCOMPRESSED_RGB_WITH_ALPHA = "Tests/images/uncompressed_rgb.dds" @@ -194,8 +195,14 @@ def test_unimplemented_dxgi_format(): pass -def test_uncompressed_rgb(): - """Check uncompressed RGB images can be opened""" +def test_uncompressed(): + """Check uncompressed images can be opened""" + with Image.open(TEST_FILE_UNCOMPRESSED_L) as im: + assert im.format == "DDS" + assert im.mode == "L" + assert im.size == (128, 128) + + assert_image_equal_tofile(im, "Tests/images/uncompressed_l.png") # convert -format dds -define dds:compression=none hopper.jpg hopper.dds with Image.open(TEST_FILE_UNCOMPRESSED_RGB) as im: @@ -305,6 +312,7 @@ def test_save_unsupported_mode(tmp_path): @pytest.mark.parametrize( ("mode", "test_file"), [ + ("L", "Tests/images/linear_gradient.png"), ("RGB", "Tests/images/hopper.png"), ("RGBA", "Tests/images/pil123rgba.png"), ], diff --git a/src/PIL/DdsImagePlugin.py b/src/PIL/DdsImagePlugin.py index eea6e31534c..b78cc649f13 100644 --- a/src/PIL/DdsImagePlugin.py +++ b/src/PIL/DdsImagePlugin.py @@ -135,7 +135,12 @@ def _open(self): fourcc = header.read(4) (bitcount,) = struct.unpack(" Date: Mon, 8 Aug 2022 02:24:55 +0300 Subject: [PATCH 2/4] Add missing LA test textures --- Tests/images/la.dds | Bin 0 -> 32896 bytes Tests/images/la.png | Bin 0 -> 1060 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 Tests/images/la.dds create mode 100644 Tests/images/la.png diff --git a/Tests/images/la.dds b/Tests/images/la.dds new file mode 100644 index 0000000000000000000000000000000000000000..30bf93576fd17f80397a1a016c3ee2306e4bf28a GIT binary patch literal 32896 zcmeI4;f>T#420j&0MG%V1zNZc5Z&;DdMJ(-j@^xtFtTUtJV%OdaU|H-`0+4X(6pEBpi3mQLUN zhAVA5p%B0!$UPjuA;|dw9Djv6iQ(a(_u$>I1Ojy6clnLvvWhAUCVm}G%is+ZHu896>c61SC68$csOrpOQNl+^8 zJtZg=cfSOs;_k2AQNU1G`clA9So{<)6l&b7JH(^~&%jUNQoik;evw#x!ROi zq3`pbTr({T)*H&H70aUD|CJNy-#_6Imjze<{;7TgzW@DKCa}DDa=}tu{POEfinTX? zb<;2RP!+ZuVEt!g0Fef~lfiTo-0z~AB=^@93cU%shYJiz?KiL{q5Ws5 z8>+dGpL4Ya?ey1*vMd$_D29ehEs&-Cw(-fT6JTrGTNZ_$gp0 z)VNo7h)D~cfuF*qgfYS;%Yre&CCh?!hx4B)Oj^|Za=oE=_5SH%lR^j>6v)G!66a6; z-I>IsWdU9&rx0aP^H(N77n>Bq1qTIkwJEVe-{(KMW?B}kH^rdg<&vqm`|Ee% zs!aj*l*il^(N7_%fc|P^@WKRkbP;6|{S=c5=&wg1FcjE+64r>;PeEP5`p?J!A`N&a zgXt!?-$gY^?yoBpdJ}XH7Z{S-Z(vPA`_E7}RCAMiI^aT(^Bd$Xk@KHZ^%bt;&-@J6 zasLZk$NlpT0EZy=OaO-<=Lc{Ia{fvc;JSf+I^ep2_5-dPXn#$0flZS4aDh#d`(0p@ z<>kY-L_fHp_6hgqDpmg{j=J}Ih@nI|F6h(W=Tw17T|?)^H(RZZgTdMt~Mp~@1O99%Yv(a|5Segy#M`ICa}D7a=}tu z{PW)cv+q3mQZKq&^c?)NCt#nVTrw4R|J(`K{q;L{y)ubCDI^upe|!SyuSOEp6|p15 zqyqY{=0Exl;J^MJQBYT~{$mrc{xdS}qD_)_a#2l^`*Snk{<>mdO+xoDuqL7X@dUL0 z4AmfSiQLl-@|MW?`3!RYbE-Dz$IbC)ZqSdL<9?jNaeq5{0zHAAKu@42&=cqh^aOeW tJ%OG;PoO8z6X*%_1bPBJfu2B5peN81=n3=$dICLxow)~&Z0 zH5EtM_}-^3Hu{@?P>lS=P97Ps&2Y`uaavk;f+X z|NQ$jeEDRv|F65_YwNN;r`k*j^g*GU zZrQreW}1D!B^c{>PdvO!Q}DcywYc$d-YXYC%pI{Ec)v#0Q1dpzO) z>}bXbHv4f(YB%FVzfuC*mB;y3?5j z1Y_6l`*Zr}^!K%%U%v1;Fm4i`z{@pZZ$nN1!{0UQ-Rxhl{Qn3%@>4BHFG zvO)N_WU1bT6BB&dj~$)VdmKdUP~ty6OIP9JK^?b8&5=DWQEzT4__ZJBudVs8`g7#( zEAQX`@v{F_RsA^p{{34ulKk8O-p@~*f)PiiFVsE|QIi7_fuGYeL8Um$eIo#hy0rW-j^kyJGGiySUreHRK;G{qW88_J1>XAU=NS zyafLm7qg!>=auF^k6h|9g(3RDz4}GE*KdJ{%kKNxA2hsSP1#&w#xU{!KZg8$-&HSO zwq{@j1*3+;H>ORFj9)hIlX{<mc)r>dSOl$mp?&q7^EYrKsANhAsLdGHG zJ20rK7CedkEnz6J*YW@;s5BYRZ}jM#$(_tSC4Y-t#^bFZ{I|zSJfrVe%H_twjVX^e z0tw}HCk}5+m~ShZQl<%b`g*RTKc>bd*xEBgAN@LH9B?8Cq8^B=a` z{7TfFtE}w|A`btsoASe`WPg^sa;d+23pTn#+UJ zi>uD)Er=RDdV4Fvzpy&-gjnM+dDD|ps Date: Fri, 23 Dec 2022 19:07:45 +1100 Subject: [PATCH 3/4] Added support for uncompressed LA images --- Tests/images/{la.dds => uncompressed_la.dds} | Bin Tests/images/{la.png => uncompressed_la.png} | Bin Tests/test_file_dds.py | 38 ++++++++----------- src/PIL/DdsImagePlugin.py | 31 ++++++++------- 4 files changed, 33 insertions(+), 36 deletions(-) rename Tests/images/{la.dds => uncompressed_la.dds} (100%) rename Tests/images/{la.png => uncompressed_la.png} (100%) diff --git a/Tests/images/la.dds b/Tests/images/uncompressed_la.dds similarity index 100% rename from Tests/images/la.dds rename to Tests/images/uncompressed_la.dds diff --git a/Tests/images/la.png b/Tests/images/uncompressed_la.png similarity index 100% rename from Tests/images/la.png rename to Tests/images/uncompressed_la.png diff --git a/Tests/test_file_dds.py b/Tests/test_file_dds.py index f579cd1c257..cac4108a8f0 100644 --- a/Tests/test_file_dds.py +++ b/Tests/test_file_dds.py @@ -23,6 +23,7 @@ TEST_FILE_DX10_R8G8B8A8 = "Tests/images/argb-32bpp_MipMaps-1.dds" TEST_FILE_DX10_R8G8B8A8_UNORM_SRGB = "Tests/images/DXGI_FORMAT_R8G8B8A8_UNORM_SRGB.dds" TEST_FILE_UNCOMPRESSED_L = "Tests/images/uncompressed_l.dds" +TEST_FILE_UNCOMPRESSED_L_WITH_ALPHA = "Tests/images/uncompressed_la.dds" TEST_FILE_UNCOMPRESSED_RGB = "Tests/images/hopper.dds" TEST_FILE_UNCOMPRESSED_RGB_WITH_ALPHA = "Tests/images/uncompressed_rgb.dds" @@ -195,32 +196,24 @@ def test_unimplemented_dxgi_format(): pass -def test_uncompressed(): +@pytest.mark.parametrize( + ("mode", "size", "test_file"), + [ + ("L", (128, 128), TEST_FILE_UNCOMPRESSED_L), + ("LA", (128, 128), TEST_FILE_UNCOMPRESSED_L_WITH_ALPHA), + ("RGB", (128, 128), TEST_FILE_UNCOMPRESSED_RGB), + ("RGBA", (800, 600), TEST_FILE_UNCOMPRESSED_RGB_WITH_ALPHA), + ], +) +def test_uncompressed(mode, size, test_file): """Check uncompressed images can be opened""" - with Image.open(TEST_FILE_UNCOMPRESSED_L) as im: - assert im.format == "DDS" - assert im.mode == "L" - assert im.size == (128, 128) - - assert_image_equal_tofile(im, "Tests/images/uncompressed_l.png") - - # convert -format dds -define dds:compression=none hopper.jpg hopper.dds - with Image.open(TEST_FILE_UNCOMPRESSED_RGB) as im: - assert im.format == "DDS" - assert im.mode == "RGB" - assert im.size == (128, 128) - assert_image_equal_tofile(im, "Tests/images/hopper.png") - - # Test image with alpha - with Image.open(TEST_FILE_UNCOMPRESSED_RGB_WITH_ALPHA) as im: + with Image.open(test_file) as im: assert im.format == "DDS" - assert im.mode == "RGBA" - assert im.size == (800, 600) + assert im.mode == mode + assert im.size == size - assert_image_equal_tofile( - im, TEST_FILE_UNCOMPRESSED_RGB_WITH_ALPHA.replace(".dds", ".png") - ) + assert_image_equal_tofile(im, test_file.replace(".dds", ".png")) def test__accept_true(): @@ -313,6 +306,7 @@ def test_save_unsupported_mode(tmp_path): ("mode", "test_file"), [ ("L", "Tests/images/linear_gradient.png"), + ("LA", "Tests/images/uncompressed_la.png"), ("RGB", "Tests/images/hopper.png"), ("RGBA", "Tests/images/pil123rgba.png"), ], diff --git a/src/PIL/DdsImagePlugin.py b/src/PIL/DdsImagePlugin.py index b78cc649f13..f78c8b17cbd 100644 --- a/src/PIL/DdsImagePlugin.py +++ b/src/PIL/DdsImagePlugin.py @@ -136,15 +136,18 @@ def _open(self): (bitcount,) = struct.unpack(" Date: Sat, 24 Dec 2022 08:41:57 +1100 Subject: [PATCH 4/4] Added release notes --- docs/releasenotes/9.4.0.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/releasenotes/9.4.0.rst b/docs/releasenotes/9.4.0.rst index ccbe62a6bcd..0068f281608 100644 --- a/docs/releasenotes/9.4.0.rst +++ b/docs/releasenotes/9.4.0.rst @@ -70,7 +70,8 @@ TODO Other Changes ============= -TODO -^^^^ +Added support for DDS L and LA images +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -TODO +Support has been added to read and write L and LA DDS images in the uncompressed +format, known as "luminance" textures.