smart-downscaler 0.6.2 → 0.6.4

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 CHANGED
@@ -35,7 +35,10 @@ A high-performance Rust library for intelligent image downscaling with pixel art
35
35
  | **Edge-Aware Processing** | Sobel/Scharr detection preserves boundaries |
36
36
  | **Spatial Coherence** | Neighbor and region voting for smooth results |
37
37
  | **K-Centroid Tile Logic** | Advanced dominant color extraction per tile |
38
- | **Rare-Color Preservation** | Saliency weighting + slot reservation keeps small, important colors (lips, eyes) |
38
+ | **Rare-Color Preservation** | Saliency weighting + slot reservation keeps small important colors (lips, eyes) |
39
+ | **Chroma Recovery** | Restores saturation lost to color merging, by perceptual difference |
40
+ | **Skin-Tone Isolation** | Keeps skin and non-skin colors in separate palette domains |
41
+ | **Reusable Preprocessing** | Prepare an image once, downscale to many sizes cheaply |
39
42
  | **Performance Preprocessing** | Resolution capping and color pre-quantization |
40
43
  | **WebAssembly Support** | Full browser compatibility with near-native speed |
41
44
 
@@ -171,10 +174,12 @@ println!("Palette: {} colors", result.palette.len());
171
174
  | **Tile Processing** |||||
172
175
  | `k_centroid` | `usize` | `1` | `1`, `2`, `3`, `4` | Tile color extraction mode |
173
176
  | `k_centroid_iterations` | `usize` | `0` | `0-10` | K-Means iterations for tile color |
174
- | **Rare-Color Preservation** |||||
175
- | `color_rarity` | `f32` | `0.0` | `0.0-1.0` | Damps frequency vote so large flat areas stop dominating (`0`=area, `1`=`count^0.5`) |
176
- | `detail_boost` | `f32` | `0.0` | `0.0-2.0` | Boosts colors in detail-rich regions via a local-contrast saliency map (`0`=off) |
177
- | `reserve_colors` | `usize` | `0` | `0 - palette_size` | Reserve N palette slots for distinct, important, under-represented source colors (`0`=off) |
177
+ | **Rare-Color & Saturation** |||||
178
+ | `color_rarity` | `f32` | `0.0` | `0.0-1.0` | Damps frequency vote so flat areas stop dominating (`0`=area, `1`=`count^0.5`) |
179
+ | `detail_boost` | `f32` | `0.0` | `0.0-2.0` | Boosts colors in detail-rich regions via local-contrast saliency (`0`=off) |
180
+ | `reserve_colors` | `usize` | `0` | `0 - palette_size` | Reserve N slots for distinct, important, under-represented source colors (`0`=off) |
181
+ | `chroma_recovery` | `f32` | `0.0` | `0.0-1.0+` | Restore chroma lost to merging toward source mean chroma, constant hue, gamut-clamped (`0`=off) |
182
+ | `skin_protection` | `f32` | `0.0` | `0.0-1.0` | Isolate skin vs non-skin into separate palette domains + quantization penalty (`0`=off) |
178
183
 
179
184
  ---
180
185
 
@@ -231,7 +236,7 @@ Controls how each source tile is reduced to a single representative color:
231
236
  | **Foremost** | `3` | K-Means (k=3), finer dominant detection | Complex textures, detailed sprites |
232
237
  | **Salient** | `4` | K-Means (k=2), keeps a distinctly-more-chromatic minority | Thin colorful features (lips, eyes, makeup) |
233
238
 
234
- > **Note:** Mode `2` (Dominant) snaps a mixed tile to its *larger* cluster, which discards thin minority colors — a tile that is 60% skin / 40% lip becomes pure skin. For faces and other artwork with small colorful features, prefer mode `4`, which keeps the colorful minority when it is non-trivial (≥22% of the tile) and clearly more chromatic than the majority.
239
+ > **Note:** Mode `2` (Dominant) snaps a mixed tile to its *larger* cluster, discarding thin minority colors — a tile that is 60% skin / 40% lip becomes pure skin. For faces and artwork with small colorful features, prefer mode `4`, which keeps the colorful minority when it is non-trivial (≥22% of the tile) and clearly more chromatic than the majority.
235
240
 
