From e0dce889ef21fdb0907b5d1098b79dcc8a02dbc4 Mon Sep 17 00:00:00 2001 From: shaoboyan Date: Thu, 9 Jan 2025 18:16:33 +0800 Subject: [PATCH] Add more image files with multiple format for copyToTexture,image_file cases This PR added multiple format image file to test CopyEI2T handles HTMLImageElements loaded from them. The format including coded files: *.png, *.jpg, *.bmp, *.ico, *.gif *.webp, and *.avif and svg file: *.svg --- src/resources/four-colors.avif | Bin 0 -> 3344 bytes src/resources/four-colors.bmp | Bin 0 -> 230454 bytes src/resources/four-colors.gif | Bin 0 -> 2221 bytes src/resources/four-colors.ico | Bin 0 -> 202814 bytes src/resources/four-colors.svg | 8 ++ src/resources/four-colors.webp | Bin 0 -> 78 bytes .../copyToTexture/image_file.spec.ts | 119 +++++++++++++++++- src/webgpu/web_platform/util.ts | 65 +++++++++- 8 files changed, 184 insertions(+), 8 deletions(-) create mode 100644 src/resources/four-colors.avif create mode 100644 src/resources/four-colors.bmp create mode 100644 src/resources/four-colors.gif create mode 100644 src/resources/four-colors.ico create mode 100644 src/resources/four-colors.svg create mode 100644 src/resources/four-colors.webp diff --git a/src/resources/four-colors.avif b/src/resources/four-colors.avif new file mode 100644 index 0000000000000000000000000000000000000000..06394f43827d58615be0183e15ed5eb6f924c6ab GIT binary patch literal 3344 zcmeHJPe>F|7=M#Swk;M?qCqyB#2~smyK7cE?z+aBte_FKDI)zDXJ&UFJAYm~qdQ8M zEGVSt4_zXPE)^Z3grK5>mo6eg1Rac`q@ote3WBdB6F6-}}uw zJcLkH(i$S-AWkAM4JQK{79nP8HN_HX4a}34)$DwT5W$kQ7%%#Af-TKS7ZBno&irWIaa;c<(Df!OgV zP0>1nZA^m_m&*mN5))0NIT(YO5@w_X=6|lqq7{zXM3gd$#r7*HtVg&nkH+k&kTDlrSg>!x5wI8iqG6#-&e<~i1ZSeXdd zp@}I)5O&)*nJ^5M4Fr9m9UPFr-i3W_?F$r;MYyzO5rOA(xtuT8=rgh@J`f6pcz=)& z2EBmrnnSuJ+FsqP1qK)EaI`6=l*NSV$x=?S-x#nW9Oq&es4bja;?_-{GpbKAG@h>T z0iT}-HkJ+3RB-0)RP>aUZV7JlhaJ$e>T+lgmI2uqT!x%4!hrM-3x7=r`*upOaT@*+ zlJ@`iR%}v`#znb`auuXNLEz%)D#}%m0tJDKr>iJeK?)QE{*O-A(iK?I;oh5r3vLB+ zt&Yxo`1Ssc=lYA_Ek+hcpLVp(`B51voxesS#Ez7)qxV*Q9*s47!;#55@w=C9AAIQB z`YK;)j^9wvdSdvBnvZs*=T07-dQubrOisl!7p~@J zza3h+#l8Jnck|xfN4?b@eQVuz-Rpe&@b~r;)ssW#OW#gS$Ia<{GVv_&qoJmLqIKPY YikY7iACIX`?!=f>^K!PlFSqIRZ^?r=VgLXD literal 0 HcmV?d00001 diff --git a/src/resources/four-colors.bmp b/src/resources/four-colors.bmp new file mode 100644 index 0000000000000000000000000000000000000000..d61f80398ed8429e4839b82429a2db0b450cf45f GIT binary patch literal 230454 zcmeIx!4bhw7)H@QqXR1?sKDCT>qZF*)ukNPOSoMi;dTLAZ|iKmtxLFFAmMfa zTW{-Zy{${QT_E9h0b6hDY`v{ZxLqLOb^%*&>ukNPOSoMi;dTLAZ|iKmtxLFFAmMfa zTW{-Zy{${QT_E9h0b6hDY`v{ZxLqLOb^%*&>ukNPOSoMi;dTLAZ|iKmtxLFFAmMfa zTW{-Zy{${QT_E9h0b6hDY`v{ZxLqLOb^%*&>ukNPOSoMi;dTLAZ|iKmtxLFFAmMfa zTW{-Zy{${QT_E9h0b6hDY`v{ZxLqLOb^%*&>ukNPOSoMi;dTLAZ|iKmtxLFFAmMfa zTW{-Zy{${QT_E9h0b6hDY`v{ZxLqLOb^%*&>ukNPOSoMi;dTLAZ|iKmtxLFFAmMfa zTW{-Zy{${QT_E9h0b6hDY`v{ZxLqLOb^%*&>ukNPOSoMi;dTLAZ|iKmtxLFFAmMfa zTW{-Zy{${QT_E9h0b6hDY`v{ZxLqLOb^%*&>ukNPOSoMi;dTLAZ|iKmtxLFFAmMfa zTW{-Zy{${QT_E9h0b6hDY`v{ZxLqLOb^%*&>ukNPOSoMi;dTLAZ|iKmtxLFFAmMfa zTW{-Zy{${QT_E9h0b6hDY`v{ZxLqLOb^%*&>ukNPOSoMi;dTLAZ|iKmtxLFFAmMfa zTW{-Zy{${QT_E9h0b6hDY`v{ZxLqLOb^%*&>ukNPOSoMi;dTLAZ|iKmtxLFFAmMfa zTW{-Zy{${QT_E9h0b6hDY`v{ZxLqLOb^%*&>ukNPOSoMi;dTLAZ|iKmtxLFFAmMfa zTW{-Zy{${QT_E9h0b6hDY`v{ZxLqLOb^%*&>ukNPOSoMi;dTLAZ|iKmtxLFFAmMfa zTW{-Zy{${QT_E9h0b6hDY`v{ZxLqLOb^%*&>ukNPOSoMi;dTLAZ|iKmtxLFFAmMfa zTW{-Zy{${QT_E9h0b6hDY`v{ZxLqLOb^%*&>ukNPOSoMi;dTLAZ|iKmtxLFFAmMfa zTW{-Zy{${QT_E9h0b6hDX5YKz0ui?h^#0lfY`v|s^|mhIc7cT31#G>ov-P$v;dX(9 z+XZaBt+VyEF5z~8gxdvdy{)tLwl3jzfrQ%yY`v|s^|mhIc7cT31#G>ov-P$v;dX(9 z+XZaBt+VyEF5z~8gxdvdy{)tLwl3jzfrQ%yY`v|s^|mhIc7cT31#G>ov-P$v;dX(9 z+XZaBt+VyEF5z~8gxdvdy{)tLwl3jzfrQ%yY`v|s^|mhIc7cT31#G>ov-P$v;dX(9 z+XZaBt+VyEF5z~8gxdvdy{)tLwl3jzfrQ%yY`v|s^|mhIc7cT31#G>ov-P$v;dX(9 z+XZaBt+VyEF5z~8gxdvdy{)tLwl3jzfrQ%yY`v|s^|mhIc7cT31#G>ov-P$v;dX(9 z+XZaBt+VyEF5z~8gxdvdy{)tLwl3jzfrQ%yY`v|s^|mhIc7cT31#G>ov-P$v;dX(9 z+XZaBt+VyEF5z~8gxdvdy{)tLwl3jzfrQ%yY`v|s^|mhIc7cT31#G>ov-P$v;dX(9 z+XZaBt+VyEF5z~8gxdvdy{)tLwl3jzfrQ%yY`v|s^|mhIc7cT31#G>ov-P$v;dX(9 z+XZaBt+VyEF5z~8gxdvdy{)tLwl3jzfrQ%yY`v|s^|mhIc7cT31#G>ov-P$v;dX(9 z+XZaBt+VyEF5z~8gxdvdy{)tLwl3jzfrQ%yY`v|s^|mhIc7cT31#G>ov-P$v;dX(9 z+XZaBt+VyEF5z~8gxdvdy{)tLwl3jzfrQ%yY`v|s^|mhIc7cT31#G>ov-P$v;dX(9 z+XZaBt+VyEF5z~8gxdvdy{)tLwl3jzfrQ%yY`v|s^|mhIc7cT31#G>ov-P$v;dX(9 z+XZaBt+VyEF5z~8gxdvdy{)tLwl3jzfrQ%yY`v|s^|mhIc7cT31#G>ov-P$v;dX(9 z+XZaBt+VyEF5z~8gxdvdy{)tLwl3jzfrQ%yY`v|s^|mhIc7cT31#G>ov-P$v;dX(9 Y+XZaBt+VyEF5z~8gxdvdy??*%4YwYnV*mgE literal 0 HcmV?d00001 diff --git a/src/resources/four-colors.gif b/src/resources/four-colors.gif new file mode 100644 index 0000000000000000000000000000000000000000..4d4642f7e0ce504a30e1b0c601902ecf049cb355 GIT binary patch literal 2221 zcmXYwdt8m#8poeLGlp_5(Y-i0##CN%c}ht!rXl4rI(mmLL&jLth-NltG?;k_skC=V zv{Wu7^rn=ZQbdkJ$|@baL&haa3N?-0ZEtDKcFtM4aYR-$DQaKmiy42LV7p5C{kq1O@^J5kN!`35XO#1|kOuKthlRNE9Rn5(gPTMvw`} z6l4Z62L(VuPzWd#6b1@6z6~6K6W|m$18zJ30wNFuiolFD6aWQ8fuKN9U?^}D0YyZS zph!_kFcCUPbLlaNV-Nt8*9Nu0^R zWMnd7GG#JjGG_`f1(`yaLYcyt!Wjp~k#WK}Wt=h2-v`0yh7pNTm$7J!f&g4VE)XtI zE-)@|E&>;ki-e1mi;Rn$OTZ=M65$f%65|r*GH@BWOt?(B%(%?C0$f3^5UxXeV0)}vCHytsr@aUD8Ar|99ZxkN88f!lG zZ~NyKWnD|K#fXPDin6OTqkZB>(15J!6sIL}XhYKRn+GSas>#qN=hUWqsLmd*)}Fj| z#C4O|NdID|`s{fr<0sY>=Prr!&-Tysf0L`^EgSTYM>Xe!Yp27mnsxh^ybdT@d*_7f z&63Ck=c1ZQHqI|C@GaY{8(w^~^vs+J>A7L#I`_h-#XBuZy_xOlXI0-g%r7x3d-F?m z8V!Ct!cF_4D8uK2cMA+BTJLzz&-*g2{2WsX7nUDxpIXu$Tdaz`Si9v|$CHs;h8`Jm z(c}8l8-wjvET0nneGAJR8+$3#5cTqU{?MxBp<6a|R95Id`G|+~N4_bq{dMk<(!*17s zASb)ssp0o+W0Rt9*zVE9ZMKbzr)zEF<8p0n6LyvjvE3U}eaa^Br-n2e^|rP>Hkz$^ zC)=b=rgk>TbL?}i_ic18`#2?GdYtwC0Dn8{)OA75)(1#<^tgk`(bOt!Wqh<1T~6by z4t)to2gO^QNREiGKbiVtxy323xCo2foI~Zq<=MG4_IYQ@%B@dtsE!|=f9}C} zhk{9MKMp@rVKB2Q6ipq56Rx6z0tof<7~B%y?2Aj zpj>G$AZ3RpN;D1Yl=b_ee))t_4?;amlWt*R;=pKzX(ye7+M#^tT(hx zO(`(E{5-qEv-NbX%;b>AJrv@?B5Zn%}&Yhq1T1dz*VF4CtqPaq!Gfb*-hBy9}L!+XwpRR&Ds1 zb-kF?^{)5TnOVF?w_*TnXPMmANS)Z&Z+?E}pqu5I?JrefZ$~eiX_}?k(X4IMPww;n zbG#$EQ7uJ-n@gHM?%BR(6No_pY_G#jU2Cuy{=pN zMzZx9GhDN$5}$P@ou4tzppGk7ef`_fWiyecfdC^)FN!g}j&5pCn+yl(i`?uoi#>GMYqKhVVqiXfz zFlYCmx_t-gw5y*-(fMDMBp$5jdfqKXPg^-xlSZ&*QnH`->c6DWaMg(iNByRSFG@KS zq;2`NFxNZspPF>4BQGk$-M&+&WHjQMd-XwXn+j4ge^R|@Y}8|PUCQAWt>fL!Hr&>c za>Prw#sK!7+YhLZdSdH+^O~8vE@_T=s9Jr-L}1+b#4LC1+S`+Z0}>Y{X1nTIeP4I5v!;o;E~_H~Gd;yqa-h64C*sTeh}#mtj6VPn8*bD9 literal 0 HcmV?d00001 diff --git a/src/resources/four-colors.ico b/src/resources/four-colors.ico new file mode 100644 index 0000000000000000000000000000000000000000..8ebb5d7479971439a8acde2b09f5301558cbdf74 GIT binary patch literal 202814 zcmeI&yKWp+90%YtHgq6lBSlHLr9tEkXhBqv7og%L-~o6UD3GY2K~PZe4j>^xKwK&! zq?9Ckn6W+b*k;+=T+Zc-HOyw#-kmwS-|zQdhY*_fD|{Q;|K1DtZy$$SA%y$w)*b%1 z-MZuFe~!aPr{Qe7I1pALL|a{J@U#grwy*n_uN}n)4{yiNejTksY}&o8t~Fr4F8kf< z&3|3S|1Z<|=U@NVn+N>!&p-cipq?Bs|JUpN`ey;|>v7+|*8KC|=Rp6Su&*Zv_~)Ph zdc0rHcK-S2pMU@UF9)u7gTI%b3;LgX{a?QGby?0o|NQfB{+9#mI>PaC^FjY}um8*S zy(zo-=bwN6&Hr*>Q&+gZyqwVg-0T1HTyLAz{PWL0|K@)=ux)4fzH;(H|8uYZ%kjKx zHuKLv|NNW(<-o4p;rsK?4gJr({?Fg>zFEva|NQfB{+9#$c8H(LH$U`0_xe9yzlUZo z|NQgMzxiJd9NHy*KEE8%|J>{U{M?R}wfytXKmX=`IWShIc$|FlME`TI|MT%WcDC}* zKmYuj|K-5g-Qw}m&lUa8z5Y+%=~P+DKmYvmZ~m79Q+15TO*dckKll1SU7u5DC;$BO z&%gO!4ouxO9zVUD(f{1*|MXnWm6iPS&p-d>e>pH$=XjoU@<#u2um98WICnPk&p-eC zoB!p&+}-2(md_pi&%OR%-r-VN$Up!5^Kbr_150&~=Upy;^gs9de>s0kXCMFk^UuHe zUk)tYMV^2D9Mb>X>;L)PrIL00^Upv3=6^YmN+&sw`SM8rbFcsB^Ojn+@y|d1{G0#f zKx*COe5TJO{m;GrpWa!jS;jyA{PS=AmjkJGl=GS{pY%WX`hPlKsb?4e{PWMh`CksC z-c`{U-QARuHT?6>KmX=`IZ#TcxsL7gO#gGQ|F`#2TDI`dKmYuj|K&hw-R62W z=bHZKUjJ`)Qfij)&p-eCoB!oNsU7FK*5{l4=U)G>_fdLw@XtU0{G0#fKL@ntdp5LNw;$f_j`hd;z5B1ONxv@rK9}|Bdcaoa8hrIih!1`{ zZ5!*n-@DI**T06xhPV6g8y*|pcK`Vb4A*3MJC*hM^zRN+OUOb7Py>JpgeB-(J z&UX*u^FO{7PrrXVp8Q~|Z4KW4>ru2-xCVbeiXZ&+I6nL4=P|tgO>FLe-EQ69R?`}^ zlW#lo*=k&aJAcM_bn6cv|LXksclNp;#Z~)zOj}iJuv(pE{;R(~iN`PfeD*$QnkTVo zp4uu~gRmNOe}B8%4{!JL!SLAdw)@X#sNtFnZzr}s&BeLBeCGe*dH=WX`(UeY4Z8P& zt-dvAGl_qhSL5g2>aTg&|95}6=>PUJL0bg2%GRKtP3`OXJ?Itxzh2J&{MVO%+}Gp2 zf35%1e`UQV>&~;Te^1!glLP$M*YoT0j{ADt_pdeo{P%g#zbEYL$pQZP=f58B*R!2} z{`u#>`~QFL_P_u4`@bsx?els!_@pI?sXf9~~ves0IgTK@UxpMUee92l!pJWf7&qW`(q|M_?w zJ6rkZpMU<%|8ijLZt-~O=ZgO4UjL`>bgC@npMU=OH~-6lsXE5vrkgMNpL_kEuFt8n zlYjpC=imG<2d3^CkDp%7=zs3@e|j$G%1ZwE=bwM`zZ{sWb39Kvd87Zi*Z=8woI4x& z=bwN6&Hr*>?(Xq?%jb^%=U)FW?{KLsNOrIVb;e0ik*x!3>mc}p$Z_~)O0 z{>}e#Ahm9CKGWxt{^wr*Pwy<%EaRVl{`oim%Yjro%6UzfPx_yG{Xdmj35n{~zus*DT_nfByM5|I2|~JIs0SpI`c)d;Pz^pWL&DfByOB-~2BJ za_=(dzk819fA01F?ruuS8vgm`pMUee94MvJT*vl#rvJIu|J!>hEnE2KpMU<%|8k(T zZgV}Gb4~wqum3kYDK$&@=bwN6&Hr+s)Q)pq>+?}e#p!BYD zeK&JX|8uYZZ@Q=@EBNQ1fBwz?a-f#ZbDfuYr~kRv|Cb(W%Le}W@BIgVtbi4;0#?8Z jSOF_w1+0J-umV=V3RnRvU + + + + + + + \ No newline at end of file diff --git a/src/resources/four-colors.webp b/src/resources/four-colors.webp new file mode 100644 index 0000000000000000000000000000000000000000..f7dd40bee9a6d4bbfcb3712c5524b264713dfba4 GIT binary patch literal 78 zcmWIYbaQiKU|6NE+F#L{?;G%cohfV+in*o i+Dvl)^zBTo(l2|)_S&4k;r}(49n{VFm!;p&o+( literal 0 HcmV?d00001 diff --git a/src/webgpu/web_platform/copyToTexture/image_file.spec.ts b/src/webgpu/web_platform/copyToTexture/image_file.spec.ts index aa9a16e16dc..682e2339d45 100644 --- a/src/webgpu/web_platform/copyToTexture/image_file.spec.ts +++ b/src/webgpu/web_platform/copyToTexture/image_file.spec.ts @@ -6,11 +6,14 @@ import { makeTestGroup } from '../../../common/framework/test_group.js'; import { TextureUploadingUtils } from '../../util/copy_to_texture.js'; import { convertToUnorm8, - GetSourceFromImageFile, + GetSourceFromEXIFImageFile, kImageNames, kImageInfo, kImageExpectedColors, kObjectTypeFromFiles, + kEXIFImageNames, + kEXIFImageInfo, + loadImageFileAndRun, } from '../util.js'; export const g = makeTestGroup(TextureUploadingUtils); @@ -38,7 +41,7 @@ g.test('from_orientation_metadata_file') ) .params(u => u // - .combine('imageName', kImageNames) + .combine('imageName', kEXIFImageNames) .combine('objectTypeFromFile', kObjectTypeFromFiles) .combine('srcDoFlipYDuringCopy', [true, false]) ) @@ -47,7 +50,7 @@ g.test('from_orientation_metadata_file') const kColorFormat = 'rgba8unorm'; // Load image file. - const source = await GetSourceFromImageFile(t, imageName, objectTypeFromFile); + const source = await GetSourceFromEXIFImageFile(t, imageName, objectTypeFromFile); const width = source.width; const height = source.height; @@ -72,7 +75,7 @@ g.test('from_orientation_metadata_file') } ); - const expect = kImageInfo[imageName].display; + const expect = kEXIFImageInfo[imageName].display; const presentColors = kImageExpectedColors.srgb; if (srcDoFlipYDuringCopy) { @@ -123,3 +126,111 @@ g.test('from_orientation_metadata_file') ]); } }); + +g.test('from_multiple_formats') + .desc( + ` + Test HTMLImageElements which loaded multiple image file formats. Including + *.jpg, *.png, *.bmp, *.webp, *.avif, *.svg, *.ico and *.gif. + + It creates an HTMLImageElement using images in the 'resources' folder. + + Then call copyExternalImageToTexture() to do a full copy to the 0 mipLevel + of dst texture, and read one pixel out to compare with the manually documented expected color. + + If 'flipY' in 'GPUCopyExternalImageSourceInfo' is set to 'true', copy will ensure the result + is flipped. + + The tests covers: + - Image with multiple image file format + - Valid 'flipY' config in 'GPUCopyExternalImageSourceInfo' (named 'srcDoFlipYDuringCopy' in cases) + - TODO: partial copy tests should be added + - TODO: all valid dstColorFormat tests should be added. + - TODO(#4108): Make this work in service workers (see GetSourceFromImageFile) + ` + ) + .params(u => + u // + .combine('imageName', kImageNames) + .combine('srcDoFlipYDuringCopy', [true, false]) + ) + .fn(async t => { + const { imageName, srcDoFlipYDuringCopy } = t.params; + const kColorFormat = 'rgba8unorm'; + await loadImageFileAndRun(t, imageName, (source: HTMLImageElement) => { + const width = source.width; + const height = source.height; + + const dstTexture = t.createTextureTracked({ + size: { width, height }, + format: kColorFormat, + usage: + GPUTextureUsage.COPY_DST | GPUTextureUsage.COPY_SRC | GPUTextureUsage.RENDER_ATTACHMENT, + }); + + t.device.queue.copyExternalImageToTexture( + { + source, + flipY: srcDoFlipYDuringCopy, + }, + { + texture: dstTexture, + }, + { + width, + height, + } + ); + + const expect = kImageInfo[imageName].display; + const presentColors = kImageExpectedColors.srgb; + + if (srcDoFlipYDuringCopy) { + t.expectSinglePixelComparisonsAreOkInTexture({ texture: dstTexture }, [ + // Flipped top-left. + { + coord: { x: width * 0.25, y: height * 0.25 }, + exp: convertToUnorm8(presentColors[expect.bottomLeftColor]), + }, + // Flipped top-right. + { + coord: { x: width * 0.75, y: height * 0.25 }, + exp: convertToUnorm8(presentColors[expect.bottomRightColor]), + }, + // Flipped bottom-left. + { + coord: { x: width * 0.25, y: height * 0.75 }, + exp: convertToUnorm8(presentColors[expect.topLeftColor]), + }, + // Flipped bottom-right. + { + coord: { x: width * 0.75, y: height * 0.75 }, + exp: convertToUnorm8(presentColors[expect.topRightColor]), + }, + ]); + } else { + t.expectSinglePixelComparisonsAreOkInTexture({ texture: dstTexture }, [ + // Top-left. + { + coord: { x: width * 0.25, y: height * 0.25 }, + exp: convertToUnorm8(presentColors[expect.topLeftColor]), + }, + // Top-right. + { + coord: { x: width * 0.75, y: height * 0.25 }, + exp: convertToUnorm8(presentColors[expect.topRightColor]), + }, + // Bottom-left. + { + coord: { x: width * 0.25, y: height * 0.75 }, + exp: convertToUnorm8(presentColors[expect.bottomLeftColor]), + }, + // Bottom-right. + { + coord: { x: width * 0.75, y: height * 0.75 }, + exp: convertToUnorm8(presentColors[expect.bottomRightColor]), + }, + ]); + } + }); + }); diff --git a/src/webgpu/web_platform/util.ts b/src/webgpu/web_platform/util.ts index 66a2163b738..7b5131d4ba8 100644 --- a/src/webgpu/web_platform/util.ts +++ b/src/webgpu/web_platform/util.ts @@ -626,7 +626,7 @@ const kFourColorsInfo = { }, } as const; -export const kImageInfo = makeTable({ +export const kEXIFImageInfo = makeTable({ table: { 'four-colors.jpg': kFourColorsInfo, 'four-colors-rotate-90-cw.jpg': kFourColorsInfo, @@ -635,9 +635,25 @@ export const kImageInfo = makeTable({ }, } as const); +export const kImageInfo = makeTable({ + table: { + 'four-colors.jpg': kFourColorsInfo, + 'four-colors.png': kFourColorsInfo, + 'four-colors.bmp': kFourColorsInfo, + 'four-colors.webp': kFourColorsInfo, + 'four-colors.gif': kFourColorsInfo, + 'four-colors.avif': kFourColorsInfo, + 'four-colors.ico': kFourColorsInfo, + 'four-colors.svg': kFourColorsInfo, + }, +} as const); + type ImageName = keyof typeof kImageInfo; export const kImageNames: readonly ImageName[] = keysOf(kImageInfo); +type EXIFImageName = keyof typeof kEXIFImageInfo; +export const kEXIFImageNames: readonly EXIFImageName[] = keysOf(kEXIFImageInfo); + type ObjectTypeFromFile = (typeof kObjectTypeFromFiles)[number]; export const kObjectTypeFromFiles = [ 'ImageBitmap-from-Blob', @@ -649,12 +665,12 @@ export const kObjectTypeFromFiles = [ * Load image file(e.g. *.jpg) from ImageBitmap, blob or HTMLImageElement. And * convert the result to valid source that GPUCopyExternalImageSource supported. */ -export async function GetSourceFromImageFile( +export async function GetSourceFromEXIFImageFile( test: GPUTest, - imageName: ImageName, + exifImageName: EXIFImageName, objectTypeFromFile: ObjectTypeFromFile ): Promise { - const imageUrl = getResourcePath(imageName); + const imageUrl = getResourcePath(exifImageName); switch (objectTypeFromFile) { case 'ImageBitmap-from-Blob': { @@ -689,3 +705,44 @@ export async function GetSourceFromImageFile( } } } + +/** + * Create HTMLImageElement and load image file and waits for it to be loaded. + * Returns a promise which resolves after `callback` (which may be async) completes. + * + * @param imageName An valid imageName in kkImageInfo table . + * @param callback Function to call when HTMLImageElement is loaded. + * + */ +export function loadImageFileAndRun( + test: GPUTest, + imageName: ImageName, + callback: (image: HTMLImageElement) => unknown | Promise +): Promise { + return raceWithRejectOnTimeout( + new Promise((resolve, reject) => { + const callbackAndResolve = (image: HTMLImageElement) => + void (async () => { + try { + await callback(image); + resolve(); + } catch (ex) { + reject(ex); + } + })(); + // Skip test if HTMLImageElement is not available, e.g. in worker. + if (typeof HTMLImageElement === 'undefined') { + test.skip( + 'Try to use HTMLImage do image file decoding but HTMLImageElement not available.' + ); + } + const image = new Image(); + image.src = getResourcePath(imageName); + image.onload = () => { + callbackAndResolve(image); + }; + }), + 2000, + 'Video never became ready' + ); +}