@@ -47,86 +47,90 @@ var LibraryBrowser = {
4747 imagePlugin [ 'canHandle' ] = function imagePlugin_canHandle ( name ) {
4848 return ! Module [ 'noImageDecoding' ] && / \. ( j p g | j p e g | p n g | b m p | w e b p ) $ / i. test ( name ) ;
4949 } ;
50- imagePlugin [ 'handle' ] = function imagePlugin_handle ( byteArray , name , onload , onerror ) {
50+ imagePlugin [ 'handle' ] = async function imagePlugin_handle ( byteArray , name ) {
5151 var b = new Blob ( [ byteArray ] , { type : Browser . getMimetype ( name ) } ) ;
5252 if ( b . size !== byteArray . length ) { // Safari bug #118630
5353 // Safari's Blob can only take an ArrayBuffer
5454 b = new Blob ( [ ( new Uint8Array ( byteArray ) ) . buffer ] , { type : Browser . getMimetype ( name ) } ) ;
5555 }
5656 var url = URL . createObjectURL ( b ) ;
57- var img = new Image ( ) ;
58- img . onload = ( ) => {
57+ return new Promise ( ( resolve , reject ) => {
58+ var img = new Image ( ) ;
59+ img . onload = ( ) => {
5960#if ASSERTIONS
60- assert ( img . complete , `Image ${ name } could not be decoded` ) ;
61+ assert ( img . complete , `Image ${ name } could not be decoded` ) ;
6162#endif
62- var canvas = /** @type {!HTMLCanvasElement } */ ( document . createElement ( 'canvas' ) ) ;
63- canvas . width = img . width ;
64- canvas . height = img . height ;
65- var ctx = canvas . getContext ( '2d' ) ;
66- ctx . drawImage ( img , 0 , 0 ) ;
67- Browser . preloadedImages [ name ] = canvas ;
68- URL . revokeObjectURL ( url ) ;
69- onload ?. ( byteArray ) ;
70- } ;
71- img . onerror = ( event ) => {
72- err ( `Image ${ url } could not be decoded` ) ;
73- onerror ?. ( ) ;
74- } ;
75- img . src = url ;
63+ var canvas = /** @type {!HTMLCanvasElement } */ ( document . createElement ( 'canvas' ) ) ;
64+ canvas . width = img . width ;
65+ canvas . height = img . height ;
66+ var ctx = canvas . getContext ( '2d' ) ;
67+ ctx . drawImage ( img , 0 , 0 ) ;
68+ Browser . preloadedImages [ name ] = canvas ;
69+ URL . revokeObjectURL ( url ) ;
70+ resolve ( byteArray ) ;
71+ } ;
72+ img . onerror = ( event ) => {
73+ err ( `Image ${ url } could not be decoded` ) ;
74+ reject ( ) ;
75+ } ;
76+ img . src = url ;
77+ } ) ;
7678 } ;
7779 preloadPlugins . push ( imagePlugin ) ;
7880
7981 var audioPlugin = { } ;
8082 audioPlugin [ 'canHandle' ] = function audioPlugin_canHandle ( name ) {
8183 return ! Module [ 'noAudioDecoding' ] && name . slice ( - 4 ) in { '.ogg' : 1 , '.wav' : 1 , '.mp3' : 1 } ;
8284 } ;
83- audioPlugin [ 'handle' ] = function audioPlugin_handle ( byteArray , name , onload , onerror ) {
84- var done = false ;
85- function finish ( audio ) {
86- if ( done ) return ;
87- done = true ;
88- Browser . preloadedAudios [ name ] = audio ;
89- onload ?. ( byteArray ) ;
90- }
91- var b = new Blob ( [ byteArray ] , { type : Browser . getMimetype ( name ) } ) ;
92- var url = URL . createObjectURL ( b ) ; // XXX we never revoke this!
93- var audio = new Audio ( ) ;
94- audio . addEventListener ( 'canplaythrough' , ( ) => finish ( audio ) , false ) ; // use addEventListener due to chromium bug 124926
95- audio . onerror = function audio_onerror ( event ) {
96- if ( done ) return ;
97- err ( `warning: browser could not fully decode audio ${ name } , trying slower base64 approach` ) ;
98- function encode64 ( data ) {
99- var BASE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' ;
100- var PAD = '=' ;
101- var ret = '' ;
102- var leftchar = 0 ;
103- var leftbits = 0 ;
104- for ( var i = 0 ; i < data . length ; i ++ ) {
105- leftchar = ( leftchar << 8 ) | data [ i ] ;
106- leftbits += 8 ;
107- while ( leftbits >= 6 ) {
108- var curr = ( leftchar >> ( leftbits - 6 ) ) & 0x3f ;
109- leftbits -= 6 ;
110- ret += BASE [ curr ] ;
85+ audioPlugin [ 'handle' ] = async function audioPlugin_handle ( byteArray , name ) {
86+ return new Promise ( ( resolve , reject ) => {
87+ var done = false ;
88+ function finish ( audio ) {
89+ if ( done ) return ;
90+ done = true ;
91+ Browser . preloadedAudios [ name ] = audio ;
92+ resolve ( byteArray ) ;
93+ }
94+ var b = new Blob ( [ byteArray ] , { type : Browser . getMimetype ( name ) } ) ;
95+ var url = URL . createObjectURL ( b ) ; // XXX we never revoke this!
96+ var audio = new Audio ( ) ;
97+ audio . addEventListener ( 'canplaythrough' , ( ) => finish ( audio ) , false ) ; // use addEventListener due to chromium bug 124926
98+ audio . onerror = function audio_onerror ( event ) {
99+ if ( done ) return ;
100+ err ( `warning: browser could not fully decode audio ${ name } , trying slower base64 approach` ) ;
101+ function encode64 ( data ) {
102+ var BASE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' ;
103+ var PAD = '=' ;
104+ var ret = '' ;
105+ var leftchar = 0 ;
106+ var leftbits = 0 ;
107+ for ( var i = 0 ; i < data . length ; i ++ ) {
108+ leftchar = ( leftchar << 8 ) | data [ i ] ;
109+ leftbits += 8 ;
110+ while ( leftbits >= 6 ) {
111+ var curr = ( leftchar >> ( leftbits - 6 ) ) & 0x3f ;
112+ leftbits -= 6 ;
113+ ret += BASE [ curr ] ;
114+ }
111115 }
116+ if ( leftbits == 2 ) {
117+ ret += BASE [ ( leftchar & 3 ) << 4 ] ;
118+ ret += PAD + PAD ;
119+ } else if ( leftbits == 4 ) {
120+ ret += BASE [ ( leftchar & 0xf ) << 2 ] ;
121+ ret += PAD ;
122+ }
123+ return ret ;
112124 }
113- if ( leftbits == 2 ) {
114- ret += BASE [ ( leftchar & 3 ) << 4 ] ;
115- ret += PAD + PAD ;
116- } else if ( leftbits == 4 ) {
117- ret += BASE [ ( leftchar & 0xf ) << 2 ] ;
118- ret += PAD ;
119- }
120- return ret ;
121- }
122- audio . src = 'data:audio/x-' + name . slice ( - 3 ) + ';base64,' + encode64 ( byteArray ) ;
123- finish ( audio ) ; // we don't wait for confirmation this worked - but it's worth trying
124- } ;
125- audio . src = url ;
126- // workaround for chrome bug 124926 - we do not always get oncanplaythrough or onerror
127- safeSetTimeout ( ( ) => {
128- finish ( audio ) ; // try to use it even though it is not necessarily ready to play
129- } , 10000 ) ;
125+ audio . src = 'data:audio/x-' + name . slice ( - 3 ) + ';base64,' + encode64 ( byteArray ) ;
126+ finish ( audio ) ; // we don't wait for confirmation this worked - but it's worth trying
127+ } ;
128+ audio . src = url ;
129+ // workaround for chrome bug 124926 - we do not always get oncanplaythrough or onerror
130+ safeSetTimeout ( ( ) => {
131+ finish ( audio ) ; // try to use it even though it is not necessarily ready to play
132+ } , 10000 ) ;
133+ } ) ;
130134 } ;
131135 preloadPlugins . push ( audioPlugin ) ;
132136#endif
0 commit comments