236
241
  ```javascript
237
242
  // Mode 1: Average (default) - smooth results
@@ -323,6 +328,36 @@ const result = downscale_with_palette(
323
328
 
324
329
  ---
325
330
 
331
+ ### Prepare / Reuse Functions
332
+
333
+ #### `prepare(data, width, height, config?)` / `prepare_rgba(data, width, height, config?)`
334
+
335
+ Run target-independent work (resolution cap, color pre-quantization, segmentation)
336
+ once and return a reusable handle. `prepare` takes `Uint8Array`; `prepare_rgba` takes
337
+ `Uint8ClampedArray` (from canvas `getImageData`).
338
+
339
+ ```javascript
340
+ const prepared = prepare_rgba(imageData.data, imageData.width, imageData.height, config);
341
+ // prepared.width / prepared.height — dimensions after any resolution cap
342
+ prepared.free(); // release WASM memory when finished
343
+ ```
344
+
345
+ #### `downscale_prepared(prepared, targetWidth, targetHeight, config?)`
346
+
347
+ Downscale a prepared image. The optional `config` overrides per-target knobs
348
+ (`palette_size`, `k_centroid`, `chroma_recovery`, `skin_protection`, …); preprocess
349
+ and segmentation settings always come from prepare time.
350
+
351
+ ```javascript
352
+ const result = downscale_prepared(prepared, 128, 128, sizeConfig);
353
+ ```
354
+
355
+ #### `downscale_prepared_with_palette(prepared, targetWidth, targetHeight, palette, config?)`
356
+
357
+ As above, with a caller-supplied `Uint8Array` RGB palette.
358
+
359
+ ---
360
+
326
361
  ### Palette Functions
327
362
 
328
363
  #### `extract_palette_from_image(data, width, height, numColors, iterations, strategy?)`
@@ -508,58 +543,140 @@ const exact = WasmDownscaleConfig.exact_colors();
508
543
 
509
544
  ### Preset Comparison
510
545
 
511
- | Preset | Palette | K-Means | Segmentation | K-Centroid | Rare-Color¹ | Speed |
512
- |--------|---------|---------|--------------|------------|-------------|-------|
546
+ | Preset | Palette | K-Means | Segmentation | K-Centroid | Rare/Sat/Skin¹ | Speed |
547
+ |--------|---------|---------|--------------|------------|----------------|-------|
513
548
  | `fast()` | 16 | 3 | none | 1 (avg) | off | ⚡⚡⚡ |
514
549
  | `default` | 16 | 5 | hierarchy_fast | 1 (avg) | off | ⚡⚡ |
515
- | `vibrant()` | 24 | 8 | hierarchy_fast | 2 (dom) | on (3 slots) | ⚡ |
516
- | `quality()` | 32 | 10 | hierarchy | 2 (dom) | on (4 slots) | 🐢 |
550
+ | `vibrant()` | 24 | 8 | hierarchy_fast | 2 (dom) | reserve+rarity+chroma(0.7) | ⚡ |
551
+ | `quality()` | 32 | 10 | hierarchy | 2 (dom) | reserve+rarity+chroma(0.6)+skin(0.5) | 🐢 |
517
552
  | `exact_colors()` | 16 | 0 | hierarchy_fast | 1 (avg) | off | ⚡⚡ |
518
553
 
519
- ¹ `vibrant()` and `quality()` enable `reserve_colors` + `detail_boost` + `color_rarity`. For the strongest thin-feature retention (faces), additionally set `k_centroid = 4`.
554
+ ¹ For the strongest thin-feature retention on faces, additionally set `k_centroid = 4`.
520
555
 
521
556
  ---
522
557
 
523
558
  ## Advanced Usage
524
559
 
560
+ ### Reusing Preprocessing Across Sizes (Performance)
561
+
562
+ Resolution capping, color pre-quantization, and region segmentation depend only on
563
+ the **source** image, not the target size. When you downscale the same source to
564
+ several sizes (e.g. multiple previews), repeating that work each time is wasted.
565
+ `prepare` runs it **once**; `downscale_prepared` then only does palette extraction
566
+ and tiling per size.
567
+
568
+ ```javascript
569
+ import init, { prepare_rgba, downscale_prepared, WasmDownscaleConfig } from 'smart-downscaler';
570
+ await init();
571
+
572
+ const base = new WasmDownscaleConfig();
573
+ base.segmentation_method = 'hierarchy_fast';
574
+ base.max_resolution_mp = 2.048;
575
+ base.max_color_preprocess = 4096;
576
+
577
+ // Once per source image:
578
+ const prepared = prepare_rgba(imageData.data, imageData.width, imageData.height, base);
579
+
580
+ // Many times, cheaply — palette_size and target size may differ each call:
581
+ for (const { w, h, colors } of sizes) {
582
+ const cfg = new WasmDownscaleConfig();
583
+ cfg.palette_size = colors;
584
+ cfg.k_centroid = 4;
585
+ cfg.reserve_colors = Math.round(colors / 8);
586
+ cfg.chroma_recovery = 0.6;
587
+ cfg.skin_protection = 0.5;
588
+ const result = downscale_prepared(prepared, w, h, cfg);
589
+ // ... use result ...
590
+ }
591
+
592
+ prepared.free(); // release WASM memory when done (also freed on GC)
593
+ ```
594
+
595
+ **Contract:** the prepared image fixes `max_resolution_mp`, `max_color_preprocess`,
596
+ and `segmentation_*` at prepare time. `downscale_prepared` overlays per-target knobs
597
+ (`palette_size`, `k_centroid`, `chroma_recovery`, `skin_protection`, …) but never
598
+ re-runs preprocessing or segmentation. Change any of the prepare-time settings →
599
+ call `prepare` again. `prepare` / `prepare_rgba` and `downscale_prepared` /
600
+ `downscale_prepared_with_palette` mirror the one-shot functions.
601
+
602
+ In Rust:
603
+
604
+ ```rust
605
+ use smart_downscaler::{prepare_image, smart_downscale_prepared, DownscaleConfig};
606
+
607
+ let prepared = prepare_image(&pixels, w, h, &config); // once
608
+ let small = smart_downscale_prepared(&prepared, 128, 128, &config_s); // reuse
609
+ let large = smart_downscale_prepared(&prepared, 256, 256, &config_l); // reuse
610
+ ```
611
+
525
612
  ### Preserving Rare / Important Colors
526
613
 
527
- Palette extraction is **area-weighted**: a color that covers a large region gets
528
- many "votes", so small but perceptually important colors — lips, eyes, a logo,
529
- a colored highlight are easily merged into the dominant tones (e.g. lips into
530
- skin) at low palette sizes (16–64). Three knobs counteract this:
614
+ Palette extraction is **area-weighted**: a color covering a large region gets many
615
+ "votes", so small but important colors — lips, eyes, a logo, a highlight — easily
616
+ merge into dominant tones at low palette sizes (16–64). Counteract this with:
531
617
 
532
618
  | Knob | What it does | When to raise it |
533
619
  |------|--------------|------------------|
534
- | `reserve_colors` | **Hard guarantee.** Reserves N slots, filled with exact source colors that are far from the rest of the palette *and* important. The most reliable fix. | Always, for portraits/artwork with small features. ~`palette_size / 8`. |
535
- | `detail_boost` | Weights extraction toward colors in **detail-rich regions** using a local-contrast saliency map (measured at the downscale radius, so it targets features thin enough to be averaged away — and picks their *clean* interior color, not muddy edge blends). | When the important color sits in a high-detail area (most facial features). `0.8–1.0`. |
620
+ | `reserve_colors` | **Hard guarantee.** Reserves N slots filled with exact source colors that are far from the rest of the palette *and* important. Most reliable fix. | Always, for portraits. ~`palette_size / 8`. |
621
+ | `detail_boost` | Weights extraction toward **detail-rich regions** via a local-contrast saliency map (measured at the downscale radius, so it targets features thin enough to be averaged away). | When the important color is in a high-detail area. `0.8–1.0`. |
536
622
  | `color_rarity` | Damps the frequency vote (`count^p`, `p = 1 − 0.5·rarity`) so large flat regions stop monopolizing the palette. | Mild assist alongside the above. `0.3–0.4`. |
537
623
 
538
- Pair these with `k_centroid = 4` (Salient), which stops the *tile* stage from
539
- discarding the same minority colors. A correct palette is wasted if a 60% skin /
540
- 40% lip tile is still snapped to skin.
624
+ Pair these with `k_centroid = 4` (Salient) so the *tile* stage doesn't discard the
625
+ same minority colors a correct palette preserved.
626
+
627
+ ### Restoring Saturation (Chroma Recovery)
628
+
629
+ Averaging colors in Oklab during median-cut/k-means pulls the result *inward* — the
630
+ mean of two hues is less colorful than either. `chroma_recovery` undoes this **by
631
+ perceptual difference**: each palette color is pushed back toward the count-weighted
632
+ **mean chroma of the source colors it represents**, at constant hue and lightness,
633
+ then clamped to the sRGB gamut. It only ever *increases* saturation, never reduces it.
634
+
635
+ ```javascript
636
+ config.chroma_recovery = 0.6; // 0 = off, ~0.6 natural, 1.0 = full restoration, >1 = punchy
637
+ ```
638
+
639
+ This is a global de-wash that fixes the "muddy" look of low-palette output; it is
640
+ independent of (and composes with) the rare-color knobs above.
641
+
642
+ ### Isolating Skin Tones
643
+
644
+ Skin clusters tightly in the YCbCr chroma plane (`80 ≤ Cb ≤ 120`, `133 ≤ Cr ≤ 173`).
645
+ With `skin_protection > 0`, skin and non-skin colors are extracted in **separate
646
+ domains** — a single palette bucket never mixes the two, so skin never picks up a
647
+ muddy blend with hair/background and vice-versa. Palette slots are split between the
648
+ domains by population (each guaranteed at least one). The same value also acts as a
649
+ **quantization penalty**: a skin tile prefers skin palette colors, a non-skin tile
650
+ prefers non-skin.
651
+
652
+ ```javascript
653
+ config.skin_protection = 0.5; // 0 = off, ~0.5 typical
654
+ ```
655
+
656
+ > Lips are reddish and usually pass the skin test, so they live in the *skin* domain
657
+ > — `skin_protection` won't separate lips from skin. Use `reserve_colors` /
658
+ > `k_centroid = 4` for that; they operate *within* the skin domain, so the two
659
+ > features compose: skin gets its own budget, and a distinct lip is preserved inside it.
660
+
661
+ ### Recommended Config for Faces / Portraits
541
662
 
542
663
  ```javascript
