@@ -52,16 +52,24 @@ export default class Zlib {
5252 try {
5353 // Load WASM module with CDN fallback
5454 const moduleFactory = await this . loadWASMModule ( )
55- this . module = await moduleFactory ( {
56- wasmBinary : await this . loadWasmBinary ( )
55+ const wasmBinary = await this . loadWasmBinary ( )
56+
57+ // Create module with wasmBinary
58+ const module = await moduleFactory ( {
59+ wasmBinary : wasmBinary
5760 } )
5861
62+ // Emscripten may return the module directly or a promise - ensure we have the initialized module
63+ this . module = await module
64+
5965 // Verify WASM functions available
6066 const requiredFunctions = [
6167 '_zlib_compress_buffer' ,
6268 '_zlib_decompress_buffer' ,
69+ '_zlib_compress_bound' ,
6370 '_zlib_crc32' ,
64- '_zlib_adler32'
71+ '_zlib_adler32' ,
72+ '_zlib_get_version'
6573 ]
6674
6775 if ( ! this . module ) {
@@ -100,43 +108,57 @@ export default class Zlib {
100108 const inputPtr = this . module ! . _malloc ( data . length )
101109 this . module ! . HEAPU8 . set ( data , inputPtr )
102110
103- // Perform compression with SIMD acceleration when available
111+ // Perform compression with output parameter API
104112 const level = options . level ?? ZlibCompression . DEFAULT_COMPRESSION
105- const strategy = options . strategy ?? ZlibStrategy . DEFAULT_STRATEGY
106113
114+ // Allocate output buffer - get max compressed size
115+ const maxCompressedSize = this . module ! . _zlib_compress_bound ( data . length )
116+ const outputPtr = this . module ! . _malloc ( maxCompressedSize )
117+
118+ // Allocate space for output length parameter
119+ const outputLenPtr = this . module ! . _malloc ( 4 ) // unsigned long is 4 bytes in wasm32
120+ this . module ! . setValue ( outputLenPtr , maxCompressedSize , 'i32' )
121+
122+ // Call compression function with output parameters
107123 const result = this . module ! . _zlib_compress_buffer (
108124 inputPtr ,
109125 data . length ,
110- level ,
111- strategy
126+ outputPtr ,
127+ outputLenPtr ,
128+ level
112129 )
113130
114- // Free input buffer
131+ // Read the actual compressed size
132+ const compressedSize = this . module ! . getValue ( outputLenPtr , 'i32' )
133+
134+ // Free input buffer and length pointer
115135 this . module ! . _free ( inputPtr )
136+ this . module ! . _free ( outputLenPtr )
116137
117- if ( ! result || result . size === 0 ) {
118- throw new ZlibCompressionError ( 'Compression failed - no output generated' )
138+ if ( result !== 0 ) { // Z_OK = 0
139+ this . module ! . _free ( outputPtr )
140+ throw new ZlibCompressionError ( `Compression failed with error code: ${ result } ` )
119141 }
120142
121143 // Copy compressed data
122- const compressedData = new Uint8Array ( result . size )
144+ const compressedData = new Uint8Array ( compressedSize )
123145 compressedData . set (
124- this . module ! . HEAPU8 . subarray ( result . dataPtr , result . dataPtr + result . size )
146+ this . module ! . HEAPU8 . subarray ( outputPtr , outputPtr + compressedSize )
125147 )
126148
127- // Free output buffer (allocated by WASM)
128- this . module ! . _free ( result . dataPtr )
149+ // Free output buffer
150+ this . module ! . _free ( outputPtr )
129151
130152 const endTime = performance . now ( )
131153 const processingTime = endTime - startTime
132154
133155 return {
134156 data : compressedData ,
135157 originalSize : data . length ,
136- compressedSize : result . size ,
137- compressionRatio : data . length / result . size ,
158+ compressedSize : compressedSize ,
159+ compressionRatio : data . length / compressedSize ,
138160 processingTime,
139- simdAccelerated : result . simdUsed
161+ simdAccelerated : false // SIMD detection to be added
140162 }
141163 } catch ( error ) {
142164 const errorMessage = error instanceof Error ? error . message : String ( error ) ;
@@ -159,38 +181,53 @@ export default class Zlib {
159181 const inputPtr = this . module ! . _malloc ( data . length )
160182 this . module ! . HEAPU8 . set ( data , inputPtr )
161183
184+ // Allocate output buffer - estimate 20x compressed size (zlib can achieve 10-20x compression)
185+ const estimatedSize = Math . max ( data . length * 20 , 64 * 1024 ) // At least 64KB
186+ const outputPtr = this . module ! . _malloc ( estimatedSize )
187+
188+ // Allocate space for output length parameter
189+ const outputLenPtr = this . module ! . _malloc ( 4 )
190+ this . module ! . setValue ( outputLenPtr , estimatedSize , 'i32' )
191+
162192 // Perform decompression
163193 const result = this . module ! . _zlib_decompress_buffer (
164194 inputPtr ,
165- data . length
195+ data . length ,
196+ outputPtr ,
197+ outputLenPtr
166198 )
167199
168- // Free input buffer
200+ // Read the actual decompressed size
201+ const decompressedSize = this . module ! . getValue ( outputLenPtr , 'i32' )
202+
203+ // Free input buffer and length pointer
169204 this . module ! . _free ( inputPtr )
205+ this . module ! . _free ( outputLenPtr )
170206
171- if ( ! result || result . size === 0 ) {
172- throw new ZlibCompressionError ( 'Decompression failed - no output generated' )
207+ if ( result !== 0 ) { // Z_OK = 0
208+ this . module ! . _free ( outputPtr )
209+ throw new ZlibCompressionError ( `Decompression failed with error code: ${ result } ` )
173210 }
174211
175212 // Copy decompressed data
176- const decompressedData = new Uint8Array ( result . size )
213+ const decompressedData = new Uint8Array ( decompressedSize )
177214 decompressedData . set (
178- this . module ! . HEAPU8 . subarray ( result . dataPtr , result . dataPtr + result . size )
215+ this . module ! . HEAPU8 . subarray ( outputPtr , outputPtr + decompressedSize )
179216 )
180217
181- // Free output buffer (allocated by WASM)
182- this . module ! . _free ( result . dataPtr )
218+ // Free output buffer
219+ this . module ! . _free ( outputPtr )
183220
184221 const endTime = performance . now ( )
185222 const processingTime = endTime - startTime
186223
187224 return {
188225 data : decompressedData ,
189- originalSize : result . size ,
226+ originalSize : decompressedSize ,
190227 compressedSize : data . length ,
191- compressionRatio : result . size / data . length ,
228+ compressionRatio : decompressedSize / data . length ,
192229 processingTime,
193- simdAccelerated : result . simdUsed
230+ simdAccelerated : false // SIMD detection to be added
194231 }
195232 } catch ( error ) {
196233 const errorMessage = error instanceof Error ? error . message : String ( error ) ;
@@ -209,7 +246,7 @@ export default class Zlib {
209246 const inputPtr = this . module ! . _malloc ( data . length )
210247 this . module ! . HEAPU8 . set ( data , inputPtr )
211248
212- const crc = this . module ! . _zlib_crc32 ( inputPtr , data . length )
249+ const crc = this . module ! . _zlib_crc32 ( 0 , inputPtr , data . length )
213250
214251 this . module ! . _free ( inputPtr )
215252 return crc
@@ -226,7 +263,7 @@ export default class Zlib {
226263 const inputPtr = this . module ! . _malloc ( data . length )
227264 this . module ! . HEAPU8 . set ( data , inputPtr )
228265
229- const adler = this . module ! . _zlib_adler32 ( inputPtr , data . length )
266+ const adler = this . module ! . _zlib_adler32 ( 0 , inputPtr , data . length )
230267
231268 this . module ! . _free ( inputPtr )
232269 return adler
@@ -241,13 +278,16 @@ export default class Zlib {
241278 }
242279
243280 // Check SIMD capabilities
244- const simdSupported = this . module ! . _zlib_simd_supported ?.( ) ?? false
245- const simdCapabilities = this . module ! . _zlib_simd_capabilities ?.( ) ?? 'None'
281+ const simdSupported = this . module ! . _zlib_has_simd ?.( ) ?? false
282+
283+ // Get version string
284+ const versionPtr = this . module ! . _zlib_get_version ?.( )
285+ const version = versionPtr ? this . module ! . UTF8ToString ( versionPtr ) : '1.4.2'
246286
247287 return {
248288 simdSupported,
249- simdCapabilities,
250- version : this . module ! . _zlib_get_version ?. ( ) ?? '1.4.2' ,
289+ simdCapabilities : simdSupported ? 'WASM SIMD128' : 'None' ,
290+ version,
251291 maxMemoryMB : this . loadingOptions . maxMemoryMB ?? 256 ,
252292 compressionLevels : [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ] ,
253293 strategies : Object . values ( ZlibStrategy ) . filter ( v => typeof v === 'number' ) as ZlibStrategy [ ]
@@ -316,10 +356,8 @@ export default class Zlib {
316356 * Cleanup resources
317357 */
318358 cleanup ( ) : void {
319- if ( this . module ) {
320- this . module ! . _zlib_cleanup ?.( )
321- this . module = null
322- }
359+ // Clean up module resources
360+ this . module = null
323361 this . initialized = false
324362 }
325363
0 commit comments