rapier-jxl 2.0.0 → 2.2.0

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.
Files changed (55) hide show
  1. package/AGENTS.md +10 -1
  2. package/ENCODER-COMPARISON.md +6 -6
  3. package/KERNELS.md +58 -0
  4. package/README.md +75 -18
  5. package/admit.mjs +5 -1
  6. package/ans.mjs +157 -0
  7. package/bits.mjs +5 -2
  8. package/build-jxl-kernels.mjs +29 -0
  9. package/coefficient-ans.mjs +26 -0
  10. package/coefficient-effort.mjs +62 -0
  11. package/effort-job.mjs +229 -0
  12. package/effort-level.mjs +10 -0
  13. package/effort.d.mts +4 -2
  14. package/effort.min.mjs +2 -2
  15. package/effort.mjs +7 -199
  16. package/frame.mjs +29 -1
  17. package/index.mjs +2 -2
  18. package/jfif.mjs +11 -0
  19. package/jpeg-ans.d.mts +3 -0
  20. package/jpeg-ans.min.mjs +2 -0
  21. package/jpeg-ans.mjs +9 -0
  22. package/jpeg-job.mjs +29 -0
  23. package/jpeg.d.mts +6 -2
  24. package/jpeg.min.mjs +2 -2
  25. package/jpeg.mjs +12 -36
  26. package/kernel-control.d.mts +3 -0
  27. package/kernel-hooks.mjs +3 -0
  28. package/kernels-bytes.mjs +4 -0
  29. package/kernels-probe.wat +1 -0
  30. package/kernels-scalar.wat +831 -0
  31. package/kernels-simd.wat +252 -0
  32. package/kernels.mjs +141 -0
  33. package/local.mjs +201 -0
  34. package/lossless-coding.mjs +30 -0
  35. package/lossless.mjs +88 -67
  36. package/modular.mjs +11 -7
  37. package/package.json +40 -6
  38. package/photo-ans.d.mts +3 -0
  39. package/photo-ans.min.mjs +2 -0
  40. package/photo-ans.mjs +9 -0
  41. package/photo-dct.mjs +83 -0
  42. package/photo-job.mjs +27 -0
  43. package/photo-quant.mjs +150 -0
  44. package/photo.d.mts +5 -1
  45. package/photo.min.mjs +2 -2
  46. package/photo.mjs +7 -101
  47. package/pool.mjs +136 -0
  48. package/rapier-jxl.min.mjs +2 -2
  49. package/rct-search.mjs +61 -0
  50. package/sizes.json +237 -56
  51. package/vardct.mjs +45 -8
  52. package/wasm.d.mts +4 -0
  53. package/wasm.min.mjs +2 -0
  54. package/wasm.mjs +6 -0
  55. package/weighted.mjs +22 -10
