zeck 2.0.0 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +158 -28
- package/package.json +3 -2
- package/zeck.d.ts +247 -16
- package/zeck_bg.js +408 -16
- package/zeck_bg.wasm +0 -0
package/README.md
CHANGED
|
@@ -13,17 +13,20 @@ The Zeckendorf algorithm represents numbers as a sum of non-consecutive Fibonacc
|
|
|
13
13
|
## Features
|
|
14
14
|
|
|
15
15
|
- **Compression & Decompression**: Convert data to/from Zeckendorf representation
|
|
16
|
+
- **File Format with Headers**: `.zeck` file format that automatically preserves original file size and endianness information
|
|
16
17
|
- **Multiple Endian Interpretations**: Support for both big-endian and little-endian input interpretations
|
|
17
18
|
- **Automatic Best Compression**: Try both endian interpretations and automatically select the best result
|
|
18
19
|
- **Multiple Fibonacci Algorithms**:
|
|
19
20
|
- Slow recursive (memoized, for small numbers)
|
|
20
21
|
- Slow iterative (memoized, for large numbers)
|
|
21
22
|
- Fast Doubling (optimized, ~160x faster for large indices)
|
|
23
|
+
- Memoized Fast Doubling (with sparse HashMap caching for large, non-contiguous indices)
|
|
22
24
|
- **BigInt Support**: Handle arbitrarily large numbers using `num-bigint`
|
|
23
25
|
- **Memoization**: Thread-safe caching for improved performance
|
|
24
26
|
- **Statistics & Visualization**: Generate compression statistics and plots
|
|
25
27
|
- **Benchmarking**: Comprehensive performance benchmarks
|
|
26
28
|
- **WebAssembly Support**: Available as a WebAssembly module for use in web browsers
|
|
29
|
+
- **Error Handling**: Comprehensive error types for file format operations
|
|
27
30
|
|
|
28
31
|
## WebAssembly
|
|
29
32
|
|
|
@@ -44,14 +47,14 @@ Or add this to your `Cargo.toml`:
|
|
|
44
47
|
|
|
45
48
|
```toml
|
|
46
49
|
[dependencies]
|
|
47
|
-
zeck = "
|
|
50
|
+
zeck = "2.1.0"
|
|
48
51
|
```
|
|
49
52
|
|
|
50
53
|
For plotting features:
|
|
51
54
|
|
|
52
55
|
```toml
|
|
53
56
|
[dependencies]
|
|
54
|
-
zeck = { version = "
|
|
57
|
+
zeck = { version = "2.1.0", features = ["plotting"] }
|
|
55
58
|
```
|
|
56
59
|
|
|
57
60
|
### Install from GitHub (development version)
|
|
@@ -87,70 +90,130 @@ Or add this to your `package.json`:
|
|
|
87
90
|
```json
|
|
88
91
|
{
|
|
89
92
|
"dependencies": {
|
|
90
|
-
"zeck": "^
|
|
93
|
+
"zeck": "^2.1.0"
|
|
91
94
|
}
|
|
92
95
|
}
|
|
93
96
|
```
|
|
94
97
|
|
|
95
98
|
## Usage
|
|
96
99
|
|
|
97
|
-
###
|
|
100
|
+
### File Format Compression (Recommended)
|
|
98
101
|
|
|
99
|
-
|
|
102
|
+
The `.zeck` file format automatically handles size preservation and endianness information. This is the recommended approach for most use cases.
|
|
103
|
+
|
|
104
|
+
#### Big-Endian File Format
|
|
100
105
|
|
|
101
106
|
```rust
|
|
102
|
-
use zeck::{
|
|
107
|
+
use zeck::zeck_file_format::{compress::compress_zeck_be, decompress::decompress_zeck_file};
|
|
103
108
|
|
|
104
109
|
// Compress data (interpreted as big-endian integer)
|
|
105
110
|
let data = vec![12u8];
|
|
106
|
-
let
|
|
111
|
+
let zeck_file = compress_zeck_be(&data)?;
|
|
107
112
|
|
|
108
|
-
//
|
|
109
|
-
let
|
|
113
|
+
// Serialize to bytes for storage
|
|
114
|
+
let bytes = zeck_file.to_bytes();
|
|
115
|
+
|
|
116
|
+
// Later, deserialize and decompress
|
|
117
|
+
use zeck::zeck_file_format::file::deserialize_zeck_file;
|
|
118
|
+
let zeck_file = deserialize_zeck_file(&bytes)?;
|
|
119
|
+
let decompressed = decompress_zeck_file(&zeck_file)?;
|
|
110
120
|
assert_eq!(data, decompressed);
|
|
111
121
|
```
|
|
112
122
|
|
|
113
|
-
#### Little-Endian
|
|
123
|
+
#### Little-Endian File Format
|
|
114
124
|
|
|
115
125
|
```rust
|
|
116
|
-
use zeck::{
|
|
126
|
+
use zeck::zeck_file_format::{compress::compress_zeck_le, decompress::decompress_zeck_file};
|
|
117
127
|
|
|
118
128
|
// Compress data (interpreted as little-endian integer)
|
|
119
129
|
let data = vec![12u8];
|
|
120
|
-
let
|
|
130
|
+
let zeck_file = compress_zeck_le(&data)?;
|
|
121
131
|
|
|
122
132
|
// Decompress data
|
|
123
|
-
let decompressed =
|
|
133
|
+
let decompressed = decompress_zeck_file(&zeck_file)?;
|
|
124
134
|
assert_eq!(data, decompressed);
|
|
125
135
|
```
|
|
126
136
|
|
|
127
|
-
#### Automatic Best Compression
|
|
137
|
+
#### Automatic Best Compression (File Format)
|
|
128
138
|
|
|
129
139
|
```rust
|
|
130
|
-
use zeck::{
|
|
140
|
+
use zeck::zeck_file_format::{
|
|
141
|
+
compress::{compress_zeck_best, BestCompressionResult},
|
|
142
|
+
decompress::decompress_zeck_file,
|
|
143
|
+
};
|
|
131
144
|
|
|
132
145
|
// Try both endian interpretations and get the best result
|
|
133
146
|
let data = vec![1, 0];
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
match result {
|
|
137
|
-
CompressionResult::BigEndianBest { compressed_data, le_size } => {
|
|
147
|
+
match compress_zeck_best(&data)? {
|
|
148
|
+
BestCompressionResult::BigEndianBest { zeck_file, le_size } => {
|
|
138
149
|
// Big-endian produced the best compression
|
|
139
|
-
let decompressed =
|
|
150
|
+
let decompressed = decompress_zeck_file(&zeck_file)?;
|
|
140
151
|
assert_eq!(data, decompressed);
|
|
141
152
|
}
|
|
142
|
-
|
|
153
|
+
BestCompressionResult::LittleEndianBest { zeck_file, be_size } => {
|
|
143
154
|
// Little-endian produced the best compression
|
|
144
|
-
let decompressed =
|
|
155
|
+
let decompressed = decompress_zeck_file(&zeck_file)?;
|
|
145
156
|
assert_eq!(data, decompressed);
|
|
146
157
|
}
|
|
147
|
-
|
|
158
|
+
BestCompressionResult::Neither { be_size, le_size } => {
|
|
148
159
|
// Neither method compressed the data (both were larger than original)
|
|
149
160
|
println!("Neither method compressed: BE size = {}, LE size = {}", be_size, le_size);
|
|
150
161
|
}
|
|
151
162
|
}
|
|
152
163
|
```
|
|
153
164
|
|
|
165
|
+
### Padless Compression (Advanced)
|
|
166
|
+
|
|
167
|
+
The padless compression functions strip leading zero bytes and do not preserve original size information. **You must manually track the original size** if you need to restore leading zeros. These functions are marked as `_dangerous` to indicate they require careful handling.
|
|
168
|
+
|
|
169
|
+
**⚠️ Important:** The padless functions are lower-level and do not preserve leading zero bytes. Use the file format functions above for most use cases.
|
|
170
|
+
|
|
171
|
+
#### Big-Endian Padless
|
|
172
|
+
|
|
173
|
+
```rust
|
|
174
|
+
use zeck::{padless_zeckendorf_compress_be_dangerous, padless_zeckendorf_decompress_be_dangerous};
|
|
175
|
+
|
|
176
|
+
// Compress data (interpreted as big-endian integer)
|
|
177
|
+
let data = vec![12u8];
|
|
178
|
+
let compressed = padless_zeckendorf_compress_be_dangerous(&data);
|
|
179
|
+
|
|
180
|
+
// Decompress data (leading zeros may be lost)
|
|
181
|
+
let decompressed = padless_zeckendorf_decompress_be_dangerous(&compressed);
|
|
182
|
+
// Note: decompressed may not equal data if data had leading zeros
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
#### Little-Endian Padless
|
|
186
|
+
|
|
187
|
+
```rust
|
|
188
|
+
use zeck::{padless_zeckendorf_compress_le_dangerous, padless_zeckendorf_decompress_le_dangerous};
|
|
189
|
+
|
|
190
|
+
// Compress data (interpreted as little-endian integer)
|
|
191
|
+
let data = vec![12u8];
|
|
192
|
+
let compressed = padless_zeckendorf_compress_le_dangerous(&data);
|
|
193
|
+
|
|
194
|
+
// Decompress data (trailing zeros may be lost)
|
|
195
|
+
let decompressed = padless_zeckendorf_decompress_le_dangerous(&compressed);
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
#### Automatic Best Padless Compression
|
|
199
|
+
|
|
200
|
+
```rust
|
|
201
|
+
use zeck::{padless_zeckendorf_compress_best_dangerous, PadlessCompressionResult};
|
|
202
|
+
|
|
203
|
+
let data = vec![1, 0];
|
|
204
|
+
match padless_zeckendorf_compress_best_dangerous(&data) {
|
|
205
|
+
PadlessCompressionResult::BigEndianBest { compressed_data, le_size } => {
|
|
206
|
+
// Use padless_zeckendorf_decompress_be_dangerous for decompression
|
|
207
|
+
}
|
|
208
|
+
PadlessCompressionResult::LittleEndianBest { compressed_data, be_size } => {
|
|
209
|
+
// Use padless_zeckendorf_decompress_le_dangerous for decompression
|
|
210
|
+
}
|
|
211
|
+
PadlessCompressionResult::Neither { be_size, le_size } => {
|
|
212
|
+
// Neither method compressed the data
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
```
|
|
216
|
+
|
|
154
217
|
### Fibonacci Numbers
|
|
155
218
|
|
|
156
219
|
```rust
|
|
@@ -160,8 +223,12 @@ use zeck::memoized_slow_fibonacci_recursive;
|
|
|
160
223
|
let fib_10 = memoized_slow_fibonacci_recursive(10); // Returns 55
|
|
161
224
|
|
|
162
225
|
// For larger numbers, use BigInt versions
|
|
163
|
-
use zeck::
|
|
164
|
-
let fib_100 =
|
|
226
|
+
use zeck::fast_doubling_fibonacci_biguint;
|
|
227
|
+
let fib_100 = fast_doubling_fibonacci_biguint(100);
|
|
228
|
+
|
|
229
|
+
// For even better performance with caching, use memoized fast doubling
|
|
230
|
+
use zeck::memoized_fast_doubling_fibonacci_biguint;
|
|
231
|
+
let fib_1000 = memoized_fast_doubling_fibonacci_biguint(1000);
|
|
165
232
|
```
|
|
166
233
|
|
|
167
234
|
### Zeckendorf Representation
|
|
@@ -172,8 +239,58 @@ use zeck::memoized_zeckendorf_list_descending_for_integer;
|
|
|
172
239
|
// Get Zeckendorf representation as a list of Fibonacci indices
|
|
173
240
|
let zld = memoized_zeckendorf_list_descending_for_integer(12);
|
|
174
241
|
// Returns [6, 4, 2] meaning F(6) + F(4) + F(2) = 8 + 3 + 1 = 12
|
|
242
|
+
|
|
243
|
+
// For BigInt numbers
|
|
244
|
+
use zeck::memoized_zeckendorf_list_descending_for_biguint;
|
|
245
|
+
use num_bigint::BigUint;
|
|
246
|
+
let zld = memoized_zeckendorf_list_descending_for_biguint(&BigUint::from(12u64));
|
|
175
247
|
```
|
|
176
248
|
|
|
249
|
+
### Utility Functions
|
|
250
|
+
|
|
251
|
+
The library provides various utility functions for working with Fibonacci numbers and Zeckendorf representations:
|
|
252
|
+
|
|
253
|
+
```rust
|
|
254
|
+
use zeck::{
|
|
255
|
+
bit_count_for_number, // Count bits needed to represent a number
|
|
256
|
+
highest_one_bit, // Get the highest set bit
|
|
257
|
+
efi_to_fi, fi_to_efi, // Convert between Effective Fibonacci Index and Fibonacci Index
|
|
258
|
+
memoized_effective_fibonacci, // Get Fibonacci number from Effective Fibonacci Index
|
|
259
|
+
zl_to_ezl, ezl_to_zl, // Convert between Zeckendorf List and Effective Zeckendorf List
|
|
260
|
+
all_ones_zeckendorf_to_biguint, // Create "all ones" Zeckendorf numbers
|
|
261
|
+
PHI, PHI_SQUARED, // Golden ratio constants
|
|
262
|
+
};
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
### Error Handling
|
|
266
|
+
|
|
267
|
+
The file format functions return `Result` types with comprehensive error handling:
|
|
268
|
+
|
|
269
|
+
```rust
|
|
270
|
+
use zeck::zeck_file_format::{compress::compress_zeck_be, error::ZeckFormatError};
|
|
271
|
+
|
|
272
|
+
match compress_zeck_be(&data) {
|
|
273
|
+
Ok(zeck_file) => {
|
|
274
|
+
// Compression succeeded
|
|
275
|
+
}
|
|
276
|
+
Err(ZeckFormatError::DataSizeTooLarge { size }) => {
|
|
277
|
+
// Data size exceeds u64::MAX
|
|
278
|
+
}
|
|
279
|
+
Err(e) => {
|
|
280
|
+
// Handle other errors
|
|
281
|
+
eprintln!("Compression error: {}", e);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
Common error types include:
|
|
287
|
+
- `HeaderTooShort`: Input data is too short to contain a valid header
|
|
288
|
+
- `UnsupportedVersion`: File format version is not supported
|
|
289
|
+
- `ReservedFlagsSet`: Reserved flags are set (indicating a newer format)
|
|
290
|
+
- `CompressionFailed`: Compression did not reduce the data size
|
|
291
|
+
- `DecompressedTooLarge`: Decompressed data is larger than expected
|
|
292
|
+
- `DataSizeTooLarge`: Data size exceeds the maximum representable size
|
|
293
|
+
|
|
177
294
|
## Binaries
|
|
178
295
|
|
|
179
296
|
The project includes several utility binaries. The command-line compression tools (`zeck-compress` and `zeck-decompress`) can be installed globally via:
|
|
@@ -297,7 +414,7 @@ cat input.zbe | zeck-decompress --endian big
|
|
|
297
414
|
### Main Playground
|
|
298
415
|
|
|
299
416
|
```bash
|
|
300
|
-
cargo run --release --bin zeck
|
|
417
|
+
cargo run --release --bin zeck-playground --features development_tools
|
|
301
418
|
```
|
|
302
419
|
|
|
303
420
|
A playground/scratchpad for testing library functions.
|
|
@@ -373,6 +490,7 @@ cargo bench --bench zeckendorf_bench -- --baseline <name>
|
|
|
373
490
|
## Performance Characteristics
|
|
374
491
|
|
|
375
492
|
- **Fast Doubling Fibonacci**: ~160x faster than iterative method for the 100,000th Fibonacci number
|
|
493
|
+
- **Memoized Fast Doubling**: Uses sparse HashMap caching for efficient memory usage with large, non-contiguous Fibonacci indices
|
|
376
494
|
- **Memoization**: Thread-safe caching significantly improves repeated calculations. The trade-off is that the cache takes up memory.
|
|
377
495
|
- **Compression Effectiveness**: Varies by input; compression ratios oscillate and become less favorable as input size increases
|
|
378
496
|
|
|
@@ -385,12 +503,23 @@ Every positive integer can be uniquely represented as a sum of non-consecutive F
|
|
|
385
503
|
|
|
386
504
|
### Compression Process
|
|
387
505
|
|
|
388
|
-
1. Input data is interpreted as either a big-endian or little-endian integer (you can choose, or use `
|
|
506
|
+
1. Input data is interpreted as either a big-endian or little-endian integer (you can choose, or use `compress_zeck_best` to try both)
|
|
389
507
|
2. The integer is converted to its Zeckendorf representation (list of Fibonacci indices)
|
|
390
508
|
3. The representation is encoded as bits (use/skip bits)
|
|
391
509
|
4. Bits are packed into bytes (little-endian output)
|
|
392
510
|
|
|
393
|
-
The library provides functions to compress with either interpretation, or you can use `
|
|
511
|
+
The library provides functions to compress with either interpretation, or you can use `compress_zeck_best` to automatically try both and select the one that produces the smallest output.
|
|
512
|
+
|
|
513
|
+
### File Format
|
|
514
|
+
|
|
515
|
+
The `.zeck` file format includes a 10-byte header:
|
|
516
|
+
- **Version** (1 byte): File format version (currently 1)
|
|
517
|
+
- **Original Size** (8 bytes): Original uncompressed file size in bytes (little-endian)
|
|
518
|
+
- **Flags** (1 byte): Endianness and reserved flags
|
|
519
|
+
- Bit 0: Big endian flag (1 = big endian, 0 = little endian)
|
|
520
|
+
- Bits 1-7: Reserved for future use
|
|
521
|
+
|
|
522
|
+
The header is followed by the compressed data. This format automatically preserves the original file size, allowing proper restoration of leading or trailing zero bytes during decompression.
|
|
394
523
|
|
|
395
524
|
### Effective Fibonacci Indices
|
|
396
525
|
|
|
@@ -407,6 +536,7 @@ This avoids redundant Fibonacci numbers (F(0)=0 and F(1)=F(2)=1).
|
|
|
407
536
|
- Compression effectiveness decreases as input size increases
|
|
408
537
|
- The library supports both big-endian and little-endian interpretations, but other byte orderings or word boundaries are not currently explored
|
|
409
538
|
- **⚠️ Warning:** Compressing or decompressing files larger than 10KB (10,000 bytes) is unstable due to time and memory pressure. The library may experience performance issues, excessive memory usage, or failures when processing files exceeding this size.
|
|
539
|
+
- Padless compression functions (`*_dangerous`) do not preserve leading/trailing zero bytes—use the file format functions for automatic size preservation
|
|
410
540
|
|
|
411
541
|
## NPM Versioning Quirk
|
|
412
542
|
|
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"Peter Ryszkiewicz"
|
|
6
6
|
],
|
|
7
7
|
"description": "A Rust library for compressing and decompressing data using the Zeckendorf representation algorithm",
|
|
8
|
-
"version": "2.
|
|
8
|
+
"version": "2.1.1",
|
|
9
9
|
"license": "MIT",
|
|
10
10
|
"repository": {
|
|
11
11
|
"type": "git",
|
|
@@ -15,7 +15,8 @@
|
|
|
15
15
|
"zeck_bg.wasm",
|
|
16
16
|
"zeck.js",
|
|
17
17
|
"zeck_bg.js",
|
|
18
|
-
"zeck.d.ts"
|
|
18
|
+
"zeck.d.ts",
|
|
19
|
+
"LICENSE.txt"
|
|
19
20
|
],
|
|
20
21
|
"main": "zeck.js",
|
|
21
22
|
"types": "zeck.d.ts",
|
package/zeck.d.ts
CHANGED
|
@@ -1,5 +1,45 @@
|
|
|
1
1
|
/* tslint:disable */
|
|
2
2
|
/* eslint-disable */
|
|
3
|
+
/**
|
|
4
|
+
* Result of best compression attempt, containing the best compressed zeck file and the size for the other endianness attempt, or if neither produced compression (both were larger than the original).
|
|
5
|
+
*/
|
|
6
|
+
export type BestCompressionResult = { BigEndianBest: { zeck_file: ZeckFile; le_size: number } } | { LittleEndianBest: { zeck_file: ZeckFile; be_size: number } } | { Neither: { be_size: number; le_size: number } };
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Errors that can occur when parsing or processing .zeck files.
|
|
10
|
+
*/
|
|
11
|
+
export type ZeckFormatError = { HeaderTooShort: { actual_length: number; required_length: number } } | { UnsupportedVersion: { found_version: number; supported_version: number } } | { ReservedFlagsSet: { flags: number } } | { CompressionFailed: { original_size: number; be_size: number; le_size: number } } | { DecompressedTooLarge: { expected_size: number; actual_size: number } } | { DataSizeTooLarge: { size: number } };
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Represents a .zeck file with its header information and compressed data.
|
|
15
|
+
*
|
|
16
|
+
* This struct holds all the information needed to reconstruct a .zeck file,
|
|
17
|
+
* including the format version, original file size, endianness flags, and
|
|
18
|
+
* the compressed data itself.
|
|
19
|
+
*
|
|
20
|
+
* Using `derive(Serialize, Deserialize, Tsify)` and `tsify(into_wasm_abi, from_wasm_abi)` on the struct is necessary
|
|
21
|
+
* to allow the struct to be used in the WebAssembly module, namely because the `compressed_data` field is
|
|
22
|
+
* a [`Vec<u8>`], which needed [`Copy`], and the [`wasm_bindgen`] attribute was insufficient to achieve this.
|
|
23
|
+
*/
|
|
24
|
+
export interface ZeckFile {
|
|
25
|
+
/**
|
|
26
|
+
* File format version
|
|
27
|
+
*/
|
|
28
|
+
version: number;
|
|
29
|
+
/**
|
|
30
|
+
* Original uncompressed file size in bytes
|
|
31
|
+
*/
|
|
32
|
+
original_size: number;
|
|
33
|
+
/**
|
|
34
|
+
* Flags byte (bit 0 = big endian, bits 1-7 reserved)
|
|
35
|
+
*/
|
|
36
|
+
flags: number;
|
|
37
|
+
/**
|
|
38
|
+
* Compressed data (without header)
|
|
39
|
+
*/
|
|
40
|
+
compressed_data: number[];
|
|
41
|
+
}
|
|
42
|
+
|
|
3
43
|
|
|
4
44
|
/**
|
|
5
45
|
* Returns the number of bits required to represent the given number. Returns 0 if the number is less than or equal to 0.
|
|
@@ -17,6 +57,187 @@
|
|
|
17
57
|
*/
|
|
18
58
|
export function bit_count_for_number(n: number): number;
|
|
19
59
|
|
|
60
|
+
/**
|
|
61
|
+
* Compresses data using the Zeckendorf algorithm with big endian interpretation,
|
|
62
|
+
* and stores the result in a [`ZeckFile`] struct.
|
|
63
|
+
*
|
|
64
|
+
* # ⚠️ Warning
|
|
65
|
+
*
|
|
66
|
+
* **Compressing or decompressing data larger than 10KB (10,000 bytes) is unstable due to time and memory pressure.**
|
|
67
|
+
* The library may experience performance issues, excessive memory usage, or failures when processing data exceeding this size.
|
|
68
|
+
*
|
|
69
|
+
* # Examples
|
|
70
|
+
*
|
|
71
|
+
* ```
|
|
72
|
+
* # use zeck::zeck_file_format::compress::compress_zeck_be;
|
|
73
|
+
* let data = vec![1, 0];
|
|
74
|
+
* match compress_zeck_be(&data) {
|
|
75
|
+
* Ok(zeck_file) => {
|
|
76
|
+
* // Access file information
|
|
77
|
+
* println!("Original size: {} bytes", zeck_file.original_size);
|
|
78
|
+
* println!("Is big endian: {}", zeck_file.is_big_endian());
|
|
79
|
+
* // Serialize to bytes for writing to file
|
|
80
|
+
* let bytes = zeck_file.to_bytes();
|
|
81
|
+
* }
|
|
82
|
+
* Err(e) => {
|
|
83
|
+
* // Handle error (e.g., data size too large)
|
|
84
|
+
* }
|
|
85
|
+
* }
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
export function compress_zeck_be(data: Uint8Array): ZeckFile;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Compresses data using the Zeckendorf algorithm with automatic endianness selection,
|
|
92
|
+
* and stores the result in a [`BestCompressionResult`] struct.
|
|
93
|
+
*
|
|
94
|
+
* This function attempts compression with both big endian and little endian interpretations,
|
|
95
|
+
* and returns the best result, or if neither produced compression (both were larger than the original).
|
|
96
|
+
*
|
|
97
|
+
* # ⚠️ Warning
|
|
98
|
+
*
|
|
99
|
+
* **Compressing or decompressing data larger than 10KB (10,000 bytes) is unstable due to time and memory pressure.**
|
|
100
|
+
* The library may experience performance issues, excessive memory usage, or failures when processing data exceeding this size.
|
|
101
|
+
*
|
|
102
|
+
* # Examples
|
|
103
|
+
*
|
|
104
|
+
* ```
|
|
105
|
+
* # use zeck::zeck_file_format::compress::compress_zeck_best;
|
|
106
|
+
* # use zeck::zeck_file_format::compress::BestCompressionResult;
|
|
107
|
+
* # use zeck::zeck_file_format::decompress::decompress_zeck_file;
|
|
108
|
+
* let data = vec![0, 1]; // Compresses best interpreted as a big endian integer
|
|
109
|
+
* match compress_zeck_best(&data) {
|
|
110
|
+
* Ok(best_compression_result) => {
|
|
111
|
+
* match best_compression_result {
|
|
112
|
+
* BestCompressionResult::BigEndianBest { zeck_file, le_size } => {
|
|
113
|
+
* let decompressed = decompress_zeck_file(&zeck_file).unwrap();
|
|
114
|
+
* assert_eq!(decompressed, data);
|
|
115
|
+
* }
|
|
116
|
+
* BestCompressionResult::LittleEndianBest { zeck_file, be_size } => {
|
|
117
|
+
* assert!(false);
|
|
118
|
+
* }
|
|
119
|
+
* BestCompressionResult::Neither { be_size, le_size } => {
|
|
120
|
+
* assert!(false);
|
|
121
|
+
* }
|
|
122
|
+
* }
|
|
123
|
+
* }
|
|
124
|
+
* Err(e) => {
|
|
125
|
+
* assert!(false);
|
|
126
|
+
* }
|
|
127
|
+
* }
|
|
128
|
+
*
|
|
129
|
+
* let data = vec![1, 0]; // Compresses best interpreted as a little endian integer
|
|
130
|
+
* match compress_zeck_best(&data) {
|
|
131
|
+
* Ok(best_compression_result) => {
|
|
132
|
+
* match best_compression_result {
|
|
133
|
+
* BestCompressionResult::BigEndianBest { zeck_file, le_size } => {
|
|
134
|
+
* assert!(false);
|
|
135
|
+
* }
|
|
136
|
+
* BestCompressionResult::LittleEndianBest { zeck_file, be_size } => {
|
|
137
|
+
* let decompressed = decompress_zeck_file(&zeck_file).unwrap();
|
|
138
|
+
* assert_eq!(decompressed, data);
|
|
139
|
+
* }
|
|
140
|
+
* BestCompressionResult::Neither { be_size, le_size } => {
|
|
141
|
+
* assert!(false);
|
|
142
|
+
* }
|
|
143
|
+
* }
|
|
144
|
+
* }
|
|
145
|
+
* Err(e) => {
|
|
146
|
+
* assert!(false);
|
|
147
|
+
* }
|
|
148
|
+
* }
|
|
149
|
+
* ```
|
|
150
|
+
*/
|
|
151
|
+
export function compress_zeck_best(data: Uint8Array): BestCompressionResult;
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Compresses data using the Zeckendorf algorithm with little endian interpretation,
|
|
155
|
+
* and stores the result in a [`ZeckFile`] struct.
|
|
156
|
+
*
|
|
157
|
+
* # ⚠️ Warning
|
|
158
|
+
*
|
|
159
|
+
* **Compressing or decompressing data larger than 10KB (10,000 bytes) is unstable due to time and memory pressure.**
|
|
160
|
+
* The library may experience performance issues, excessive memory usage, or failures when processing data exceeding this size.
|
|
161
|
+
*
|
|
162
|
+
* # Examples
|
|
163
|
+
*
|
|
164
|
+
* ```
|
|
165
|
+
* # use zeck::zeck_file_format::compress::compress_zeck_le;
|
|
166
|
+
* let data = vec![1, 0];
|
|
167
|
+
* match compress_zeck_le(&data) {
|
|
168
|
+
* Ok(zeck_file) => {
|
|
169
|
+
* // Access file information
|
|
170
|
+
* println!("Original size: {} bytes", zeck_file.original_size);
|
|
171
|
+
* println!("Compressed size: {} bytes", zeck_file.compressed_data.len());
|
|
172
|
+
* // Serialize to bytes for writing to file
|
|
173
|
+
* let bytes = zeck_file.to_bytes();
|
|
174
|
+
* }
|
|
175
|
+
* Err(e) => {
|
|
176
|
+
* // Handle error (e.g., data size too large)
|
|
177
|
+
* }
|
|
178
|
+
* }
|
|
179
|
+
* ```
|
|
180
|
+
*/
|
|
181
|
+
export function compress_zeck_le(data: Uint8Array): ZeckFile;
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Decompresses data from a [`ZeckFile`] struct.
|
|
185
|
+
*
|
|
186
|
+
* This function takes a [`ZeckFile`] directly and uses its header information to decompress
|
|
187
|
+
* the data. This is a convenience function that avoids the need to serialize and parse the
|
|
188
|
+
* file format when you already have a [`ZeckFile`] struct.
|
|
189
|
+
*
|
|
190
|
+
* # ⚠️ Warning
|
|
191
|
+
*
|
|
192
|
+
* **Compressing or decompressing data larger than 10KB (10,000 bytes) is unstable due to time and memory pressure.**
|
|
193
|
+
* The library may experience performance issues, excessive memory usage, or failures when processing data exceeding this size.
|
|
194
|
+
*
|
|
195
|
+
* # Examples
|
|
196
|
+
*
|
|
197
|
+
* ```
|
|
198
|
+
* # use zeck::zeck_file_format::{compress::compress_zeck_le, decompress::decompress_zeck_file};
|
|
199
|
+
* let original = vec![0, 1];
|
|
200
|
+
* let zeck_file = compress_zeck_le(&original).unwrap();
|
|
201
|
+
* match decompress_zeck_file(&zeck_file) {
|
|
202
|
+
* Ok(decompressed) => {
|
|
203
|
+
* assert_eq!(decompressed, original);
|
|
204
|
+
* }
|
|
205
|
+
* Err(e) => {
|
|
206
|
+
* // Handle error
|
|
207
|
+
* assert!(false);
|
|
208
|
+
* }
|
|
209
|
+
* }
|
|
210
|
+
* ```
|
|
211
|
+
*/
|
|
212
|
+
export function decompress_zeck_file(zeck_file: ZeckFile): Uint8Array;
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Deserializes a .zeck file from raw bytes into a [`ZeckFile`] struct.
|
|
216
|
+
*
|
|
217
|
+
* This function reads the header to determine the file format version, original size, and endianness,
|
|
218
|
+
* and constructs a [`ZeckFile`] struct. To decompress the data, call [`crate::zeck_file_format::decompress::decompress_zeck_file`] on the result.
|
|
219
|
+
*
|
|
220
|
+
* # Examples
|
|
221
|
+
*
|
|
222
|
+
* ```
|
|
223
|
+
* # use zeck::zeck_file_format::{compress::compress_zeck_le, file::deserialize_zeck_file, decompress::decompress_zeck_file};
|
|
224
|
+
* let original = vec![0, 1];
|
|
225
|
+
* let zeck_file = compress_zeck_le(&original).unwrap();
|
|
226
|
+
* let zeck_file_bytes = zeck_file.to_bytes();
|
|
227
|
+
* match deserialize_zeck_file(&zeck_file_bytes) {
|
|
228
|
+
* Ok(zeck_file) => {
|
|
229
|
+
* let decompressed = decompress_zeck_file(&zeck_file).unwrap();
|
|
230
|
+
* assert_eq!(decompressed, original);
|
|
231
|
+
* }
|
|
232
|
+
* Err(e) => {
|
|
233
|
+
* // Handle error
|
|
234
|
+
* assert!(false);
|
|
235
|
+
* }
|
|
236
|
+
* }
|
|
237
|
+
* ```
|
|
238
|
+
*/
|
|
239
|
+
export function deserialize_zeck_file(zeck_file_data: Uint8Array): ZeckFile;
|
|
240
|
+
|
|
20
241
|
/**
|
|
21
242
|
* Effective Fibonacci Index to Fibonacci Index: FI(efi) === efi + 2, where efi is the Effective Fibonacci Index
|
|
22
243
|
*
|
|
@@ -64,9 +285,9 @@ export function ezba_from_ezld(effective_zeckendorf_list_descending: BigUint64Ar
|
|
|
64
285
|
*
|
|
65
286
|
* ```
|
|
66
287
|
* # use zeck::ezba_to_ezla;
|
|
67
|
-
* assert_eq!(ezba_to_ezla(&[0, 0, 0, 0, 0, 0, 0, 0]), vec![]);
|
|
68
|
-
* assert_eq!(ezba_to_ezla(&[1, 0, 0, 0, 0, 0, 0, 0]), vec![
|
|
69
|
-
* assert_eq!(ezba_to_ezla(&[1, 1, 1, 0, 0, 0, 0, 0]), vec![
|
|
288
|
+
* assert_eq!(ezba_to_ezla(&[0, 0, 0, 0, 0, 0, 0, 0]), vec![] as Vec<u64>);
|
|
289
|
+
* assert_eq!(ezba_to_ezla(&[1, 0, 0, 0, 0, 0, 0, 0]), vec![0u64]);
|
|
290
|
+
* assert_eq!(ezba_to_ezla(&[1, 1, 1, 0, 0, 0, 0, 0]), vec![0u64, 2u64, 4u64]);
|
|
70
291
|
* ```
|
|
71
292
|
*/
|
|
72
293
|
export function ezba_to_ezla(ezba_bits: Uint8Array): BigUint64Array;
|
|
@@ -194,21 +415,21 @@ export function memoized_slow_fibonacci_recursive(fi: bigint): bigint;
|
|
|
194
415
|
* ```
|
|
195
416
|
* # use zeck::memoized_zeckendorf_list_descending_for_integer;
|
|
196
417
|
* // Base cases
|
|
197
|
-
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(0), vec![]);
|
|
198
|
-
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(1), vec![
|
|
199
|
-
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(2), vec![
|
|
418
|
+
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(0), vec![] as Vec<u64>);
|
|
419
|
+
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(1), vec![2u64]);
|
|
420
|
+
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(2), vec![3u64]);
|
|
200
421
|
*
|
|
201
422
|
* // Small Zeckendorf numbers
|
|
202
|
-
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(3), vec![
|
|
203
|
-
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(4), vec![
|
|
204
|
-
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(5), vec![
|
|
205
|
-
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(6), vec![
|
|
206
|
-
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(7), vec![
|
|
207
|
-
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(8), vec![
|
|
208
|
-
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(9), vec![
|
|
209
|
-
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(10), vec![
|
|
210
|
-
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(11), vec![
|
|
211
|
-
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(12), vec![
|
|
423
|
+
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(3), vec![4u64]);
|
|
424
|
+
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(4), vec![4u64, 2u64]);
|
|
425
|
+
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(5), vec![5u64]);
|
|
426
|
+
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(6), vec![5u64, 2u64]);
|
|
427
|
+
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(7), vec![5u64, 3u64]);
|
|
428
|
+
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(8), vec![6u64]);
|
|
429
|
+
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(9), vec![6u64, 2u64]);
|
|
430
|
+
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(10), vec![6u64, 3u64]);
|
|
431
|
+
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(11), vec![6u64, 4u64]);
|
|
432
|
+
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(12), vec![6u64, 4u64, 2u64]);
|
|
212
433
|
* ```
|
|
213
434
|
*/
|
|
214
435
|
export function memoized_zeckendorf_list_descending_for_integer(n: bigint): BigUint64Array;
|
|
@@ -384,6 +605,16 @@ export function padless_zeckendorf_decompress_le_dangerous(compressed_data: Uint
|
|
|
384
605
|
*/
|
|
385
606
|
export function unpack_bytes_to_ezba_bits(bytes: Uint8Array): Uint8Array;
|
|
386
607
|
|
|
608
|
+
/**
|
|
609
|
+
* We need to make public standalone functions on ZeckFile because for some reason, the #[wasm_bindgen] attribute doesn't seem to work on the struct methods. Maybe using Tsify on ZeckFile is causing the issue.
|
|
610
|
+
* This is a workaround to allow the functions to be used in the WebAssembly module.
|
|
611
|
+
*/
|
|
612
|
+
export function zeck_file_is_big_endian(zeck_file: ZeckFile): boolean;
|
|
613
|
+
|
|
614
|
+
export function zeck_file_to_bytes(zeck_file: ZeckFile): Uint8Array;
|
|
615
|
+
|
|
616
|
+
export function zeck_file_total_size(zeck_file: ZeckFile): number;
|
|
617
|
+
|
|
387
618
|
/**
|
|
388
619
|
* An Effective Zeckendorf List (EZL) has a lowest EFI of 0, which is an FI of 2.
|
|
389
620
|
* This is because it doesn't make sense for the lists to contain FIs 0 or 1 because
|
package/zeck_bg.js
CHANGED
|
@@ -3,6 +3,12 @@ export function __wbg_set_wasm(val) {
|
|
|
3
3
|
wasm = val;
|
|
4
4
|
}
|
|
5
5
|
|
|
6
|
+
function addToExternrefTable0(obj) {
|
|
7
|
+
const idx = wasm.__externref_table_alloc();
|
|
8
|
+
wasm.__wbindgen_externrefs.set(idx, obj);
|
|
9
|
+
return idx;
|
|
10
|
+
}
|
|
11
|
+
|
|
6
12
|
function getArrayU64FromWasm0(ptr, len) {
|
|
7
13
|
ptr = ptr >>> 0;
|
|
8
14
|
return getBigUint64ArrayMemory0().subarray(ptr / 8, ptr / 8 + len);
|
|
@@ -21,6 +27,19 @@ function getBigUint64ArrayMemory0() {
|
|
|
21
27
|
return cachedBigUint64ArrayMemory0;
|
|
22
28
|
}
|
|
23
29
|
|
|
30
|
+
let cachedDataViewMemory0 = null;
|
|
31
|
+
function getDataViewMemory0() {
|
|
32
|
+
if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer)) {
|
|
33
|
+
cachedDataViewMemory0 = new DataView(wasm.memory.buffer);
|
|
34
|
+
}
|
|
35
|
+
return cachedDataViewMemory0;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function getStringFromWasm0(ptr, len) {
|
|
39
|
+
ptr = ptr >>> 0;
|
|
40
|
+
return decodeText(ptr, len);
|
|
41
|
+
}
|
|
42
|
+
|
|
24
43
|
let cachedUint8ArrayMemory0 = null;
|
|
25
44
|
function getUint8ArrayMemory0() {
|
|
26
45
|
if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) {
|
|
@@ -29,6 +48,19 @@ function getUint8ArrayMemory0() {
|
|
|
29
48
|
return cachedUint8ArrayMemory0;
|
|
30
49
|
}
|
|
31
50
|
|
|
51
|
+
function handleError(f, args) {
|
|
52
|
+
try {
|
|
53
|
+
return f.apply(this, args);
|
|
54
|
+
} catch (e) {
|
|
55
|
+
const idx = addToExternrefTable0(e);
|
|
56
|
+
wasm.__wbindgen_exn_store(idx);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function isLikeNone(x) {
|
|
61
|
+
return x === undefined || x === null;
|
|
62
|
+
}
|
|
63
|
+
|
|
32
64
|
function passArray64ToWasm0(arg, malloc) {
|
|
33
65
|
const ptr = malloc(arg.length * 8, 8) >>> 0;
|
|
34
66
|
getBigUint64ArrayMemory0().set(arg, ptr / 8);
|
|
@@ -43,6 +75,76 @@ function passArray8ToWasm0(arg, malloc) {
|
|
|
43
75
|
return ptr;
|
|
44
76
|
}
|
|
45
77
|
|
|
78
|
+
function passStringToWasm0(arg, malloc, realloc) {
|
|
79
|
+
if (realloc === undefined) {
|
|
80
|
+
const buf = cachedTextEncoder.encode(arg);
|
|
81
|
+
const ptr = malloc(buf.length, 1) >>> 0;
|
|
82
|
+
getUint8ArrayMemory0().subarray(ptr, ptr + buf.length).set(buf);
|
|
83
|
+
WASM_VECTOR_LEN = buf.length;
|
|
84
|
+
return ptr;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
let len = arg.length;
|
|
88
|
+
let ptr = malloc(len, 1) >>> 0;
|
|
89
|
+
|
|
90
|
+
const mem = getUint8ArrayMemory0();
|
|
91
|
+
|
|
92
|
+
let offset = 0;
|
|
93
|
+
|
|
94
|
+
for (; offset < len; offset++) {
|
|
95
|
+
const code = arg.charCodeAt(offset);
|
|
96
|
+
if (code > 0x7F) break;
|
|
97
|
+
mem[ptr + offset] = code;
|
|
98
|
+
}
|
|
99
|
+
if (offset !== len) {
|
|
100
|
+
if (offset !== 0) {
|
|
101
|
+
arg = arg.slice(offset);
|
|
102
|
+
}
|
|
103
|
+
ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0;
|
|
104
|
+
const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len);
|
|
105
|
+
const ret = cachedTextEncoder.encodeInto(arg, view);
|
|
106
|
+
|
|
107
|
+
offset += ret.written;
|
|
108
|
+
ptr = realloc(ptr, len, offset, 1) >>> 0;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
WASM_VECTOR_LEN = offset;
|
|
112
|
+
return ptr;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function takeFromExternrefTable0(idx) {
|
|
116
|
+
const value = wasm.__wbindgen_externrefs.get(idx);
|
|
117
|
+
wasm.__externref_table_dealloc(idx);
|
|
118
|
+
return value;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
|
|
122
|
+
cachedTextDecoder.decode();
|
|
123
|
+
const MAX_SAFARI_DECODE_BYTES = 2146435072;
|
|
124
|
+
let numBytesDecoded = 0;
|
|
125
|
+
function decodeText(ptr, len) {
|
|
126
|
+
numBytesDecoded += len;
|
|
127
|
+
if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) {
|
|
128
|
+
cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
|
|
129
|
+
cachedTextDecoder.decode();
|
|
130
|
+
numBytesDecoded = len;
|
|
131
|
+
}
|
|
132
|
+
return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const cachedTextEncoder = new TextEncoder();
|
|
136
|
+
|
|
137
|
+
if (!('encodeInto' in cachedTextEncoder)) {
|
|
138
|
+
cachedTextEncoder.encodeInto = function (arg, view) {
|
|
139
|
+
const buf = cachedTextEncoder.encode(arg);
|
|
140
|
+
view.set(buf);
|
|
141
|
+
return {
|
|
142
|
+
read: arg.length,
|
|
143
|
+
written: buf.length
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
46
148
|
let WASM_VECTOR_LEN = 0;
|
|
47
149
|
|
|
48
150
|
/**
|
|
@@ -66,6 +168,237 @@ export function bit_count_for_number(n) {
|
|
|
66
168
|
return ret >>> 0;
|
|
67
169
|
}
|
|
68
170
|
|
|
171
|
+
/**
|
|
172
|
+
* Compresses data using the Zeckendorf algorithm with big endian interpretation,
|
|
173
|
+
* and stores the result in a [`ZeckFile`] struct.
|
|
174
|
+
*
|
|
175
|
+
* # ⚠️ Warning
|
|
176
|
+
*
|
|
177
|
+
* **Compressing or decompressing data larger than 10KB (10,000 bytes) is unstable due to time and memory pressure.**
|
|
178
|
+
* The library may experience performance issues, excessive memory usage, or failures when processing data exceeding this size.
|
|
179
|
+
*
|
|
180
|
+
* # Examples
|
|
181
|
+
*
|
|
182
|
+
* ```
|
|
183
|
+
* # use zeck::zeck_file_format::compress::compress_zeck_be;
|
|
184
|
+
* let data = vec![1, 0];
|
|
185
|
+
* match compress_zeck_be(&data) {
|
|
186
|
+
* Ok(zeck_file) => {
|
|
187
|
+
* // Access file information
|
|
188
|
+
* println!("Original size: {} bytes", zeck_file.original_size);
|
|
189
|
+
* println!("Is big endian: {}", zeck_file.is_big_endian());
|
|
190
|
+
* // Serialize to bytes for writing to file
|
|
191
|
+
* let bytes = zeck_file.to_bytes();
|
|
192
|
+
* }
|
|
193
|
+
* Err(e) => {
|
|
194
|
+
* // Handle error (e.g., data size too large)
|
|
195
|
+
* }
|
|
196
|
+
* }
|
|
197
|
+
* ```
|
|
198
|
+
* @param {Uint8Array} data
|
|
199
|
+
* @returns {ZeckFile}
|
|
200
|
+
*/
|
|
201
|
+
export function compress_zeck_be(data) {
|
|
202
|
+
const ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
|
|
203
|
+
const len0 = WASM_VECTOR_LEN;
|
|
204
|
+
const ret = wasm.compress_zeck_be(ptr0, len0);
|
|
205
|
+
if (ret[2]) {
|
|
206
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
207
|
+
}
|
|
208
|
+
return takeFromExternrefTable0(ret[0]);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Compresses data using the Zeckendorf algorithm with automatic endianness selection,
|
|
213
|
+
* and stores the result in a [`BestCompressionResult`] struct.
|
|
214
|
+
*
|
|
215
|
+
* This function attempts compression with both big endian and little endian interpretations,
|
|
216
|
+
* and returns the best result, or if neither produced compression (both were larger than the original).
|
|
217
|
+
*
|
|
218
|
+
* # ⚠️ Warning
|
|
219
|
+
*
|
|
220
|
+
* **Compressing or decompressing data larger than 10KB (10,000 bytes) is unstable due to time and memory pressure.**
|
|
221
|
+
* The library may experience performance issues, excessive memory usage, or failures when processing data exceeding this size.
|
|
222
|
+
*
|
|
223
|
+
* # Examples
|
|
224
|
+
*
|
|
225
|
+
* ```
|
|
226
|
+
* # use zeck::zeck_file_format::compress::compress_zeck_best;
|
|
227
|
+
* # use zeck::zeck_file_format::compress::BestCompressionResult;
|
|
228
|
+
* # use zeck::zeck_file_format::decompress::decompress_zeck_file;
|
|
229
|
+
* let data = vec![0, 1]; // Compresses best interpreted as a big endian integer
|
|
230
|
+
* match compress_zeck_best(&data) {
|
|
231
|
+
* Ok(best_compression_result) => {
|
|
232
|
+
* match best_compression_result {
|
|
233
|
+
* BestCompressionResult::BigEndianBest { zeck_file, le_size } => {
|
|
234
|
+
* let decompressed = decompress_zeck_file(&zeck_file).unwrap();
|
|
235
|
+
* assert_eq!(decompressed, data);
|
|
236
|
+
* }
|
|
237
|
+
* BestCompressionResult::LittleEndianBest { zeck_file, be_size } => {
|
|
238
|
+
* assert!(false);
|
|
239
|
+
* }
|
|
240
|
+
* BestCompressionResult::Neither { be_size, le_size } => {
|
|
241
|
+
* assert!(false);
|
|
242
|
+
* }
|
|
243
|
+
* }
|
|
244
|
+
* }
|
|
245
|
+
* Err(e) => {
|
|
246
|
+
* assert!(false);
|
|
247
|
+
* }
|
|
248
|
+
* }
|
|
249
|
+
*
|
|
250
|
+
* let data = vec![1, 0]; // Compresses best interpreted as a little endian integer
|
|
251
|
+
* match compress_zeck_best(&data) {
|
|
252
|
+
* Ok(best_compression_result) => {
|
|
253
|
+
* match best_compression_result {
|
|
254
|
+
* BestCompressionResult::BigEndianBest { zeck_file, le_size } => {
|
|
255
|
+
* assert!(false);
|
|
256
|
+
* }
|
|
257
|
+
* BestCompressionResult::LittleEndianBest { zeck_file, be_size } => {
|
|
258
|
+
* let decompressed = decompress_zeck_file(&zeck_file).unwrap();
|
|
259
|
+
* assert_eq!(decompressed, data);
|
|
260
|
+
* }
|
|
261
|
+
* BestCompressionResult::Neither { be_size, le_size } => {
|
|
262
|
+
* assert!(false);
|
|
263
|
+
* }
|
|
264
|
+
* }
|
|
265
|
+
* }
|
|
266
|
+
* Err(e) => {
|
|
267
|
+
* assert!(false);
|
|
268
|
+
* }
|
|
269
|
+
* }
|
|
270
|
+
* ```
|
|
271
|
+
* @param {Uint8Array} data
|
|
272
|
+
* @returns {BestCompressionResult}
|
|
273
|
+
*/
|
|
274
|
+
export function compress_zeck_best(data) {
|
|
275
|
+
const ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
|
|
276
|
+
const len0 = WASM_VECTOR_LEN;
|
|
277
|
+
const ret = wasm.compress_zeck_best(ptr0, len0);
|
|
278
|
+
if (ret[2]) {
|
|
279
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
280
|
+
}
|
|
281
|
+
return takeFromExternrefTable0(ret[0]);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Compresses data using the Zeckendorf algorithm with little endian interpretation,
|
|
286
|
+
* and stores the result in a [`ZeckFile`] struct.
|
|
287
|
+
*
|
|
288
|
+
* # ⚠️ Warning
|
|
289
|
+
*
|
|
290
|
+
* **Compressing or decompressing data larger than 10KB (10,000 bytes) is unstable due to time and memory pressure.**
|
|
291
|
+
* The library may experience performance issues, excessive memory usage, or failures when processing data exceeding this size.
|
|
292
|
+
*
|
|
293
|
+
* # Examples
|
|
294
|
+
*
|
|
295
|
+
* ```
|
|
296
|
+
* # use zeck::zeck_file_format::compress::compress_zeck_le;
|
|
297
|
+
* let data = vec![1, 0];
|
|
298
|
+
* match compress_zeck_le(&data) {
|
|
299
|
+
* Ok(zeck_file) => {
|
|
300
|
+
* // Access file information
|
|
301
|
+
* println!("Original size: {} bytes", zeck_file.original_size);
|
|
302
|
+
* println!("Compressed size: {} bytes", zeck_file.compressed_data.len());
|
|
303
|
+
* // Serialize to bytes for writing to file
|
|
304
|
+
* let bytes = zeck_file.to_bytes();
|
|
305
|
+
* }
|
|
306
|
+
* Err(e) => {
|
|
307
|
+
* // Handle error (e.g., data size too large)
|
|
308
|
+
* }
|
|
309
|
+
* }
|
|
310
|
+
* ```
|
|
311
|
+
* @param {Uint8Array} data
|
|
312
|
+
* @returns {ZeckFile}
|
|
313
|
+
*/
|
|
314
|
+
export function compress_zeck_le(data) {
|
|
315
|
+
const ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
|
|
316
|
+
const len0 = WASM_VECTOR_LEN;
|
|
317
|
+
const ret = wasm.compress_zeck_le(ptr0, len0);
|
|
318
|
+
if (ret[2]) {
|
|
319
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
320
|
+
}
|
|
321
|
+
return takeFromExternrefTable0(ret[0]);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* Decompresses data from a [`ZeckFile`] struct.
|
|
326
|
+
*
|
|
327
|
+
* This function takes a [`ZeckFile`] directly and uses its header information to decompress
|
|
328
|
+
* the data. This is a convenience function that avoids the need to serialize and parse the
|
|
329
|
+
* file format when you already have a [`ZeckFile`] struct.
|
|
330
|
+
*
|
|
331
|
+
* # ⚠️ Warning
|
|
332
|
+
*
|
|
333
|
+
* **Compressing or decompressing data larger than 10KB (10,000 bytes) is unstable due to time and memory pressure.**
|
|
334
|
+
* The library may experience performance issues, excessive memory usage, or failures when processing data exceeding this size.
|
|
335
|
+
*
|
|
336
|
+
* # Examples
|
|
337
|
+
*
|
|
338
|
+
* ```
|
|
339
|
+
* # use zeck::zeck_file_format::{compress::compress_zeck_le, decompress::decompress_zeck_file};
|
|
340
|
+
* let original = vec![0, 1];
|
|
341
|
+
* let zeck_file = compress_zeck_le(&original).unwrap();
|
|
342
|
+
* match decompress_zeck_file(&zeck_file) {
|
|
343
|
+
* Ok(decompressed) => {
|
|
344
|
+
* assert_eq!(decompressed, original);
|
|
345
|
+
* }
|
|
346
|
+
* Err(e) => {
|
|
347
|
+
* // Handle error
|
|
348
|
+
* assert!(false);
|
|
349
|
+
* }
|
|
350
|
+
* }
|
|
351
|
+
* ```
|
|
352
|
+
* @param {ZeckFile} zeck_file
|
|
353
|
+
* @returns {Uint8Array}
|
|
354
|
+
*/
|
|
355
|
+
export function decompress_zeck_file(zeck_file) {
|
|
356
|
+
const ret = wasm.decompress_zeck_file(zeck_file);
|
|
357
|
+
if (ret[3]) {
|
|
358
|
+
throw takeFromExternrefTable0(ret[2]);
|
|
359
|
+
}
|
|
360
|
+
var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
|
|
361
|
+
wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
|
|
362
|
+
return v1;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
* Deserializes a .zeck file from raw bytes into a [`ZeckFile`] struct.
|
|
367
|
+
*
|
|
368
|
+
* This function reads the header to determine the file format version, original size, and endianness,
|
|
369
|
+
* and constructs a [`ZeckFile`] struct. To decompress the data, call [`crate::zeck_file_format::decompress::decompress_zeck_file`] on the result.
|
|
370
|
+
*
|
|
371
|
+
* # Examples
|
|
372
|
+
*
|
|
373
|
+
* ```
|
|
374
|
+
* # use zeck::zeck_file_format::{compress::compress_zeck_le, file::deserialize_zeck_file, decompress::decompress_zeck_file};
|
|
375
|
+
* let original = vec![0, 1];
|
|
376
|
+
* let zeck_file = compress_zeck_le(&original).unwrap();
|
|
377
|
+
* let zeck_file_bytes = zeck_file.to_bytes();
|
|
378
|
+
* match deserialize_zeck_file(&zeck_file_bytes) {
|
|
379
|
+
* Ok(zeck_file) => {
|
|
380
|
+
* let decompressed = decompress_zeck_file(&zeck_file).unwrap();
|
|
381
|
+
* assert_eq!(decompressed, original);
|
|
382
|
+
* }
|
|
383
|
+
* Err(e) => {
|
|
384
|
+
* // Handle error
|
|
385
|
+
* assert!(false);
|
|
386
|
+
* }
|
|
387
|
+
* }
|
|
388
|
+
* ```
|
|
389
|
+
* @param {Uint8Array} zeck_file_data
|
|
390
|
+
* @returns {ZeckFile}
|
|
391
|
+
*/
|
|
392
|
+
export function deserialize_zeck_file(zeck_file_data) {
|
|
393
|
+
const ptr0 = passArray8ToWasm0(zeck_file_data, wasm.__wbindgen_malloc);
|
|
394
|
+
const len0 = WASM_VECTOR_LEN;
|
|
395
|
+
const ret = wasm.deserialize_zeck_file(ptr0, len0);
|
|
396
|
+
if (ret[2]) {
|
|
397
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
398
|
+
}
|
|
399
|
+
return takeFromExternrefTable0(ret[0]);
|
|
400
|
+
}
|
|
401
|
+
|
|
69
402
|
/**
|
|
70
403
|
* Effective Fibonacci Index to Fibonacci Index: FI(efi) === efi + 2, where efi is the Effective Fibonacci Index
|
|
71
404
|
*
|
|
@@ -127,9 +460,9 @@ export function ezba_from_ezld(effective_zeckendorf_list_descending) {
|
|
|
127
460
|
*
|
|
128
461
|
* ```
|
|
129
462
|
* # use zeck::ezba_to_ezla;
|
|
130
|
-
* assert_eq!(ezba_to_ezla(&[0, 0, 0, 0, 0, 0, 0, 0]), vec![]);
|
|
131
|
-
* assert_eq!(ezba_to_ezla(&[1, 0, 0, 0, 0, 0, 0, 0]), vec![
|
|
132
|
-
* assert_eq!(ezba_to_ezla(&[1, 1, 1, 0, 0, 0, 0, 0]), vec![
|
|
463
|
+
* assert_eq!(ezba_to_ezla(&[0, 0, 0, 0, 0, 0, 0, 0]), vec![] as Vec<u64>);
|
|
464
|
+
* assert_eq!(ezba_to_ezla(&[1, 0, 0, 0, 0, 0, 0, 0]), vec![0u64]);
|
|
465
|
+
* assert_eq!(ezba_to_ezla(&[1, 1, 1, 0, 0, 0, 0, 0]), vec![0u64, 2u64, 4u64]);
|
|
133
466
|
* ```
|
|
134
467
|
* @param {Uint8Array} ezba_bits
|
|
135
468
|
* @returns {BigUint64Array}
|
|
@@ -295,21 +628,21 @@ export function memoized_slow_fibonacci_recursive(fi) {
|
|
|
295
628
|
* ```
|
|
296
629
|
* # use zeck::memoized_zeckendorf_list_descending_for_integer;
|
|
297
630
|
* // Base cases
|
|
298
|
-
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(0), vec![]);
|
|
299
|
-
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(1), vec![
|
|
300
|
-
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(2), vec![
|
|
631
|
+
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(0), vec![] as Vec<u64>);
|
|
632
|
+
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(1), vec![2u64]);
|
|
633
|
+
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(2), vec![3u64]);
|
|
301
634
|
*
|
|
302
635
|
* // Small Zeckendorf numbers
|
|
303
|
-
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(3), vec![
|
|
304
|
-
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(4), vec![
|
|
305
|
-
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(5), vec![
|
|
306
|
-
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(6), vec![
|
|
307
|
-
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(7), vec![
|
|
308
|
-
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(8), vec![
|
|
309
|
-
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(9), vec![
|
|
310
|
-
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(10), vec![
|
|
311
|
-
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(11), vec![
|
|
312
|
-
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(12), vec![
|
|
636
|
+
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(3), vec![4u64]);
|
|
637
|
+
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(4), vec![4u64, 2u64]);
|
|
638
|
+
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(5), vec![5u64]);
|
|
639
|
+
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(6), vec![5u64, 2u64]);
|
|
640
|
+
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(7), vec![5u64, 3u64]);
|
|
641
|
+
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(8), vec![6u64]);
|
|
642
|
+
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(9), vec![6u64, 2u64]);
|
|
643
|
+
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(10), vec![6u64, 3u64]);
|
|
644
|
+
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(11), vec![6u64, 4u64]);
|
|
645
|
+
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(12), vec![6u64, 4u64, 2u64]);
|
|
313
646
|
* ```
|
|
314
647
|
* @param {bigint} n
|
|
315
648
|
* @returns {BigUint64Array}
|
|
@@ -546,6 +879,37 @@ export function unpack_bytes_to_ezba_bits(bytes) {
|
|
|
546
879
|
return v2;
|
|
547
880
|
}
|
|
548
881
|
|
|
882
|
+
/**
|
|
883
|
+
* We need to make public standalone functions on ZeckFile because for some reason, the #[wasm_bindgen] attribute doesn't seem to work on the struct methods. Maybe using Tsify on ZeckFile is causing the issue.
|
|
884
|
+
* This is a workaround to allow the functions to be used in the WebAssembly module.
|
|
885
|
+
* @param {ZeckFile} zeck_file
|
|
886
|
+
* @returns {boolean}
|
|
887
|
+
*/
|
|
888
|
+
export function zeck_file_is_big_endian(zeck_file) {
|
|
889
|
+
const ret = wasm.zeck_file_is_big_endian(zeck_file);
|
|
890
|
+
return ret !== 0;
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
/**
|
|
894
|
+
* @param {ZeckFile} zeck_file
|
|
895
|
+
* @returns {Uint8Array}
|
|
896
|
+
*/
|
|
897
|
+
export function zeck_file_to_bytes(zeck_file) {
|
|
898
|
+
const ret = wasm.zeck_file_to_bytes(zeck_file);
|
|
899
|
+
var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
|
|
900
|
+
wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
|
|
901
|
+
return v1;
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
/**
|
|
905
|
+
* @param {ZeckFile} zeck_file
|
|
906
|
+
* @returns {number}
|
|
907
|
+
*/
|
|
908
|
+
export function zeck_file_total_size(zeck_file) {
|
|
909
|
+
const ret = wasm.zeck_file_total_size(zeck_file);
|
|
910
|
+
return ret >>> 0;
|
|
911
|
+
}
|
|
912
|
+
|
|
549
913
|
/**
|
|
550
914
|
* An Effective Zeckendorf List (EZL) has a lowest EFI of 0, which is an FI of 2.
|
|
551
915
|
* This is because it doesn't make sense for the lists to contain FIs 0 or 1 because
|
|
@@ -574,6 +938,34 @@ export function zl_to_ezl(zl) {
|
|
|
574
938
|
return v2;
|
|
575
939
|
}
|
|
576
940
|
|
|
941
|
+
export function __wbg___wbindgen_is_undefined_f6b95eab589e0269(arg0) {
|
|
942
|
+
const ret = arg0 === undefined;
|
|
943
|
+
return ret;
|
|
944
|
+
};
|
|
945
|
+
|
|
946
|
+
export function __wbg___wbindgen_string_get_a2a31e16edf96e42(arg0, arg1) {
|
|
947
|
+
const obj = arg1;
|
|
948
|
+
const ret = typeof(obj) === 'string' ? obj : undefined;
|
|
949
|
+
var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
950
|
+
var len1 = WASM_VECTOR_LEN;
|
|
951
|
+
getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
|
|
952
|
+
getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
|
|
953
|
+
};
|
|
954
|
+
|
|
955
|
+
export function __wbg___wbindgen_throw_dd24417ed36fc46e(arg0, arg1) {
|
|
956
|
+
throw new Error(getStringFromWasm0(arg0, arg1));
|
|
957
|
+
};
|
|
958
|
+
|
|
959
|
+
export function __wbg_parse_a09a54cf72639456() { return handleError(function (arg0, arg1) {
|
|
960
|
+
const ret = JSON.parse(getStringFromWasm0(arg0, arg1));
|
|
961
|
+
return ret;
|
|
962
|
+
}, arguments) };
|
|
963
|
+
|
|
964
|
+
export function __wbg_stringify_655a6390e1f5eb6b() { return handleError(function (arg0) {
|
|
965
|
+
const ret = JSON.stringify(arg0);
|
|
966
|
+
return ret;
|
|
967
|
+
}, arguments) };
|
|
968
|
+
|
|
577
969
|
export function __wbindgen_init_externref_table() {
|
|
578
970
|
const table = wasm.__wbindgen_externrefs;
|
|
579
971
|
const offset = table.grow(4);
|
package/zeck_bg.wasm
CHANGED
|
Binary file
|