@@ -16,6 +16,20 @@ const METHODES = {
1616 grand_rhombitrihex : 9 , hex_tronque : 10 ,
1717} ;
1818
19+ const EXPORTS_CODES_METHODES = {
20+ hex : "methode_hexagone" ,
21+ square : "methode_carre" ,
22+ triangle : "methode_triangle" ,
23+ trihex : "methode_trihex" ,
24+ snub_trihex : "methode_snub_trihex" ,
25+ triangulaire_elongue : "methode_triangulaire_elongue" ,
26+ carre_snub : "methode_carre_snub" ,
27+ rhombitrihex : "methode_rhombitrihex" ,
28+ carre_tronque : "methode_carre_tronque" ,
29+ grand_rhombitrihex : "methode_grand_rhombitrihex" ,
30+ hex_tronque : "methode_hex_tronque" ,
31+ } ;
32+
1933let wasm = null ;
2034let loadedImage = null ;
2135let renderToken = 0 ;
@@ -43,6 +57,7 @@ async function chargerWasm() {
4357 }
4458
4559 wasm = instance . exports ;
60+ synchroniserCodesMethodes ( wasm ) ;
4661 status . textContent = "Moteur WASM charge." ;
4762 btnApply . disabled = false ;
4863 document . getElementById ( "upload-zone" ) . style . pointerEvents = "auto" ;
@@ -88,6 +103,14 @@ function km_ajouter(r, g, b) { wasm.km_ajouter(r, g, b); }
88103function km_calculer ( maxIter ) { wasm . km_calculer ( maxIter ) ; }
89104function km_resultat ( ) { return [ Number ( wasm . km_r ( ) ) , Number ( wasm . km_g ( ) ) , Number ( wasm . km_b ( ) ) ] ; }
90105
106+ function synchroniserCodesMethodes ( exports ) {
107+ for ( const [ nom , exportNom ] of Object . entries ( EXPORTS_CODES_METHODES ) ) {
108+ if ( typeof exports [ exportNom ] !== "function" ) continue ;
109+ const code = Number ( exports [ exportNom ] ( ) ) ;
110+ if ( Number . isInteger ( code ) && code >= 0 ) METHODES [ nom ] = code ;
111+ }
112+ }
113+
91114function boitePolygone ( sommets ) {
92115 let minX = Infinity , minY = Infinity , maxX = - Infinity , maxY = - Infinity ;
93116 for ( const [ x , y ] of sommets ) {
@@ -178,6 +201,28 @@ function dimensionsScalees(imgEl) {
178201 return [ w , h ] ;
179202}
180203
204+ function lireSommetsTuile ( ti ) {
205+ const n = Number ( wasm . tuile_n_sommets ( ti ) ) ;
206+ if ( ! Number . isInteger ( n ) || n < 3 || n > 64 ) return null ;
207+ const sommets = [ ] ;
208+ for ( let j = 0 ; j < n ; j ++ ) {
209+ const x = Number ( wasm . tuile_sommet_x ( ti , j ) ) ;
210+ const y = Number ( wasm . tuile_sommet_y ( ti , j ) ) ;
211+ if ( ! Number . isFinite ( x ) || ! Number . isFinite ( y ) ) return null ;
212+ sommets . push ( [ x , y ] ) ;
213+ }
214+ return sommets ;
215+ }
216+
217+ function lireNombreSommetsTuile ( ti ) {
218+ try {
219+ const n = Number ( wasm . tuile_n_sommets ( ti ) ) ;
220+ return Number . isInteger ( n ) && n >= 0 ? n : Number . MAX_SAFE_INTEGER ;
221+ } catch ( err ) {
222+ return Number . MAX_SAFE_INTEGER ;
223+ }
224+ }
225+
181226function entierSecurise ( valeur , secours , minimum = null , maximum = null ) {
182227 let n = Number . isFinite ( valeur ) ? Math . trunc ( valeur ) : Math . trunc ( Number ( valeur ) ) ;
183228 if ( ! Number . isFinite ( n ) ) n = secours ;
@@ -218,24 +263,38 @@ async function rendreSortie() {
218263 ctx . fillStyle = `rgb(${ bgCouleur [ 0 ] } ,${ bgCouleur [ 1 ] } ,${ bgCouleur [ 2 ] } )` ;
219264 ctx . fillRect ( 0 , 0 , w , h ) ;
220265
221- const code = entierSecurise ( METHODES [ state . method ] , 0 , 0 ) ;
266+ const code = entierSecurise ( METHODES [ state . method ] , METHODES . hex , 0 ) ;
222267 const cote = entierSecurise ( state . side , 30 , 1 ) ;
223268 if ( cote !== state . side ) state . side = cote ;
224269 const nTuiles = Number ( wasm . generer_tuiles ( w , h , cote , code ) ) ;
270+ if ( ! Number . isInteger ( nTuiles ) || nTuiles < 0 ) {
271+ throw new Error ( `Nombre de tuiles invalide renvoye par WASM: ${ nTuiles } ` ) ;
272+ }
225273 const indices = Array . from ( { length : nTuiles } , ( _ , i ) => i ) ;
226- indices . sort ( ( a , b ) => Number ( wasm . tuile_n_sommets ( a ) ) - Number ( wasm . tuile_n_sommets ( b ) ) ) ;
274+ indices . sort ( ( a , b ) => lireNombreSommetsTuile ( a ) - lireNombreSommetsTuile ( b ) ) ;
227275
228276 const cssContour = couleurContourCss ( ) ;
277+ let tuilesInvalides = 0 ;
229278 for ( const ti of indices ) {
230- const n = Number ( wasm . tuile_n_sommets ( ti ) ) ;
231- const sommets = [ ] ;
232- for ( let j = 0 ; j < n ; j ++ )
233- sommets . push ( [ Number ( wasm . tuile_sommet_x ( ti , j ) ) , Number ( wasm . tuile_sommet_y ( ti , j ) ) ] ) ;
279+ let sommets = null ;
280+ try {
281+ sommets = lireSommetsTuile ( ti ) ;
282+ } catch ( err ) {
283+ tuilesInvalides ++ ;
284+ console . warn ( `[pixel2polygon] Tuile ${ ti } ignoree :` , err ) ;
285+ continue ;
286+ }
287+ if ( ! sommets ) {
288+ tuilesInvalides ++ ;
289+ continue ;
290+ }
234291 const couleur = couleurTuile ( pixelData , w , h , sommets ) ;
235292 if ( couleur ) dessinerTuile ( ctx , sommets , couleur , state . outlineWidth , cssContour ) ;
236293 }
237294
238- status . textContent = `Rendu termine : ${ nTuiles } tuiles pour le mode ${ state . method } .` ;
295+ status . textContent = tuilesInvalides > 0
296+ ? `Rendu termine : ${ nTuiles - tuilesInvalides } /${ nTuiles } tuiles valides pour le mode ${ state . method } .`
297+ : `Rendu termine : ${ nTuiles } tuiles pour le mode ${ state . method } .` ;
239298 btnDl . disabled = false ;
240299 } catch ( err ) {
241300 console . error ( "[pixel2polygon] Echec du rendu :" , err ) ;
0 commit comments