@@ -0,0 +1,831 @@
1
+ ;; SPDX-License-Identifier: MIT
2
+ ;; Own bounded integer kernels. Pointers and lengths are checked by kernels.mjs.
3
+ ;; Tiny arithmetic helpers are explicitly inlined: Node 22 does not inline WAT calls
4
+ ;; by default. i64 multiplication followed by arithmetic >>24 is floor, not truncation.
5
+ ;; SIMD averages add one to negative sums before >>1, matching JavaScript's /2 |0.
6
+ (module
7
+ (import "env" "memory" (memory 1 128))
8
+ (global $table (mut i32) (i32.const 0))
9
+ (global $out (mut i32) (i32.const 0))
10
+ (global $writing (mut i32) (i32.const 0))
11
+ (global $acc (mut i64) (i64.const 0))
12
+ (global $pending (mut i32) (i32.const 0))
13
+ ;; The residual tokens' hybrid-integer configuration (split, msb, lsb; splittoken is 1 << split), and the histogram
14
+ ;; layout: a bin per context of $stride entries, LZ77 length tokens at $lenbase. A raw histogram ($raw) holds a
15
+ ;; literal's own value in its own bin and the 33 length tokens in its last 33.
16
+ (global $split (mut i32) (i32.const 0))
17
+ (global $msb (mut i32) (i32.const 0))
18
+ (global $lsb (mut i32) (i32.const 0))
19
+ (global $splittoken (mut i32) (i32.const 1))
20
+ (global $stride (mut i32) (i32.const 257))
21
+ (global $lenbase (mut i32) (i32.const 224))
22
+ (global $raw (mut i32) (i32.const 0))
23
+ (func $residual
24
+ (export "residual")
25
+ (param $p i32)
26
+ (param $w i32)
27
+ (param $h i32)
28
+ (param $pred i32)
29
+ (param $offset i32)
30
+ (param $out i32)
31
+ (local $x i32)
32
+ (local $y i32)
33
+ (local $row i32)
34
+ (local $left i32)
35
+ (local $top i32)
36
+ (local $nw i32)
37
+ (local $g i32)
38
+ (local $v i32)
39
+ (local.set $row (i32.shl (local.get $w) (i32.const 2)))
40
+ (loop $ys
41
+ (local.set $x (i32.const 0))
42
+ (loop $xs
43
+ (local.set $v (i32.const 0))
44
+ (if
45
+ (local.get $pred)
46
+ (then
47
+ (local.set $left
48
+ (if
49
+ (result i32)
50
+ (local.get $x)
51
+ (then (i32.load (i32.sub (local.get $p) (i32.const 4))))
52
+ (else
53
+ (if
54
+ (result i32)
55
+ (local.get $y)
56
+ (then (i32.load (i32.sub (local.get $p) (local.get $row))))
57
+ (else (i32.const 0))))))
58
+ (local.set $top
59
+ (if
60
+ (result i32)
61
+ (local.get $y)
62
+ (then (i32.load (i32.sub (local.get $p) (local.get $row))))
63
+ (else (local.get $left))))
64
+ (local.set $nw
65
+ (if
66
+ (result i32)
67
+ (i32.and (i32.ne (local.get $x) (i32.const 0)) (i32.ne (local.get $y) (i32.const 0)))
68
+ (then (i32.load (i32.sub (i32.sub (local.get $p) (local.get $row)) (i32.const 4))))
69
+ (else (local.get $left))))
70
+ (local.set $g (i32.sub (i32.add (local.get $left) (local.get $top)) (local.get $nw)))
71
+ (if (i32.eq (local.get $pred) (i32.const 1)) (then (local.set $v (local.get $left))))
72
+ (if (i32.eq (local.get $pred) (i32.const 2)) (then (local.set $v (local.get $top))))
73
+ (if
74
+ (i32.eq (local.get $pred) (i32.const 3))
75
+ (then (local.set $v (i32.div_s (i32.add (local.get $left) (local.get $top)) (i32.const 2)))))
76
+ (if
77
+ (i32.eq (local.get $pred) (i32.const 4))
78
+ (then
79
+ (local.set $v
80
+ (select
81
+ (local.get $left)
82
+ (local.get $top)
83
+ (i32.lt_s
84
+ (i32.sub
85
+ (i32.xor
86
+ (i32.sub (local.get $g) (local.get $left))
87
+ (i32.shr_s (i32.sub (local.get $g) (local.get $left)) (i32.const 31)))
88
+ (i32.shr_s (i32.sub (local.get $g) (local.get $left)) (i32.const 31)))
89
+ (i32.sub
90
+ (i32.xor
91
+ (i32.sub (local.get $g) (local.get $top))
92
+ (i32.shr_s (i32.sub (local.get $g) (local.get $top)) (i32.const 31)))
93
+ (i32.shr_s (i32.sub (local.get $g) (local.get $top)) (i32.const 31))))))))
94
+ (if
95
+ (i32.eq (local.get $pred) (i32.const 5))
96
+ (then
97
+ (local.set $v
98
+ (select
99
+ (select (local.get $left) (local.get $top) (i32.lt_s (local.get $left) (local.get $top)))
100
+ (select
101
+ (select (local.get $left) (local.get $top) (i32.gt_s (local.get $left) (local.get $top)))
102
+ (local.get $g)
103
+ (i32.lt_s
104
+ (select (local.get $left) (local.get $top) (i32.gt_s (local.get $left) (local.get $top)))
105
+ (local.get $g)))
106
+ (i32.gt_s
107
+ (select (local.get $left) (local.get $top) (i32.lt_s (local.get $left) (local.get $top)))
108
+ (select
109
+ (select (local.get $left) (local.get $top) (i32.gt_s (local.get $left) (local.get $top)))
110
+ (local.get $g)
111
+ (i32.lt_s
112
+ (select
113
+ (local.get $left)
114
+ (local.get $top)
115
+ (i32.gt_s (local.get $left) (local.get $top)))
116
+ (local.get $g))))))))))
117
+ (i32.store
118
+ (local.get $out)
119
+ (i32.xor
120
+ (i32.shl
121
+ (i32.sub (i32.sub (i32.load (local.get $p)) (local.get $v)) (local.get $offset))
122
+ (i32.const 1))
123
+ (i32.shr_s
124
+ (i32.sub (i32.sub (i32.load (local.get $p)) (local.get $v)) (local.get $offset))
125
+ (i32.const 31))))
126
+ (local.set $out (i32.add (local.get $out) (i32.const 4)))
127
+ (local.set $p (i32.add (local.get $p) (i32.const 4)))
128
+ (local.set $x (i32.add (local.get $x) (i32.const 1)))
129
+ (br_if $xs (i32.lt_u (local.get $x) (local.get $w))))
130
+ (local.set $y (i32.add (local.get $y) (i32.const 1)))
131
+ (br_if $ys (i32.lt_u (local.get $y) (local.get $h)))))
132
+ (func $bits
133
+ (param $n i32)
134
+ (param $v i32)
135
+ (global.set $acc
136
+ (i64.or
137
+ (global.get $acc)
138
+ (i64.shl (i64.extend_i32_u (local.get $v)) (i64.extend_i32_u (global.get $pending)))))
139
+ (global.set $pending (i32.add (global.get $pending) (local.get $n)))
140
+ (block $done
141
+ (loop $bytes
142
+ (br_if $done (i32.lt_u (global.get $pending) (i32.const 8)))
143
+ (i32.store8 (global.get $out) (i32.wrap_i64 (global.get $acc)))
144
+ (global.set $out (i32.add (global.get $out) (i32.const 1)))
145
+ (global.set $acc (i64.shr_u (global.get $acc) (i64.const 8)))
146
+ (global.set $pending (i32.sub (global.get $pending) (i32.const 8)))
147
+ (br $bytes))))
148
+ (func $emit
149
+ (param $context i32)
150
+ (param $value i32)
151
+ (param $run i32)
152
+ (local $symbol i32)
153
+ (local $n i32)
154
+ (local $nbits i32)
155
+ (local $extra i32)
156
+ (local $below i32)
157
+ (local $at i32)
158
+ (if
159
+ (local.get $run)
160
+ (then
161
+ ;; An LZ77 length, split 4: a value below 16 is its own token, above it n + 12 with n raw bits.
162
+ (if
163
+ (i32.lt_u (local.get $value) (i32.const 16))
164
+ (then (local.set $symbol (i32.add (local.get $value) (global.get $lenbase))))
165
+ (else
166
+ (local.set $n (i32.sub (i32.const 31) (i32.clz (local.get $value))))
167
+ (local.set $symbol (i32.add (i32.add (local.get $n) (i32.const 12)) (global.get $lenbase)))
168
+ (local.set $nbits (local.get $n))
169
+ (local.set $extra
170
+ (i32.and (local.get $value) (i32.sub (i32.shl (i32.const 1) (local.get $n)) (i32.const 1)))))))
171
+ (else
172
+ (if
173
+ (global.get $raw)
174
+ (then
175
+ ;; The literal's own bin; a value past the histogram is not counted, as a write past an array's end.
176
+ (if (i32.ge_u (local.get $value) (global.get $stride)) (then (return)))
177
+ (local.set $symbol (local.get $value)))
178
+ (else
179
+ (if
180
+ (i32.lt_u (local.get $value) (global.get $splittoken))
181
+ (then (local.set $symbol (local.get $value)))
182
+ (else
183
+ (local.set $n (i32.sub (i32.const 31) (i32.clz (local.get $value))))
184
+ (if
185
+ (i32.eqz (i32.or (global.get $msb) (global.get $lsb)))
186
+ (then
187
+ ;; Every bit under the top one raw.
188
+ (local.set $symbol (i32.add (global.get $splittoken) (i32.sub (local.get $n) (global.get $split))))
189
+ (local.set $nbits (local.get $n))
190
+ (local.set $extra
191
+ (i32.and (local.get $value) (i32.sub (i32.shl (i32.const 1) (local.get $n)) (i32.const 1)))))
192
+ (else
193
+ (local.set $below (i32.sub (local.get $value) (i32.shl (i32.const 1) (local.get $n))))
194
+ (local.set $nbits (i32.sub (i32.sub (local.get $n) (global.get $msb)) (global.get $lsb)))
195
+ (local.set $symbol
196
+ (i32.add
197
+ (global.get $splittoken)
198
+ (i32.or
199
+ (i32.or
200
+ (i32.shl
201
+ (i32.sub (local.get $n) (global.get $split))
202
+ (i32.add (global.get $msb) (global.get $lsb)))
203
+ (i32.shl
204
+ (i32.shr_u (local.get $below) (i32.sub (local.get $n) (global.get $msb)))
205
+ (global.get $lsb)))
206
+ (i32.and
207
+ (local.get $below)
208
+ (i32.sub (i32.shl (i32.const 1) (global.get $lsb)) (i32.const 1))))))
209
+ (local.set $extra
210
+ (i32.and
211
+ (i32.shr_u (local.get $value) (global.get $lsb))
212
+ (i32.sub (i32.shl (i32.const 1) (local.get $nbits)) (i32.const 1))))))))))))
213
+ (if
214
+ (global.get $writing)
215
+ (then
216
+ (local.set $at
217
+ (i32.add
218
+ (global.get $table)
219
+ (i32.shl (i32.add (i32.mul (local.get $context) (global.get $stride)) (local.get $symbol)) (i32.const 3))))
220
+ (call $bits (i32.load (local.get $at)) (i32.load offset=4 (local.get $at)))
221
+ (if (local.get $nbits) (then (call $bits (local.get $nbits) (local.get $extra)))))
222
+ (else
223
+ (local.set $at
224
+ (i32.add
225
+ (global.get $table)
226
+ (i32.shl (i32.add (i32.mul (local.get $context) (global.get $stride)) (local.get $symbol)) (i32.const 2))))
227
+ (i32.store (local.get $at) (i32.add (i32.load (local.get $at)) (i32.const 1))))))
228
+ (func $context
229
+ (param $contexts i32)
230
+ (param $i i32)
231
+ (result i32)
232
+ (if
233
+ (result i32)
234
+ (local.get $contexts)
235
+ (then (i32.load (i32.add (local.get $contexts) (i32.shl (local.get $i) (i32.const 2)))))
236
+ (else (i32.const 0))))
237
+ (func $tokens
238
+ (export "tokens")
239
+ (param $values i32)
240
+ (param $contexts i32)
241
+ (param $n i32)
242
+ (param $table i32)
243
+ (param $out i32)
244
+ (param $writing i32)
245
+ (param $acc i32)
246
+ (param $pending i32)
247
+ (param $split i32)
248
+ (param $msb i32)
249
+ (param $lsb i32)
250
+ (param $rawlen i32)
251
+ (result i32)
252
+ (local $i i32)
253
+ (local $run i32)
254
+ (local $v i32)
255
+ (local $j i32)
256
+ (global.set $table (local.get $table))
257
+ (global.set $out (local.get $out))
258
+ (global.set $writing (local.get $writing))
259
+ (global.set $acc (i64.extend_i32_u (local.get $acc)))
260
+ (global.set $pending (local.get $pending))
261
+ (global.set $split (local.get $split))
262
+ (global.set $msb (local.get $msb))
263
+ (global.set $lsb (local.get $lsb))
264
+ (global.set $splittoken (i32.shl (i32.const 1) (local.get $split)))
265
+ (global.set $raw (i32.ne (local.get $rawlen) (i32.const 0)))
266
+ (global.set $stride (select (local.get $rawlen) (i32.const 257) (local.get $rawlen)))
267
+ (global.set $lenbase (select (i32.sub (local.get $rawlen) (i32.const 33)) (i32.const 224) (local.get $rawlen)))
268
+ (block $done
269
+ (loop $next
270
+ (br_if $done (i32.ge_u (local.get $i) (local.get $n)))
271
+ (local.set $v (i32.load (i32.add (local.get $values) (i32.shl (local.get $i) (i32.const 2)))))
272
+ (local.set $run (i32.const 1))
273
+ (if
274
+ (i32.eqz (local.get $v))
275
+ (then
276
+ (block $endrun
277
+ (loop $zeros
278
+ (br_if $endrun (i32.ge_u (i32.add (local.get $i) (local.get $run)) (local.get $n)))
279
+ (br_if $endrun
280
+ (i32.load
281
+ (i32.add
282
+ (local.get $values)
283
+ (i32.shl (i32.add (local.get $i) (local.get $run)) (i32.const 2)))))
284
+ (local.set $run (i32.add (local.get $run) (i32.const 1)))
285
+ (br $zeros)))))
286
+ (call $emit (call $context (local.get $contexts) (local.get $i)) (local.get $v) (i32.const 0))
287
+ (if
288
+ (i32.gt_u (local.get $run) (i32.const 7))
289
+ (then
290
+ (call $emit
291
+ (call $context (local.get $contexts) (i32.add (local.get $i) (i32.const 1)))
292
+ (i32.sub (local.get $run) (i32.const 8))
293
+ (i32.const 1)))
294
+ (else
295
+ (local.set $j (i32.const 1))
296
+ (block $shortdone
297
+ (loop $short
298
+ (br_if $shortdone (i32.ge_u (local.get $j) (local.get $run)))
299
+ (call $emit
300
+ (call $context (local.get $contexts) (i32.add (local.get $i) (local.get $j)))
301
+ (i32.const 0)
302
+ (i32.const 0))
303
+ (local.set $j (i32.add (local.get $j) (i32.const 1)))
304
+ (br $short)))))
305
+ (local.set $i (i32.add (local.get $i) (local.get $run)))
306
+ (br $next)))
307
+ (i32.store (i32.sub (local.get $out) (i32.const 8)) (i32.wrap_i64 (global.get $acc)))
308
+ (i32.store (i32.sub (local.get $out) (i32.const 4)) (global.get $pending))
309
+ (i32.sub (global.get $out) (local.get $out)))
310
+ (func $fill
311
+ (export "fill")
312
+ (param $src i32)
313
+ (param $n i32)
314
+ (param $channels i32)
315
+ (param $p0 i32)
316
+ (param $p1 i32)
317
+ (param $p2 i32)
318
+ (param $p3 i32)
319
+ (local $v i32)
320
+ (local $r i32)
321
+ (local $g i32)
322
+ (local $b i32)
323
+ (local $co i32)
324
+ (local $cg i32)
325
+ (local $tmp i32)
326
+ (local $i i32)
327
+ (loop $next
328
+ (local.set $v (i32.load (local.get $src)))
329
+ (local.set $r (i32.and (local.get $v) (i32.const 255)))
330
+ (if
331
+ (i32.ge_u (local.get $channels) (i32.const 3))
332
+ (then
333
+ (local.set $g (i32.and (i32.shr_u (local.get $v) (i32.const 8)) (i32.const 255)))
334
+ (local.set $b (i32.and (i32.shr_u (local.get $v) (i32.const 16)) (i32.const 255)))
335
+ (local.set $co (i32.sub (local.get $r) (local.get $b)))
336
+ (local.set $tmp (i32.add (local.get $b) (i32.shr_s (local.get $co) (i32.const 1))))
337
+ (local.set $cg (i32.sub (local.get $g) (local.get $tmp)))
338
+ (i32.store (local.get $p0) (i32.add (local.get $tmp) (i32.shr_s (local.get $cg) (i32.const 1))))
339
+ (i32.store (local.get $p1) (local.get $co))
340
+ (i32.store (local.get $p2) (local.get $cg))
341
+ (if
342
+ (i32.eq (local.get $channels) (i32.const 4))
343
+ (then (i32.store (local.get $p3) (i32.shr_u (local.get $v) (i32.const 24))))))
344
+ (else
345
+ (i32.store (local.get $p0) (local.get $r))
346
+ (if
347
+ (i32.eq (local.get $channels) (i32.const 2))
348
+ (then (i32.store (local.get $p1) (i32.shr_u (local.get $v) (i32.const 24)))))))
349
+ (local.set $p0 (i32.add (local.get $p0) (i32.const 4)))
350
+ (local.set $p1 (i32.add (local.get $p1) (i32.const 4)))
351
+ (local.set $p2 (i32.add (local.get $p2) (i32.const 4)))
352
+ (local.set $p3 (i32.add (local.get $p3) (i32.const 4)))
353
+ (local.set $src (i32.add (local.get $src) (i32.const 4)))
354
+ (local.set $i (i32.add (local.get $i) (i32.const 1)))
355
+ (br_if $next (i32.lt_u (local.get $i) (local.get $n)))))
356
+ (func $weighted
357
+ (export "weighted")
358
+ (param $p i32)
359
+ (param $width i32)
360
+ (param $height i32)
361
+ (param $offset i32)
362
+ (param $out i32)
363
+ (param $properties i32)
364
+ (param $contexts i32)
365
+ (param $map i32)
366
+ (param $bucket i32)
367
+ (param $div i32)
368
+ (param $weights i32)
369
+ (param $state i32)
370
+ (local $wshift i32)
371
+ (local $wsum i32)
372
+ (local $stride i32)
373
+ (local $row i32)
374
+ (local $x i32)
375
+ (local $y i32)
376
+ (local $cur i32)
377
+ (local $prev i32)
378
+ (local $n i32)
379
+ (local $ne i32)
380
+ (local $nw i32)
381
+ (local $left i32)
382
+ (local $top i32)
383
+ (local $right i32)
384
+ (local $N i32)
385
+ (local $W i32)
386
+ (local $NE i32)
387
+ (local $teW i32)
388
+ (local $teN i32)
389
+ (local $teNW i32)
390
+ (local $teNE i32)
391
+ (local $most i32)
392
+ (local $sumWN i32)
393
+ (local $p0 i32)
394
+ (local $p1 i32)
395
+ (local $p2 i32)
396
+ (local $p3 i32)
397
+ (local $w0 i32)
398
+ (local $w1 i32)
399
+ (local $w2 i32)
400
+ (local $w3 i32)
401
+ (local $shift i32)
402
+ (local $sum i32)
403
+ (local $pred i32)
404
+ (local $value i32)
405
+ (local $v i32)
406
+ (local $e0 i32)
407
+ (local $e1 i32)
408
+ (local $e2 i32)
409
+ (local $e3 i32)
410
+ (local $errors0 i32)
411
+ (local $errors1 i32)
412
+ (local $errors2 i32)
413
+ (local $errors3 i32)
414
+ (local $error i32)
415
+ (local $at i32)
416
+ (local.set $stride (i32.shl (i32.add (local.get $width) (i32.const 2)) (i32.const 2)))
417
+ (local.set $row (i32.shl (local.get $width) (i32.const 2)))
418
+ (local.set $errors0 (local.get $state))
419
+ (local.set $errors1 (i32.add (local.get $state) (i32.mul (local.get $stride) (i32.const 2))))
420
+ (local.set $errors2 (i32.add (local.get $state) (i32.mul (local.get $stride) (i32.const 4))))
421
+ (local.set $errors3 (i32.add (local.get $state) (i32.mul (local.get $stride) (i32.const 6))))
422
+ (local.set $error (i32.add (local.get $state) (i32.mul (local.get $stride) (i32.const 8))))
423
+ (loop $ys
424
+ (local.set $cur (select (i32.const 0) (local.get $stride) (i32.and (local.get $y) (i32.const 1))))
425
+ (local.set $prev (i32.sub (local.get $stride) (local.get $cur)))
426
+ (local.set $x (i32.const 0))
427
+ (loop $xs
428
+ (local.set $left
429
+ (if
430
+ (result i32)
431
+ (local.get $x)
432
+ (then (i32.load (i32.sub (local.get $p) (i32.const 4))))
433
+ (else
434
+ (if
435
+ (result i32)
436
+ (local.get $y)
437
+ (then (i32.load (i32.sub (local.get $p) (local.get $row))))
438
+ (else (i32.const 0))))))
439
+ (local.set $top
440
+ (if
441
+ (result i32)
442
+ (local.get $y)
443
+ (then (i32.load (i32.sub (local.get $p) (local.get $row))))
444
+ (else (local.get $left))))
445
+ (local.set $right
446
+ (if
447
+ (result i32)
448
+ (i32.and
449
+ (i32.lt_u (i32.add (local.get $x) (i32.const 1)) (local.get $width))
450
+ (i32.ne (local.get $y) (i32.const 0)))
451
+ (then (i32.load (i32.add (i32.sub (local.get $p) (local.get $row)) (i32.const 4))))
452
+ (else (local.get $top))))
453
+ (local.set $n (i32.add (local.get $prev) (i32.shl (local.get $x) (i32.const 2))))
454
+ (local.set $nw (select (i32.sub (local.get $n) (i32.const 4)) (local.get $n) (local.get $x)))
455
+ (local.set $ne
456
+ (select
457
+ (i32.add (local.get $n) (i32.const 4))
458
+ (local.get $n)
459
+ (i32.lt_u (i32.add (local.get $x) (i32.const 1)) (local.get $width))))
460
+ (local.set $wsum
461
+ (i32.add
462
+ (i32.add
463
+ (i32.load (i32.add (local.get $errors0) (local.get $n)))
464
+ (i32.load (i32.add (local.get $errors0) (local.get $ne))))
465
+ (i32.load (i32.add (local.get $errors0) (local.get $nw)))))
466
+ (if
467
+ (i32.lt_u (local.get $wsum) (i32.const 2048))
468
+ (then
469
+ (local.set $w0
470
+ (i32.load
471
+ (i32.add
472
+ (local.get $weights)
473
+ (i32.shl (i32.add (local.get $wsum) (i32.const 2048)) (i32.const 2))))))
474
+ (else
475
+ (local.set $wshift
476
+ (select
477
+ (i32.const 0)
478
+ (i32.sub (i32.const 26) (i32.clz (i32.add (local.get $wsum) (i32.const 1))))
479
+ (i32.gt_s
480
+ (i32.const 0)
481
+ (i32.sub (i32.const 26) (i32.clz (i32.add (local.get $wsum) (i32.const 1)))))))
482
+ (local.set $w0
483
+ (i32.add
484
+ (i32.const 4)
485
+ (i32.shr_s
486
+ (i32.mul
487
+ (i32.const 13)
488
+ (i32.load
489
+ (i32.add
490
+ (local.get $div)
491
+ (i32.shl (i32.shr_s (local.get $wsum) (local.get $wshift)) (i32.const 2)))))
492
+ (local.get $wshift))))))
493
+ (local.set $wsum
494
+ (i32.add
495
+ (i32.add
496
+ (i32.load (i32.add (local.get $errors1) (local.get $n)))
497
+ (i32.load (i32.add (local.get $errors1) (local.get $ne))))
498
+ (i32.load (i32.add (local.get $errors1) (local.get $nw)))))
499
+ (if
500
+ (i32.lt_u (local.get $wsum) (i32.const 2048))
501
+ (then
502
+ (local.set $w1
503
+ (i32.load
504
+ (i32.add (local.get $weights) (i32.shl (i32.add (local.get $wsum) (i32.const 0)) (i32.const 2))))))
505
+ (else
506
+ (local.set $wshift
507
+ (select
508
+ (i32.const 0)
509
+ (i32.sub (i32.const 26) (i32.clz (i32.add (local.get $wsum) (i32.const 1))))
510
+ (i32.gt_s
511
+ (i32.const 0)
512
+ (i32.sub (i32.const 26) (i32.clz (i32.add (local.get $wsum) (i32.const 1)))))))
513
+ (local.set $w1
514
+ (i32.add
515
+ (i32.const 4)
516
+ (i32.shr_s
517
+ (i32.mul
518
+ (i32.const 12)
519
+ (i32.load
520
+ (i32.add
521
+ (local.get $div)
522
+ (i32.shl (i32.shr_s (local.get $wsum) (local.get $wshift)) (i32.const 2)))))
523
+ (local.get $wshift))))))
524
+ (local.set $wsum
525
+ (i32.add
526
+ (i32.add
527
+ (i32.load (i32.add (local.get $errors2) (local.get $n)))
528
+ (i32.load (i32.add (local.get $errors2) (local.get $ne))))
529
+ (i32.load (i32.add (local.get $errors2) (local.get $nw)))))
530
+ (if
531
+ (i32.lt_u (local.get $wsum) (i32.const 2048))
532
+ (then
533
+ (local.set $w2
534
+ (i32.load
535
+ (i32.add (local.get $weights) (i32.shl (i32.add (local.get $wsum) (i32.const 0)) (i32.const 2))))))
536
+ (else
537
+ (local.set $wshift
538
+ (select
539
+ (i32.const 0)
540
+ (i32.sub (i32.const 26) (i32.clz (i32.add (local.get $wsum) (i32.const 1))))
541
+ (i32.gt_s
542
+ (i32.const 0)
543
+ (i32.sub (i32.const 26) (i32.clz (i32.add (local.get $wsum) (i32.const 1)))))))
544
+ (local.set $w2
545
+ (i32.add
546
+ (i32.const 4)
547
+ (i32.shr_s
548
+ (i32.mul
549
+ (i32.const 12)
550
+ (i32.load
551
+ (i32.add
552
+ (local.get $div)
553
+ (i32.shl (i32.shr_s (local.get $wsum) (local.get $wshift)) (i32.const 2)))))
554
+ (local.get $wshift))))))
555
+ (local.set $wsum
556
+ (i32.add
557
+ (i32.add
558
+ (i32.load (i32.add (local.get $errors3) (local.get $n)))
559
+ (i32.load (i32.add (local.get $errors3) (local.get $ne))))
560
+ (i32.load (i32.add (local.get $errors3) (local.get $nw)))))
561
+ (if
562
+ (i32.lt_u (local.get $wsum) (i32.const 2048))
563
+ (then
564
+ (local.set $w3
565
+ (i32.load
566
+ (i32.add (local.get $weights) (i32.shl (i32.add (local.get $wsum) (i32.const 0)) (i32.const 2))))))
567
+ (else
568
+ (local.set $wshift
569
+ (select
570
+ (i32.const 0)
571
+ (i32.sub (i32.const 26) (i32.clz (i32.add (local.get $wsum) (i32.const 1))))
572
+ (i32.gt_s
573
+ (i32.const 0)
574
+ (i32.sub (i32.const 26) (i32.clz (i32.add (local.get $wsum) (i32.const 1)))))))
575
+ (local.set $w3
576
+ (i32.add
577
+ (i32.const 4)
578
+ (i32.shr_s
579
+ (i32.mul
580
+ (i32.const 12)
581
+ (i32.load
582
+ (i32.add
583
+ (local.get $div)
584
+ (i32.shl (i32.shr_s (local.get $wsum) (local.get $wshift)) (i32.const 2)))))
585
+ (local.get $wshift))))))
586
+ (local.set $N (i32.shl (local.get $top) (i32.const 3)))
587
+ (local.set $W (i32.shl (local.get $left) (i32.const 3)))
588
+ (local.set $NE (i32.shl (local.get $right) (i32.const 3)))
589
+ (local.set $teW
590
+ (if
591
+ (result i32)
592
+ (local.get $x)
593
+ (then
594
+ (i32.load
595
+ (i32.sub
596
+ (i32.add (i32.add (local.get $error) (local.get $cur)) (i32.shl (local.get $x) (i32.const 2)))
597
+ (i32.const 4))))
598
+ (else (i32.const 0))))
599
+ (local.set $teN (i32.load (i32.add (local.get $error) (local.get $n))))
600
+ (local.set $teNW (i32.load (i32.add (local.get $error) (local.get $nw))))
601
+ (local.set $teNE (i32.load (i32.add (local.get $error) (local.get $ne))))
602
+ (local.set $most (local.get $teW))
603
+ (if
604
+ (i32.gt_s
605
+ (i32.sub
606
+ (i32.xor (local.get $teN) (i32.shr_s (local.get $teN) (i32.const 31)))
607
+ (i32.shr_s (local.get $teN) (i32.const 31)))
608
+ (i32.sub
609
+ (i32.xor (local.get $most) (i32.shr_s (local.get $most) (i32.const 31)))
610
+ (i32.shr_s (local.get $most) (i32.const 31))))
611
+ (then (local.set $most (local.get $teN))))
612
+ (if
613
+ (i32.gt_s
614
+ (i32.sub
615
+ (i32.xor (local.get $teNW) (i32.shr_s (local.get $teNW) (i32.const 31)))
616
+ (i32.shr_s (local.get $teNW) (i32.const 31)))
617
+ (i32.sub
618
+ (i32.xor (local.get $most) (i32.shr_s (local.get $most) (i32.const 31)))
619
+ (i32.shr_s (local.get $most) (i32.const 31))))
620
+ (then (local.set $most (local.get $teNW))))
621
+ (if
622
+ (i32.gt_s
623
+ (i32.sub
624
+ (i32.xor (local.get $teNE) (i32.shr_s (local.get $teNE) (i32.const 31)))
625
+ (i32.shr_s (local.get $teNE) (i32.const 31)))
626
+ (i32.sub
627
+ (i32.xor (local.get $most) (i32.shr_s (local.get $most) (i32.const 31)))
628
+ (i32.shr_s (local.get $most) (i32.const 31))))
629
+ (then (local.set $most (local.get $teNE))))
630
+ (i32.store (local.get $properties) (local.get $most))
631
+ (local.set $at
632
+ (i32.add
633
+ (local.get $bucket)
634
+ (i32.shl
635
+ (i32.add
636
+ (select
637
+ (i32.const 501)
638
+ (select (i32.const -501) (local.get $most) (i32.gt_s (i32.const -501) (local.get $most)))
639
+ (i32.lt_s
640
+ (i32.const 501)
641
+ (select (i32.const -501) (local.get $most) (i32.gt_s (i32.const -501) (local.get $most)))))
642
+ (i32.const 501))
643
+ (i32.const 2))))
644
+ (i32.store
645
+ (local.get $contexts)
646
+ (i32.load (i32.add (local.get $map) (i32.shl (i32.load (local.get $at)) (i32.const 2)))))
647
+ (local.set $sumWN (i32.add (local.get $teW) (local.get $teN)))
648
+ (local.set $p0 (i32.sub (i32.add (local.get $W) (local.get $NE)) (local.get $N)))
649
+ (local.set $p1
650
+ (i32.sub
651
+ (local.get $N)
652
+ (i32.shr_s (i32.mul (i32.add (local.get $sumWN) (local.get $teNE)) (i32.const 16)) (i32.const 5))))
653
+ (local.set $p2
654
+ (i32.sub
655
+ (local.get $W)
656
+ (i32.shr_s (i32.mul (i32.add (local.get $sumWN) (local.get $teNW)) (i32.const 10)) (i32.const 5))))
657
+ (local.set $p3
658
+ (i32.sub
659
+ (local.get $N)
660
+ (i32.shr_s
661
+ (i32.mul (i32.add (i32.add (local.get $teNW) (local.get $teN)) (local.get $teNE)) (i32.const 7))
662
+ (i32.const 5))))
663
+ (local.set $shift
664
+ (i32.sub
665
+ (i32.const 27)
666
+ (i32.clz
667
+ (i32.add (i32.add (local.get $w0) (local.get $w1)) (i32.add (local.get $w2) (local.get $w3))))))
668
+ (local.set $w0 (i32.shr_s (local.get $w0) (local.get $shift)))
669
+ (local.set $w1 (i32.shr_s (local.get $w1) (local.get $shift)))
670
+ (local.set $w2 (i32.shr_s (local.get $w2) (local.get $shift)))
671
+ (local.set $w3 (i32.shr_s (local.get $w3) (local.get $shift)))
672
+ (local.set $sum
673
+ (i32.add (i32.add (local.get $w0) (local.get $w1)) (i32.add (local.get $w2) (local.get $w3))))
674
+ (local.set $pred
675
+ (i32.wrap_i64
676
+ (i64.shr_s
677
+ (i64.mul
678
+ (i64.add
679
+ (i64.extend_i32_s (i32.sub (i32.shr_s (local.get $sum) (i32.const 1)) (i32.const 1)))
680
+ (i64.add
681
+ (i64.add
682
+ (i64.mul (i64.extend_i32_s (local.get $p0)) (i64.extend_i32_s (local.get $w0)))
683
+ (i64.mul (i64.extend_i32_s (local.get $p1)) (i64.extend_i32_s (local.get $w1))))
684
+ (i64.add
685
+ (i64.mul (i64.extend_i32_s (local.get $p2)) (i64.extend_i32_s (local.get $w2)))
686
+ (i64.mul (i64.extend_i32_s (local.get $p3)) (i64.extend_i32_s (local.get $w3))))))
687
+ (i64.extend_i32_s
688
+ (i32.load
689
+ (i32.add (local.get $div) (i32.shl (i32.sub (local.get $sum) (i32.const 1)) (i32.const 2))))))
690
+ (i64.const 24))))
691
+ (if
692
+ (i32.le_s
693
+ (i32.or (i32.xor (local.get $teN) (local.get $teW)) (i32.xor (local.get $teN) (local.get $teNW)))
694
+ (i32.const 0))
695
+ (then
696
+ (local.set $pred
697
+ (select
698
+ (select
699
+ (local.get $W)
700
+ (select (local.get $NE) (local.get $N) (i32.lt_s (local.get $NE) (local.get $N)))
701
+ (i32.lt_s
702
+ (local.get $W)
703
+ (select (local.get $NE) (local.get $N) (i32.lt_s (local.get $NE) (local.get $N)))))
704
+ (select
705
+ (local.get $pred)
706
+ (select
707
+ (local.get $W)
708
+ (select (local.get $NE) (local.get $N) (i32.gt_s (local.get $NE) (local.get $N)))
709
+ (i32.gt_s
710
+ (local.get $W)
711
+ (select (local.get $NE) (local.get $N) (i32.gt_s (local.get $NE) (local.get $N)))))
712
+ (i32.lt_s
713
+ (local.get $pred)
714
+ (select
715
+ (local.get $W)
716
+ (select (local.get $NE) (local.get $N) (i32.gt_s (local.get $NE) (local.get $N)))
717
+ (i32.gt_s
718
+ (local.get $W)
719
+ (select (local.get $NE) (local.get $N) (i32.gt_s (local.get $NE) (local.get $N)))))))
720
+ (i32.gt_s
721
+ (select
722
+ (local.get $W)
723
+ (select (local.get $NE) (local.get $N) (i32.lt_s (local.get $NE) (local.get $N)))
724
+ (i32.lt_s
725
+ (local.get $W)
726
+ (select (local.get $NE) (local.get $N) (i32.lt_s (local.get $NE) (local.get $N)))))
727
+ (select
728
+ (local.get $pred)
729
+ (select
730
+ (local.get $W)
731
+ (select (local.get $NE) (local.get $N) (i32.gt_s (local.get $NE) (local.get $N)))
732
+ (i32.gt_s
733
+ (local.get $W)
734
+ (select (local.get $NE) (local.get $N) (i32.gt_s (local.get $NE) (local.get $N)))))
735
+ (i32.lt_s
736
+ (local.get $pred)
737
+ (select
738
+ (local.get $W)
739
+ (select (local.get $NE) (local.get $N) (i32.gt_s (local.get $NE) (local.get $N)))
740
+ (i32.gt_s
741
+ (local.get $W)
742
+ (select (local.get $NE) (local.get $N) (i32.gt_s (local.get $NE) (local.get $N))))))))))))
743
+ (local.set $value (i32.load (local.get $p)))
744
+ (i32.store
745
+ (local.get $out)
746
+ (i32.xor
747
+ (i32.shl
748
+ (i32.sub
749
+ (i32.sub (local.get $value) (i32.shr_s (i32.add (local.get $pred) (i32.const 3)) (i32.const 3)))
750
+ (local.get $offset))
751
+ (i32.const 1))
752
+ (i32.shr_s
753
+ (i32.sub
754
+ (i32.sub (local.get $value) (i32.shr_s (i32.add (local.get $pred) (i32.const 3)) (i32.const 3)))
755
+ (local.get $offset))
756
+ (i32.const 31))))
757
+ (local.set $v (i32.shl (local.get $value) (i32.const 3)))
758
+ (local.set $at (i32.add (local.get $cur) (i32.shl (local.get $x) (i32.const 2))))
759
+ (i32.store (i32.add (local.get $error) (local.get $at)) (i32.sub (local.get $pred) (local.get $v)))
760
+ (local.set $e0
761
+ (i32.shr_s
762
+ (i32.add
763
+ (i32.sub
764
+ (i32.xor
765
+ (i32.sub (local.get $p0) (local.get $v))
766
+ (i32.shr_s (i32.sub (local.get $p0) (local.get $v)) (i32.const 31)))
767
+ (i32.shr_s (i32.sub (local.get $p0) (local.get $v)) (i32.const 31)))
768
+ (i32.const 3))
769
+ (i32.const 3)))
770
+ (i32.store (i32.add (local.get $errors0) (local.get $at)) (local.get $e0))
771
+ (i32.store
772
+ (i32.add (i32.add (local.get $errors0) (local.get $n)) (i32.const 4))
773
+ (i32.add
774
+ (i32.load (i32.add (i32.add (local.get $errors0) (local.get $n)) (i32.const 4)))
775
+ (local.get $e0)))
776
+ (local.set $e1
777
+ (i32.shr_s
778
+ (i32.add
779
+ (i32.sub
780
+ (i32.xor
781
+ (i32.sub (local.get $p1) (local.get $v))
782
+ (i32.shr_s (i32.sub (local.get $p1) (local.get $v)) (i32.const 31)))
783
+ (i32.shr_s (i32.sub (local.get $p1) (local.get $v)) (i32.const 31)))
784
+ (i32.const 3))
785
+ (i32.const 3)))
786
+ (i32.store (i32.add (local.get $errors1) (local.get $at)) (local.get $e1))
787
+ (i32.store
788
+ (i32.add (i32.add (local.get $errors1) (local.get $n)) (i32.const 4))
789
+ (i32.add
790
+ (i32.load (i32.add (i32.add (local.get $errors1) (local.get $n)) (i32.const 4)))
791
+ (local.get $e1)))
792
+ (local.set $e2
793
+ (i32.shr_s
794
+ (i32.add
795
+ (i32.sub
796
+ (i32.xor
797
+ (i32.sub (local.get $p2) (local.get $v))
798
+ (i32.shr_s (i32.sub (local.get $p2) (local.get $v)) (i32.const 31)))
799
+ (i32.shr_s (i32.sub (local.get $p2) (local.get $v)) (i32.const 31)))
800
+ (i32.const 3))
801
+ (i32.const 3)))
802
+ (i32.store (i32.add (local.get $errors2) (local.get $at)) (local.get $e2))
803
+ (i32.store
804
+ (i32.add (i32.add (local.get $errors2) (local.get $n)) (i32.const 4))
805
+ (i32.add
806
+ (i32.load (i32.add (i32.add (local.get $errors2) (local.get $n)) (i32.const 4)))
807
+ (local.get $e2)))
808
+ (local.set $e3
809
+ (i32.shr_s
810
+ (i32.add
811
+ (i32.sub
812
+ (i32.xor
813
+ (i32.sub (local.get $p3) (local.get $v))
814
+ (i32.shr_s (i32.sub (local.get $p3) (local.get $v)) (i32.const 31)))
815
+ (i32.shr_s (i32.sub (local.get $p3) (local.get $v)) (i32.const 31)))
816
+ (i32.const 3))
817
+ (i32.const 3)))
818
+ (i32.store (i32.add (local.get $errors3) (local.get $at)) (local.get $e3))
819
+ (i32.store
820
+ (i32.add (i32.add (local.get $errors3) (local.get $n)) (i32.const 4))
821
+ (i32.add
822
+ (i32.load (i32.add (i32.add (local.get $errors3) (local.get $n)) (i32.const 4)))
823
+ (local.get $e3)))
824
+ (local.set $p (i32.add (local.get $p) (i32.const 4)))
825
+ (local.set $out (i32.add (local.get $out) (i32.const 4)))
826
+ (local.set $properties (i32.add (local.get $properties) (i32.const 4)))
827
+ (local.set $contexts (i32.add (local.get $contexts) (i32.const 4)))
828
+ (local.set $x (i32.add (local.get $x) (i32.const 1)))
829
+ (br_if $xs (i32.lt_u (local.get $x) (local.get $width))))
830
+ (local.set $y (i32.add (local.get $y) (i32.const 1)))
831
+ (br_if $ys (i32.lt_u (local.get $y) (local.get $height))))))