543
- // Recommended for faces / portraits at 16–64 colors
544
664
  const config = new WasmDownscaleConfig();
545
665
  config.palette_size = 32;
546
- config.palette_strategy = 'oklab'; // honors color_rarity / detail_boost in median-cut
547
- config.k_centroid = 4; // salient tile color (keep colorful minorities)
666
+ config.palette_strategy = 'oklab'; // honors color_rarity / detail_boost
667
+ config.k_centroid = 4; // salient tile color
548
668
  config.k_centroid_iterations = 2;
549
669
  config.reserve_colors = 4; // ~palette_size / 8 — the guarantee
550
670
  config.detail_boost = 0.9; // saliency targeting
551
671
  config.color_rarity = 0.35; // frequency damping
672
+ config.chroma_recovery = 0.6; // restore saturation lost to merging
673
+ config.skin_protection = 0.5; // separate skin / non-skin
552
674
  config.neighbor_weight = 0.18; // lower = less erosion of thin features
553
675
  ```
554
676
 
555
- > **Trade-off:** at very small palettes, reserving slots for rare colors costs
556
- > some gradient smoothness elsewhere. Scale `reserve_colors` with `palette_size`
557
- > (16→2, 32→4, 64→8) and lean on it harder at the high end.
558
- >
559
- > **Strategy note:** `bitmask` ignores frequency weights during its initial
560
- > split, so with `bitmask` only `reserve_colors` is active. Use `oklab` (or
561
- > `saturation`) if you also want `color_rarity` / `detail_boost` to shape the
562
- > main palette.
677
+ > **Strategy note:** `bitmask` ignores frequency weights during its initial split, so
678
+ > with `bitmask` only `reserve_colors` is active. Use `oklab` (or `saturation`) if you
679
+ > also want `color_rarity` / `detail_boost` to shape the main palette.
563
680
 
564
681
  ### Custom Palette Workflow
565
682
 
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "Pixagram"
6
6
  ],
7
7
  "description": "Intelligent pixel art downscaler with region-aware color quantization",
8
- "version": "0.6.2",
8
+ "version": "0.6.4",
9
9
  "license": "MIT",
10
10
  "repository": {
11
11
  "type": "git",
@@ -14,13 +14,11 @@
14
14
  "files": [
15
15
  "smart_downscaler_bg.wasm",
16
16
  "smart_downscaler.js",
17
- "smart_downscaler_bg.js",
18
17
  "smart_downscaler.d.ts"
19
18
  ],
20
19
  "main": "smart_downscaler.js",
21
20
  "types": "smart_downscaler.d.ts",
22
21
  "sideEffects": [
23
- "./smart_downscaler.js",
24
22
  "./snippets/*"
25
23
  ],
26
24
  "keywords": [
@@ -33,6 +33,10 @@ export class WasmDownscaleConfig {
33
33
  constructor();
34
34
  static quality(): WasmDownscaleConfig;
35
35
  static vibrant(): WasmDownscaleConfig;
36
+ /**
37
+ * Restore chroma lost to merging (constant hue, gamut-clamped). 0.0 = off, ~0.6 natural.
38
+ */
39
+ chroma_recovery: number;
36
40
  /**
37
41
  * Rare-color preservation: 0.0 = pure area weighting, 1.0 = strong (count^0.5).
38
42
  */
@@ -57,6 +61,10 @@ export class WasmDownscaleConfig {
57
61
  * Reserve N palette slots for distinct, important, under-represented colors. 0 = off.
58
62
  */
59
63
  reserve_colors: number;
64
+ /**
65
+ * Isolate skin tones from non-skin (separate domains + mismatch penalty). 0.0 = off, ~0.5.
66
+ */
67
+ skin_protection: number;
60
68
  slic_compactness: number;
61
69
  slic_superpixels: number;
62
70
  two_pass_refinement: boolean;
@@ -77,6 +85,22 @@ export class WasmDownscaleResult {
77
85
  readonly width: number;
78
86
  }
79
87
 
88
+ /**
89
+ * Opaque handle holding the prepared (preprocessed + segmented) source image.
90
+ * Build with [`prepare`] / [`prepare_rgba`], reuse with [`downscale_prepared`].
91
+ *
92
+ * The segmentation is fixed at prepare time from the config you pass. Palette
93
+ * size and target dimensions may differ on every [`downscale_prepared`] call.
94
+ * If you change resolution / color-preprocess / segmentation settings, prepare again.
95
+ */
96
+ export class WasmPreparedImage {
97
+ private constructor();
98
+ free(): void;
99
+ [Symbol.dispose](): void;
100
+ readonly height: number;
101
+ readonly width: number;
102
+ }
103
+
80
104
  /**
81
105
  * Analyze colors — FIX: uses HashMap<u32, usize> for O(1) lookup (was O(n) linear scan)
82
106
  */
@@ -86,6 +110,19 @@ export function color_distance(r1: number, g1: number, b1: number, r2: number, g
86
110
 
87
111
  export function downscale(image_data: Uint8Array, width: number, height: number, target_width: number, target_height: number, config?: WasmDownscaleConfig | null): WasmDownscaleResult;
88
112
 
113
+ /**
114
+ * Downscale a prepared image. Pass an optional `config` to override per-target
115
+ * knobs (palette_size, k_centroid, chroma_recovery, skin_protection, …). The
116
+ * preprocess/segmentation settings always come from prepare time. When `config`
117
+ * is omitted, the prepare-time config is reused as-is.
118
+ */
119
+ export function downscale_prepared(prepared: WasmPreparedImage, target_width: number, target_height: number, config?: WasmDownscaleConfig | null): WasmDownscaleResult;
120
+
121
+ /**
122
+ * Downscale a prepared image with a caller-supplied palette.
123
+ */
124
+ export function downscale_prepared_with_palette(prepared: WasmPreparedImage, target_width: number, target_height: number, palette_data: Uint8Array, config?: WasmDownscaleConfig | null): WasmDownscaleResult;
125
+
89
126
  export function downscale_rgba(image_data: Uint8ClampedArray, width: number, height: number, target_width: number, target_height: number, config?: WasmDownscaleConfig | null): WasmDownscaleResult;
90
127
 
91
128
  export function downscale_simple(image_data: Uint8Array, width: number, height: number, target_width: number, target_height: number, num_colors: number): WasmDownscaleResult;
@@ -106,6 +143,16 @@ export function log(message: string): void;
106
143
 
107
144
  export function oklab_to_rgb(l: number, a: number, b: number): Uint8Array;
108
145
 
146
+ /**
147
+ * Prepare from a `Uint8Array` (RGBA).
148
+ */
149
+ export function prepare(image_data: Uint8Array, width: number, height: number, config?: WasmDownscaleConfig | null): WasmPreparedImage;
150
+
151
+ /**
152
+ * Prepare from a `Uint8ClampedArray` (canvas `getImageData`).
153
+ */
154
+ export function prepare_rgba(image_data: Uint8ClampedArray, width: number, height: number, config?: WasmDownscaleConfig | null): WasmPreparedImage;
155
+
109
156
  /**
110
157
  * Quantize to palette — FIX: compute Oklab once per pixel (was twice)
111
158
  */
@@ -114,3 +161,134 @@ export function quantize_to_palette(image_data: Uint8Array, width: number, heigh
114
161
  export function rgb_to_oklab(r: number, g: number, b: number): Float32Array;
115
162
 
116
163
  export function version(): string;
164
+
165
+ export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
166
+
167
+ export interface InitOutput {
168
+ readonly memory: WebAssembly.Memory;
169
+ readonly __wbg_coloranalysisresult_free: (a: number, b: number) => void;
170
+ readonly __wbg_colorentry_free: (a: number, b: number) => void;
171
+ readonly __wbg_get_wasmdownscaleconfig_chroma_recovery: (a: number) => number;
172
+ readonly __wbg_get_wasmdownscaleconfig_color_rarity: (a: number) => number;
173
+ readonly __wbg_get_wasmdownscaleconfig_detail_boost: (a: number) => number;
174
+ readonly __wbg_get_wasmdownscaleconfig_edge_weight: (a: number) => number;
175
+ readonly __wbg_get_wasmdownscaleconfig_hierarchy_min_size: (a: number) => number;
176
+ readonly __wbg_get_wasmdownscaleconfig_hierarchy_threshold: (a: number) => number;
177
+ readonly __wbg_get_wasmdownscaleconfig_k_centroid: (a: number) => number;
178
+ readonly __wbg_get_wasmdownscaleconfig_k_centroid_iterations: (a: number) => number;
179
+ readonly __wbg_get_wasmdownscaleconfig_kmeans_iterations: (a: number) => number;
180
+ readonly __wbg_get_wasmdownscaleconfig_max_color_preprocess: (a: number) => number;
181
+ readonly __wbg_get_wasmdownscaleconfig_max_resolution_mp: (a: number) => number;
182
+ readonly __wbg_get_wasmdownscaleconfig_neighbor_weight: (a: number) => number;
183
+ readonly __wbg_get_wasmdownscaleconfig_palette_size: (a: number) => number;
184
+ readonly __wbg_get_wasmdownscaleconfig_refinement_iterations: (a: number) => number;
185
+ readonly __wbg_get_wasmdownscaleconfig_region_weight: (a: number) => number;
186
+ readonly __wbg_get_wasmdownscaleconfig_reserve_colors: (a: number) => number;
187
+ readonly __wbg_get_wasmdownscaleconfig_skin_protection: (a: number) => number;
188
+ readonly __wbg_get_wasmdownscaleconfig_slic_compactness: (a: number) => number;
189
+ readonly __wbg_get_wasmdownscaleconfig_slic_superpixels: (a: number) => number;
190
+ readonly __wbg_get_wasmdownscaleconfig_two_pass_refinement: (a: number) => number;
191
+ readonly __wbg_set_wasmdownscaleconfig_chroma_recovery: (a: number, b: number) => void;
192
+ readonly __wbg_set_wasmdownscaleconfig_color_rarity: (a: number, b: number) => void;
193
+ readonly __wbg_set_wasmdownscaleconfig_detail_boost: (a: number, b: number) => void;
194
+ readonly __wbg_set_wasmdownscaleconfig_edge_weight: (a: number, b: number) => void;
195
+ readonly __wbg_set_wasmdownscaleconfig_hierarchy_min_size: (a: number, b: number) => void;
196
+ readonly __wbg_set_wasmdownscaleconfig_hierarchy_threshold: (a: number, b: number) => void;
197
+ readonly __wbg_set_wasmdownscaleconfig_k_centroid: (a: number, b: number) => void;
198
+ readonly __wbg_set_wasmdownscaleconfig_k_centroid_iterations: (a: number, b: number) => void;
199
+ readonly __wbg_set_wasmdownscaleconfig_kmeans_iterations: (a: number, b: number) => void;
200
+ readonly __wbg_set_wasmdownscaleconfig_max_color_preprocess: (a: number, b: number) => void;
201
+ readonly __wbg_set_wasmdownscaleconfig_max_resolution_mp: (a: number, b: number) => void;
202
+ readonly __wbg_set_wasmdownscaleconfig_neighbor_weight: (a: number, b: number) => void;
203
+ readonly __wbg_set_wasmdownscaleconfig_palette_size: (a: number, b: number) => void;
204
+ readonly __wbg_set_wasmdownscaleconfig_refinement_iterations: (a: number, b: number) => void;
205
+ readonly __wbg_set_wasmdownscaleconfig_region_weight: (a: number, b: number) => void;
206
+ readonly __wbg_set_wasmdownscaleconfig_reserve_colors: (a: number, b: number) => void;
207
+ readonly __wbg_set_wasmdownscaleconfig_skin_protection: (a: number, b: number) => void;
208
+ readonly __wbg_set_wasmdownscaleconfig_slic_compactness: (a: number, b: number) => void;
209
+ readonly __wbg_set_wasmdownscaleconfig_slic_superpixels: (a: number, b: number) => void;
210
+ readonly __wbg_set_wasmdownscaleconfig_two_pass_refinement: (a: number, b: number) => void;
211
+ readonly __wbg_wasmdownscaleconfig_free: (a: number, b: number) => void;
212
+ readonly __wbg_wasmdownscaleresult_free: (a: number, b: number) => void;
213
+ readonly __wbg_wasmpreparedimage_free: (a: number, b: number) => void;
214
+ readonly analyze_colors: (a: any, b: number, c: number, d: number) => [number, number, number];
215
+ readonly color_distance: (a: number, b: number, c: number, d: number, e: number, f: number) => number;
216
+ readonly coloranalysisresult_color_count: (a: number) => number;
217
+ readonly coloranalysisresult_get_color: (a: number, b: number) => number;
218
+ readonly coloranalysisresult_get_colors_flat: (a: number) => any;
219
+ readonly coloranalysisresult_success: (a: number) => number;
220
+ readonly coloranalysisresult_to_json: (a: number) => [number, number, number];
221
+ readonly coloranalysisresult_total_pixels: (a: number) => number;
222
+ readonly colorentry_b: (a: number) => number;
223
+ readonly colorentry_count: (a: number) => number;
224
+ readonly colorentry_g: (a: number) => number;
225
+ readonly colorentry_hex: (a: number) => [number, number];
226
+ readonly colorentry_percentage: (a: number) => number;
227
+ readonly colorentry_r: (a: number) => number;
228
+ readonly downscale: (a: any, b: number, c: number, d: number, e: number, f: number) => [number, number, number];
229
+ readonly downscale_prepared: (a: number, b: number, c: number, d: number) => [number, number, number];
230
+ readonly downscale_prepared_with_palette: (a: number, b: number, c: number, d: any, e: number) => [number, number, number];
231
+ readonly downscale_rgba: (a: any, b: number, c: number, d: number, e: number, f: number) => [number, number, number];
232
+ readonly downscale_simple: (a: any, b: number, c: number, d: number, e: number, f: number) => [number, number, number];
233
+ readonly downscale_with_palette: (a: any, b: number, c: number, d: number, e: number, f: any, g: number) => [number, number, number];
234
+ readonly extract_palette_from_image: (a: any, b: number, c: number, d: number, e: number, f: number, g: number) => [number, number, number];
235
+ readonly get_chroma: (a: number, b: number, c: number) => number;
236
+ readonly get_lightness: (a: number, b: number, c: number) => number;
237
+ readonly get_palette_strategies: () => any;
238
+ readonly init: () => void;
239
+ readonly log: (a: number, b: number) => void;
240
+ readonly oklab_to_rgb: (a: number, b: number, c: number) => any;
241
+ readonly prepare: (a: any, b: number, c: number, d: number) => [number, number, number];
242
+ readonly prepare_rgba: (a: any, b: number, c: number, d: number) => [number, number, number];
243
+ readonly quantize_to_palette: (a: any, b: number, c: number, d: any) => [number, number, number];
244
+ readonly rgb_to_oklab: (a: number, b: number, c: number) => any;
245
+ readonly version: () => [number, number];
246
+ readonly wasmdownscaleconfig_exact_colors: () => number;
247
+ readonly wasmdownscaleconfig_fast: () => number;
248
+ readonly wasmdownscaleconfig_new: () => number;
249
+ readonly wasmdownscaleconfig_palette_strategy: (a: number) => [number, number];
250
+ readonly wasmdownscaleconfig_quality: () => number;
251
+ readonly wasmdownscaleconfig_segmentation_method: (a: number) => [number, number];
252
+ readonly wasmdownscaleconfig_set_palette_strategy: (a: number, b: number, c: number) => void;
253
+ readonly wasmdownscaleconfig_set_segmentation_method: (a: number, b: number, c: number) => void;
254
+ readonly wasmdownscaleconfig_vibrant: () => number;
255
+ readonly wasmdownscaleresult_data: (a: number) => any;
256
+ readonly wasmdownscaleresult_height: (a: number) => number;
257
+ readonly wasmdownscaleresult_indices: (a: number) => any;
258
+ readonly wasmdownscaleresult_palette: (a: number) => any;
259
+ readonly wasmdownscaleresult_palette_size: (a: number) => number;
260
+ readonly wasmdownscaleresult_rgb_data: (a: number) => any;
261
+ readonly wasmdownscaleresult_width: (a: number) => number;
262
+ readonly wasmpreparedimage_height: (a: number) => number;
263
+ readonly wasmpreparedimage_width: (a: number) => number;
264
+ readonly __wbindgen_exn_store: (a: number) => void;
265
+ readonly __externref_table_alloc: () => number;
266
+ readonly __wbindgen_externrefs: WebAssembly.Table;
267
+ readonly __wbindgen_malloc: (a: number, b: number) => number;
268
+ readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
269
+ readonly __externref_table_dealloc: (a: number) => void;
270
+ readonly __wbindgen_free: (a: number, b: number, c: number) => void;
271
+ readonly __wbindgen_start: () => void;
272
+ }
273
+
274
+ export type SyncInitInput = BufferSource | WebAssembly.Module;
275
+
276
+ /**
277
+ * Instantiates the given `module`, which can either be bytes or
278
+ * a precompiled `WebAssembly.Module`.
279
+ *
280
+ * @param {{ module: SyncInitInput }} module - Passing `SyncInitInput` directly is deprecated.
281
+ *
282
+ * @returns {InitOutput}
283
+ */
284
+ export function initSync(module: { module: SyncInitInput } | SyncInitInput): InitOutput;
285
+
286
+ /**
287
+ * If `module_or_path` is {RequestInfo} or {URL}, makes a request and
288
+ * for everything else, calls `WebAssembly.instantiate` directly.
289
+ *
290
+ * @param {{ module_or_path: InitInput | Promise<InitInput> }} module_or_path - Passing `InitInput` directly is deprecated.
291
+ *
292
+ * @returns {Promise<InitOutput>}
293
+ */
294
+ export default function __wbg_init (module_or_path?: { module_or_path: InitInput | Promise<InitInput> } | InitInput | Promise<InitInput>): Promise<InitOutput>;