rapier-jxl 2.2.0 → 2.2.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/AGENTS.md +23 -28
- package/README.md +63 -158
- package/{effort.min.mjs → dist/effort.min.mjs} +1 -1
- package/{jpeg-ans.min.mjs → dist/jpeg-ans.min.mjs} +1 -1
- package/{jpeg.min.mjs → dist/jpeg.min.mjs} +1 -1
- package/{photo-ans.min.mjs → dist/photo-ans.min.mjs} +1 -1
- package/{photo.min.mjs → dist/photo.min.mjs} +1 -1
- package/{rapier-jxl.min.mjs → dist/rapier-jxl.min.mjs} +1 -1
- package/{sizes.json → dist/sizes.json} +24 -24
- package/{wasm.min.mjs → dist/wasm.min.mjs} +1 -1
- package/{build-jxl-kernels.mjs → kernels/build.mjs} +6 -4
- package/package.json +32 -39
- package/ENCODER-COMPARISON.md +0 -185
- package/KERNELS.md +0 -58
- package/public/encoder-sizes.json +0 -355
- package/public/encoders.json +0 -139
- package/public/examples/browser.html +0 -39
- package/public/examples/worker.mjs +0 -42
- package/public/measure-encoders.mjs +0 -60
- /package/{kernels-probe.wat → kernels/kernels-probe.wat} +0 -0
- /package/{kernels-scalar.wat → kernels/kernels-scalar.wat} +0 -0
- /package/{kernels-simd.wat → kernels/kernels-simd.wat} +0 -0
- /package/{admit.mjs → src/admit.mjs} +0 -0
- /package/{ans.mjs → src/ans.mjs} +0 -0
- /package/{bits.mjs → src/bits.mjs} +0 -0
- /package/{coefficient-ans.mjs → src/coefficient-ans.mjs} +0 -0
- /package/{coefficient-effort.mjs → src/coefficient-effort.mjs} +0 -0
- /package/{effort-job.mjs → src/effort-job.mjs} +0 -0
- /package/{effort-level.mjs → src/effort-level.mjs} +0 -0
- /package/{effort.d.mts → src/effort.d.mts} +0 -0
- /package/{effort.mjs → src/effort.mjs} +0 -0
- /package/{entropy.mjs → src/entropy.mjs} +0 -0
- /package/{frame.mjs → src/frame.mjs} +0 -0
- /package/{index.d.mts → src/index.d.mts} +0 -0
- /package/{index.mjs → src/index.mjs} +0 -0
- /package/{jfif.mjs → src/jfif.mjs} +0 -0
- /package/{jpeg-ans.d.mts → src/jpeg-ans.d.mts} +0 -0
- /package/{jpeg-ans.mjs → src/jpeg-ans.mjs} +0 -0
- /package/{jpeg-job.mjs → src/jpeg-job.mjs} +0 -0
- /package/{jpeg.d.mts → src/jpeg.d.mts} +0 -0
- /package/{jpeg.mjs → src/jpeg.mjs} +0 -0
- /package/{kernel-control.d.mts → src/kernel-control.d.mts} +0 -0
- /package/{kernel-hooks.mjs → src/kernel-hooks.mjs} +0 -0
- /package/{kernels-bytes.mjs → src/kernels-bytes.mjs} +0 -0
- /package/{kernels.mjs → src/kernels.mjs} +0 -0
- /package/{local.mjs → src/local.mjs} +0 -0
- /package/{lossless-coding.mjs → src/lossless-coding.mjs} +0 -0
- /package/{lossless.mjs → src/lossless.mjs} +0 -0
- /package/{lossy.mjs → src/lossy.mjs} +0 -0
- /package/{modular.mjs → src/modular.mjs} +0 -0
- /package/{photo-ans.d.mts → src/photo-ans.d.mts} +0 -0
- /package/{photo-ans.mjs → src/photo-ans.mjs} +0 -0
- /package/{photo-dct.mjs → src/photo-dct.mjs} +0 -0
- /package/{photo-job.mjs → src/photo-job.mjs} +0 -0
- /package/{photo-quant.mjs → src/photo-quant.mjs} +0 -0
- /package/{photo.d.mts → src/photo.d.mts} +0 -0
- /package/{photo.mjs → src/photo.mjs} +0 -0
- /package/{pool.mjs → src/pool.mjs} +0 -0
- /package/{prefix.mjs → src/prefix.mjs} +0 -0
- /package/{rct-search.mjs → src/rct-search.mjs} +0 -0
- /package/{squeeze.mjs → src/squeeze.mjs} +0 -0
- /package/{vardct.mjs → src/vardct.mjs} +0 -0
- /package/{wasm.d.mts → src/wasm.d.mts} +0 -0
- /package/{wasm.mjs → src/wasm.mjs} +0 -0
- /package/{weighted.mjs → src/weighted.mjs} +0 -0
- /package/{writer.mjs → src/writer.mjs} +0 -0
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
/*! Rapier JXL 2.2.
|
|
1
|
+
/*! Rapier JXL 2.2.1 | MIT License Copyright (c) 2026 rapier.website Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
|
2
2
|
function*t(t,n,A){let e,r;for(;!(e=t.next(r)).done;)r=yield at(e.value,t=>(n+t)/A);return e.value}function n(t){return t>=0?2*t:2*-t-1}function A(t){return 31-Math.clz32(t)}function e(t){return t<=1?0:32-Math.clz32(t-1)}function r(t){if(t>ct.bytes)throw ut("JXL_SIZE","The encoded picture exceeds 16 MiB.")}function o(t){try{return t()}catch(t){if(t instanceof RangeError&&!t.code)throw ut("JXL_MEMORY","Not enough memory for this picture.");throw t}}function s(t,n){t.t([[9,1],[13,1],[18,1],[30,1]],n)}function i(t,n,A,e,r,{xyb:o=!1,orientation:i=1,colorSpace:c}={}){t.write(16,2815),t.write(1,0),s(t,A),t.write(3,0),s(t,n),t.write(1,0);const l=1!==i;t.write(1,l?1:0),l&&t.write(6,i-1),t.write(4,8),r?t.write(3,5):t.write(2,0),t.write(1,o?1:0),3===e&&"display-p3"===c?t.write(21,903568):3===e?t.write(1,1):t.write(15,14100),l&&t.write(1,1),t.write(2,0),t.write(1,1),t.A()}function c(t,{alpha:n,shift:A=1}){t.write(9,8),n&&t.write(2,0),t.write(2,A),function(t,n){t.write(n?7:5,0),t.write(11,1)}(t,n)}function l(t,n,A=256){const e=Math.ceil(t/A),r=Math.ceil(n/A);return{o:e,i:r,I:Math.ceil(t/(8*A)),B:Math.ceil(n/(8*A)),u:1===e&&1===r}}function f(t,n,A,e){const r=e%t.o*Et,o=(e/t.o|0)*Et;return[r,o,Math.min(Et,n-r),Math.min(Et,A-o)]}function*a(t,n,A,e){if(t.pooled){const n=yield t;return n?(n.results.forEach((t,n)=>e(n,t)),n.hurried):null}let r=!1;for(let e=0;e<n;e++)if(A(e),r=yield t.at(e),r&&t.stop(e))return null;return r}function g(t,n){t.forEach((t,A)=>{const e=n[A];for(let n=0;n<t.length;n++)t[n]+=e[n]})}function I(t,n){const A=n.map(t=>t.length);!function(t,n){t.write(1,0),t.A();for(const A of n)t.t([[10,0],[14,1024],[22,17408],[30,4211712]],A);t.A()}(t,A);const e=t.finish(),o=e.length+A.reduce((t,n)=>t+n,0);r(o);const s=new Uint8Array(o);s.set(e);let i=e.length;for(const t of n)s.set(t,i),i+=t.length;return s}function B(t,n){const A=new Uint8Array(t.length),e=[];for(let n=0;n<t.length;n++)t[n]>0&&e.push(n);if(!e.length)return A;if(1===e.length)return A[e[0]]=1,A;for(let r=1;;r*=2){const o=e.map(n=>({w:Math.max(t[n],r),C:n,l:null,r:null})).sort((t,n)=>t.w-n.w||t.C-n.C),s=[];let i=0,c=0;const l=()=>i<o.length&&(c>=s.length||o[i].w<=s[c].w)?o[i++]:s[c++];for(;o.length-i+(s.length-c)>1;){const t=l(),n=l();s.push({w:t.w+n.w,C:-1,l:t,r:n})}const f=[[l(),0]];let a=0;for(;f.length;){const[t,n]=f.pop();t.C>=0?(A[t.C]=n,n>a&&(a=n)):f.push([t.l,n+1],[t.r,n+1])}if(a<=n)return A}}function u(t,n,A,e,r,o){const s=[];for(;s.push(e&r),e>>=o;)e--;for(let e=s.length-1;e>=0;e--)t.push(A),n.push(s[e])}function E(t,n){let A=0;for(let e=0;e<n;e++)A=A<<1|1&t,t>>=1;return A}function h(t){const n=new Uint32Array(17),A=new Uint32Array(17),e=new Uint16Array(t.length);for(const A of t)n[A]++;n[0]=0;for(let t=1,e=0;t<=16;t++)e=e+n[t-1]<<1,A[t]=e;for(let n=0;n<t.length;n++)t[n]&&(e[n]=E(A[t[n]]++,t[n]));return e}function Q(t){const n=[];for(let A=0;A<t.length;A++)t[A]>0&&n.push(A);const A=n.length,e=n[A-1]+1||1,r=A<=4?new Uint8Array(e):B(t,15).subarray(0,e);let o=0;if(A<=4){n.sort((n,A)=>t[A]-t[n]||n-A),o=4===A&&t[n[0]]>t[n[2]]+t[n[3]]?1:0;const e=A<2?[0]:2===A?[1,1]:3===A?[1,2,2]:o?[1,2,3,3]:[2,2,2,2];n.forEach((t,n)=>{r[t]=e[n]}),n.sort((t,n)=>r[t]-r[n]||t-n)}return{p:e,M:r,S:h(r),D:A&&A<=4?n:null,U:o}}function C(t,n){if(n.p<=1)return;if(n.D){const e=A(n.p-1)+1;t.write(2,1),t.write(2,n.D.length-1);for(const A of n.D)t.write(e,A);return void(4===n.D.length&&t.write(1,n.U))}const e=n.M,r=[],o=[];let s=e.length-1;for(;s>0&&!e[s];)s--;let i=8;for(let t=0;t<=s;){const n=e[t];let A=1;for(;t+A<=s&&e[t+A]===n;)A++;let c=A;if(n&&n!==i&&(r.push(n),o.push(0),c--,i=n),c<3)for(let t=0;t<c;t++)r.push(n),o.push(0);else u(r,o,n?16:17,c-3,n?3:7,n?2:3);t+=A}const c=new Uint32Array(18);for(const t of r)c[t]++;let l=0;for(const t of c)t&&l++;1===l&&(c[r[0]?0:1]=c[r[0]]);const f=B(c,5),a=h(f);let g=18;for(;g>0&&!f[ht[g-1]];)g--;t.write(2,0);for(let n=0;n<g;n++){const A=f[ht[n]];t.write(Qt[A],Ct[A])}for(let n=0;n<r.length;n++){const A=r[n];t.write(f[A],a[A]),16===A?t.write(2,o[n]):17===A&&t.write(3,o[n])}}function y(t,n=0,A=0){return{split:t,R:n,G:A,m:1<<t}}function w(t,n,A=15){t.write(e(A+1),n.split),n.split!==A&&(t.write(e(n.split+1),n.R),t.write(e(n.split-n.R+1),n.G))}function p(t,n,e){if(n<t.m)return e[0]=n,e[1]=0,void(e[2]=0);const r=A(n),o=n-(1<<r),s=r-t.R-t.G;e[0]=t.m+(r-t.split<<t.R+t.G|o>>r-t.R<<t.G|o&(1<<t.G)-1),e[1]=s,e[2]=n>>t.G&(1<<s)-1}function d(t,n,A,e=0){p(t,n,yt),A[e+yt[0]]++}function M(t,n,A,e,r=0){p(A,e,yt);const o=r+yt[0];t.write(n.M[o],n.S[o]),yt[1]&&t.write(yt[1],yt[2])}function S(t,{q:n=null,k:r,N:o}){t.write(1,n?1:0),n&&(t.t([[0,224],[0,512],[0,4096],[15,8]],n.J),t.t([[0,3],[0,4],[2,5],[8,9]],n.minLength),w(t,n.F,8)),r.length>1&&function(t,n){let A=0;for(const t of n)A=Math.max(A,t);const r=A?e(A+1):0;if(r<=3){if(t.write(1,1),t.write(2,r),r)for(const A of n)t.write(r,A);return}t.write(1,0),t.write(1,0);const o=y(8),s=y(4),i=n.length>=64,c=new Uint32Array(i?257:A+1),l=[];for(let t=0;t<n.length;){let A=1;for(;i&&t+A<n.length&&n[t+A]===n[t];)A++;if(A>=8)l.push([n[t],A-1]),c[n[t]]++,d(s,A-1-7,c,224),t+=A;else{for(let e=0;e<A;e++)l.push([n[t],0]),c[n[t]]++;t+=A}}const f=Q(c);if(!i){S(t,{k:new Uint8Array(1),N:[{config:o,code:f}]});for(const[n]of l)M(t,f,o,n);return}const a=new Uint32Array(1);a[0]=1,S(t,{q:{J:224,minLength:7,F:s},k:new Uint8Array([1,0]),N:[{config:y(0),code:Q(a)},{config:o,code:f}]});for(const[n,A]of l)M(t,f,o,n),A&&M(t,f,s,A-7,224)}(t,r),t.write(1,1);for(const n of o)w(t,n.config,15);for(const n of o){const e=n.code.p-1;if(e){const n=A(e);t.write(1,1),t.write(4,n),t.write(n,e-(1<<n))}else t.write(1,0)}for(const n of o)C(t,n.code)}function D(t,n=0,A=1){return{H:t,offset:n,L:A,context:-1}}function U(t,n,A,e){return{K:t,v:n,left:A,right:e}}function b(t,n){const A=(e,r)=>{if(e===r)return n?t[e].W:t[e];const o=e+r>>1;return U(n,n?t[o].P:o,A(o+1,r),A(e,o))};return A(0,t.length-1)}function R(t){return b(t,0)}function G(t,A){const e=[A],r=[],o=[];for(const t of e){if(t.left){r.push(t.K+1,n(t.v)),e.push(t.left,t.right);continue}t.context=o.length,o.push(t);const A=1===t.L?0:31-Math.clz32(t.L&-t.L);r.push(0,t.H,n(t.offset),A,(t.L>>A)-1)}const s=new Uint32Array(64);for(const t of r)d(St,t,s);const i=Q(s);S(t,{k:new Uint8Array(6),N:[{config:St,code:i}]});for(const n of r)M(t,i,St,n);return o}function m(t,n){const A=[[3,0],[6,8],[10,72],[13,1096]];if("rct"===n.type)t.write(2,0),t.t(A,n.Y),t.t([[0,6],[2,0],[4,2],[6,10]],n.X??6);else if("palette"===n.type)t.write(2,1),t.t(A,n.Y),t.t([[0,1],[0,3],[0,4],[13,1]],n.V),t.t([[8,0],[10,256],[12,1280],[16,5376]],n.T),t.t([[0,0],[8,1],[10,257],[16,1281]],n.Z??0),t.write(4,n.H??0);else{if("squeeze"!==n.type)throw new Error("unknown transform "+n.type);{t.write(2,2);const e=n.O??[];t.t([[0,0],[4,1],[6,9],[8,41]],e.length);for(const n of e)t.write(1,n.j?1:0),t.write(1,n._?1:0),t.t(A,n.Y),t.t([[0,1],[0,2],[0,3],[4,4]],n.V)}}}function q(t,{$:n=!0,tt:A=[]}={}){t.write(1,n?1:0),t.write(1,1),t.t([[0,0],[0,1],[4,2],[8,18]],A.length);for(const n of A)m(t,n)}function k(t,n,A,e=t=>t.context,r=()=>St){const o=new Uint8Array(n.length+1);for(const t of n)o[t.context]=e(t)+1;const s=new Uint32Array(2);s[1]=1;const i=[{config:St,code:Q(s)}],c=Math.max(...o);for(let t=0;t<c;t++)i.push({config:r(t),code:Q(A[t])});return S(t,{q:Mt,k:o,N:i}),i}function N(t,A,e,r,o,s,i=!1){if(it.channel?.(t,A,e,r,o,s,i))return;const c=s.H,l=s.offset,f=s.L,a=s.config||St,g=dt;let I=0;const B=(n,e=a,r=0)=>{t?M(t,A,e,n,r):i&&!r?A[n]++:d(e,n,A,i?A.length-33:r)},u=()=>{if(I){if(I>=8)B(0),B(I-7-1,g,224);else for(let t=0;t<I;t++)B(0);I=0}},E=(t,A)=>{const r=e[t];let o;1===f?o=r-A-l:(o=Math.round((r-A-l)/f),e[t]=A+l+o*f),0!==o?(u(),B(n(o))):I++};for(let t=0,n=0;t<o;t++)for(let A=0;A<r;A++,n++){let o;if(0===c)o=0;else{const s=A?e[n-1]:t?e[n-r]:0,i=t?e[n-r]:s;if(1===c)o=s;else if(2===c)o=i;else if(3===c)o=(s+i)/2|0;else{const l=s+i-(A&&t?e[n-r-1]:s);if(5===c){const t=s<i?s:i,n=s<i?i:s;o=l<t?t:l>n?n:l}else{if(4!==c)throw new Error("predictor "+c+" is not coded here");o=Math.abs(l-s)<Math.abs(l-i)?s:i}}}E(n,o)}u()}function J(t){const n=t.length-33,e=[0,0,0];let r,o;for(const s of Ut){const i=new Uint32Array(Dt);let c=0;for(let A=0;A<n;A++)t[A]&&(p(s,A,e),i[e[0]]+=t[A],c+=t[A]*e[1]);for(let A=0;A<33;A++)i[224+A]=t[n+A],c+=t[n+A]*Math.max(0,A-12);const l=Q(i),f=new ft(128);w(f,s),C(f,l);let a=f.nt+c+(1===l.p?1:5+A(l.p-1));for(let t=0;t<i.length;t++)i[t]&&(a+=i[t]*l.M[t]);const g={config:s,At:i,et:a,extra:c};r||(r=g),(!o||a<o.et)&&(o=g)}return[r,o]}function F(t,n,A,{palette:e=!0}={}){const r=n*A;let o=!0,s=!0;for(let n=0,A=0;A<r&&(255===t[n+3]||(o=!1,s))&&(t[n]===t[n+1]&&t[n]===t[n+2]||(s=!1,o));A++,n+=4);const i=s?1:3,c=!o,l=i+(c?1:0),f=n=>bt(t,n,s,c),a=new Map;let g=null;for(let t=0,n=0;e&&n<r;n++,t+=4){const n=f(t);if(0!==n&&!a.has(n)&&(a.set(n,1),a.size>=2048))break}if(e&&a.size<2048){const t=[...a.keys()],n=(t,n)=>t>>>8*n&255,A=t=>(.299*n(t,0)+.587*n(t,1)+.114*n(t,2)+.01)*(4===l?n(t,3):1);t.sort((t,n)=>A(t)-A(n)),g={colours:[0,...t],byte:n}}return{colour:i,alpha:c,channels:l,palette:g}}function H({channels:t,alpha:n,palette:A},e){const r=t-(n?1:0)==1,o=A&&new Map(A.map((t,n)=>[t,n]));return(s,i,c,l,f,a,g)=>{if(e&&!A&&t>=3)e.fill(s,i,c,l,f,a,g);else if(A||!it.fill?.(i,c,l,f,a,g,t,s))for(let e=0;e<g;e++){let g=4*((f+e)*c+l),I=e*a;for(let e=0;e<a;e++,g+=4,I++)if(A)s[0][I]=o.get(bt(i,g,r,n));else if(t>=3){const n=i[g],A=i[g+1],e=i[g+2],r=n-e,o=e+(r>>1),c=A-o;s[0][I]=o+(c>>1),s[1][I]=r,s[2][I]=c,4===t&&(s[3][I]=i[g+3])}else s[0][I]=i[g],2===t&&(s[1][I]=i[g+3])}}}function L(t,n){const{leaves:A,picture:e,S:r}=t,o=H(t,n),s=e.map(()=>new Int16Array(65536));return(t,n,i,c,l,f,a)=>{if(o(s,t,n,i,c,l,f),!r)return void e.forEach((t,n)=>N(null,a[t],s[n],l,f,A[t],!0));const g=a||new ft(l*f*e.length+64);return a||q(g,{$:!0,tt:[]}),e.forEach((t,n)=>N(g,r[t],s[n],l,f,A[t])),a?void 0:g.finish()}}function*K(n,A,e,{shape:r=F(n,A,e),colorSpace:o,rct:s,pooled:i}={}){let c,l;const f=r.palette?[r,{...r,palette:null}]:[r];for(let r=0;r<f.length;r++)try{const l=yield*t(x(n,A,e,f[r],o,s,i),r,f.length);(!c||l.length<c.length)&&(c=l)}catch(t){if("JXL_SIZE"!==t.code)throw t;l=t}if(!c)throw l;return c}function*x(t,n,A,e,r,o,s){const{channels:B,alpha:u,palette:E}=e,h=l(n,A),y=h.o*h.i,w=E?2:B,p=Array.from({length:w},()=>D(pt)),d=R(p),M={channels:B,alpha:u,palette:E&&E.colours,rct:o?.type,leaves:p,picture:E?[h.u?1:0]:p.map((t,n)=>n)},S=H(M,o),U=Array.from({length:B},()=>new Int16Array(1024)),b=t=>f(h,n,A,t);let m=null;if(E){const t=E.colours.length;m=new Int16Array(t*B),E.colours.forEach((n,A)=>{for(let e=0;e<B;e++)m[e*t+A]=E.byte(n,e)})}if(!E){const e=t=>{const n=Q(t),A=new ft(128);C(A,n);let e=A.nt;for(let A=0;A<t.length;A++)t[A]&&(e+=t[A]*(n.M[A]+Math.max(0,A<224?A-1:A-236)));return e},r=Math.min(n,32),o=Math.min(A,32),s=[pt,wt].map(t=>({H:t,At:p.map(()=>new Uint32Array(Dt))}));for(const e of[0,.5,1]){S(U,t,n,Math.floor((n-r)*e),Math.floor((A-o)*e),r,o);for(const t of s)for(let n=0;n<B;n++)N(null,t.At[n],U[n],r,o,D(t.H))}p.forEach((t,n)=>{const A=s.map(t=>e(t.At[n])),r=A[1]<A[0]?1:0;t.H=s[r].H})}const F=E?[{type:"palette",Y:0,V:B,T:E.colours.length}]:B>=3&&0!==o?.type?[{type:"rct",Y:0,X:o?.type??6}]:[];let K=p.map(()=>new Uint32Array(33+(E?4096:1024)));m&&N(null,K[0],m,E.colours.length,B,p[0],!0);const x=L(M,o);yield*a({pooled:s,kind:"plan",setup:{...M,sizes:K.map(t=>t.length)},at:t=>(t+1)/(2*y),stop:()=>!1},y,A=>x(t,n,...b(A),K),(t,n)=>g(K,n));const v=K.map(J),W=v.reduce((t,n)=>t+n[0].et-n[1].et,0)>27*(h.u?1:y+1)+8?1:0;p.forEach((t,n)=>{t.config=v[n][W].config}),K=v.map(t=>t[W].At);const P=new ft(256);i(P,n,A,e.colour,e.alpha,{colorSpace:r}),c(P,{alpha:e.alpha});const Y=new ft(4096);Y.write(1,1),Y.write(1,1);const X=k(Y,G(Y,d),K,t=>p.indexOf(t),t=>p[t].config),V={...M,S:p.map((t,n)=>X[n+1]?.code)},T=L(V,o);q(Y,{$:!0,tt:F}),m&&N(Y,V.S[0],m,E.colours.length,B,p[0]);const Z=[];if(h.u)T(t,n,0,0,n,A,Y),yield 1,Z.push(Y.finish());else{Z.push(Y.finish());for(let t=0;t<h.I*h.B+1;t++)Z.push(new Uint8Array(0));const A=Z.length,e=(t,n)=>{Z[A+t]=n};yield*a({pooled:s,kind:"plan",setup:V,at:t=>(y+t+1)/(2*y),stop:()=>!1},y,A=>e(A,T(t,n,...b(A))),e)}return I(P,Z)}function v(t,n,A){const e=t>=n&&n>=A?1:t<=n&&n<=A?-1:0;if(!e)return 0;let r=(4*(t*=e)-3*(A*=e)-(n*=e)+6)/12|0;return r-(1&r)>2*(t-n)&&(r=2*(t-n)+1),r+(1&r)>2*(n-A)&&(r=2*(n-A)),e*r}function W(t,n){const{w:A,h:e,data:r}=t,o=n?A:e,s=o+1>>1,i=o-s,c=n?s:A,l=n?e:s,f=n?i:A,a=n?e:i,g=new Int16Array(c*l),I=new Int16Array(f*a),B=n?1:A;for(let t=0;t<l;t++)for(let e=0;e<c;e++){const s=n?e:t,l=n?t*A+2*e:2*t*A+e;if(s===i){g[t*c+e]=r[l];continue}const a=r[l],u=r[l+B],E=Rt(a,u),h=s+1<i?Rt(r[l+2*B],r[l+3*B]):1&o?r[l+2*B]:E;g[t*c+e]=E,I[t*f+e]=a-u-v(s?r[l-B]:E,E,h)}const u=(A,e,r)=>({w:e,h:r,rt:t.rt+ +n,ot:t.ot+!n,data:A});return[u(g,c,l),u(I,f,a)]}function P(t){const n=[],A=t.length;let e=t[0].w,r=t[0].h;for(A>2&&t[1].w===e&&t[1].h===r&&(n.push({j:!0,_:!1,Y:1,V:2}),n.push({j:!1,_:!1,Y:1,V:2})),!(e>r)&&r>8&&(n.push({j:!1,_:!0,Y:0,V:A}),r=r+1>>1);e>8||r>8;)e>8&&(n.push({j:!0,_:!0,Y:0,V:A}),e=e+1>>1),r>8&&(n.push({j:!1,_:!0,Y:0,V:A}),r=r+1>>1);return n}function*Y(t,n,A,{quality:e=90,shape:r=F(t,n,A,{palette:!1}),colorSpace:o}={}){const s=function(t){return t>=100?0:t>=30?.1+.09*(100-t):53/3e3*t*t-1.15*t+25}(e);if(!(s>0))throw new Error("lossy encoding needs a quality below 100");const{colour:f,alpha:a,channels:g}=r,B=n*A,u=Array.from({length:g},()=>new Int16Array(B));for(let n=0,A=0;A<B;A++,n+=4){if(3===f){const e=t[n],r=t[n+1],o=t[n+2],s=e-o,i=o+(s>>1),c=r-i;u[0][A]=i+(c>>1),u[1][A]=s,u[2][A]=c}else u[0][A]=t[n];a&&(u[g-1][A]=t[n+3])}const E=u.map((t,e)=>({w:n,h:A,rt:0,ot:0,data:t,component:3===f?e:0===e?0:3})),h=1===n&&A>Gt&&3===f,Q=h?P(E).filter(t=>!t.j):1!==n&&1!==A||3!==f?[]:P(E),C=function(t,n=P(t)){const A=t.map(t=>({...t,level:0,st:!1}));for(const t of n){const n=t.Y+t.V-1,e=t._?n+1:A.length;for(let r=t.Y;r<=n;r++){const[n,o]=W(A[r],t.j),s=A[r].level+1;A[r]={...n,level:s,st:A[r].st,component:A[r].component},A.splice(e+(r-t.Y),0,{...o,level:s,st:!0,component:A[r].component})}}return A}(E,Q.length?Q:void 0),y=t=>t.st?0:pt,w=t=>function(t,n,A,e){let r=Math.min(16,n+A);if(r>0&&r--,3===t)return 1;const o=.25*function(t){let n=1;for(let A=0;A<24;A++)n=(4*n+t/(n*n*n*n))/5;return t*n}(e),s=1<<r,i=1===t||2===t?.35*o*Math.max(.5,1024/s):.35*o*1.1*(163.84/s);return Math.max(1,Math.floor(i))}(t.component,t.rt+(h&&t.component>0&&t.component<3?1:0),t.ot,s),p=[...3===f?[{type:"rct",Y:0,X:6}]:[],{type:"squeeze",O:Q}],d=l(n,A,Gt),M=d.I*d.B,S=d.o*d.i;let U=0;for(;U<C.length&&C[U].w<=Gt&&C[U].h<=Gt;)U++;const m=(t,n,A,e)=>{const r=n>>t.rt,o=A>>t.ot;return{x:r,y:o,w:Math.min(t.w,r+(e>>t.rt))-r,h:Math.min(t.h,o+(e>>t.ot))-o}},J=[{index:0,P:0,it:[]}];for(let t=0;t<U;t++)J[0].it.push({c:t,rect:{x:0,y:0,w:C[t].w,h:C[t].h}});if(!d.u){for(let t=0;t<M;t++){const n=t%d.I,A=t/d.I|0,e={index:1+t,P:1+M+t,it:[]};for(let t=U;t<C.length;t++){const r=C[t];if(Math.min(r.rt,r.ot)<3)continue;const o=m(r,n*mt,A*mt,mt);o.w>0&&o.h>0&&e.it.push({c:t,rect:o})}J.push(e)}for(let t=0;t<S;t++){const n=t%d.o,A=t/d.o|0,e={index:2+M+t,P:1+3*M+17+t,it:[]};for(let t=U;t<C.length;t++){const r=C[t];if(Math.min(r.rt,r.ot)>2)continue;const o=m(r,n*Gt,A*Gt,Gt);o.w>0&&o.h>0&&e.it.push({c:t,rect:o})}J.push(e)}}for(const t of J)for(const n of t.it){const t=C[n.c];n.ct=D(y(t),0,w(t)),n.ct.channel=n.c}const H=J.filter(t=>t.it.length),L=1===H.length?R(H[0].it.map(t=>t.ct)):function(t){return b(t,1)}(H.map(t=>({P:t.P,W:R(t.it.map(t=>t.ct))}))),K=new Int16Array(1048576),x=t=>{const n=C[t.c],A=t.rect;if(A.w===n.w&&A.h===n.h)return n.data;for(let t=0;t<A.h;t++)K.set(n.data.subarray((A.y+t)*n.w+A.x,(A.y+t)*n.w+A.x+A.w),t*A.w);return K},v=[...new Set(J.flatMap(t=>t.it.map(t=>t.c)))].sort((t,n)=>t-n),Y=new Map(v.map((t,n)=>[t,n])),X=v.map(()=>new Uint32Array(Dt)),V=1+2*J.length;let T=1;yield T/V;for(const t of J){for(const n of t.it)N(null,X[Y.get(n.c)],x(n),n.rect.w,n.rect.h,n.ct);yield++T/V}const Z=new ft(256);i(Z,n,A,f,a,{colorSpace:o}),c(Z,{alpha:a,shift:n>256||A>256?3:1});const O=Array.from({length:d.u?1:2+M+S},()=>null),j=O[0]=new ft(65536);j.write(1,1),j.write(1,1);const z=k(j,G(j,L),X,t=>Y.get(t.channel));q(j,{$:!0,tt:p});for(const t of J){let n=O[t.index];n||(n=O[t.index]=new ft(4096),t.it.length&&q(n,{$:!0,tt:[]}));for(const A of t.it)N(n,z[Y.get(A.c)+1].code,x(A),A.rect.w,A.rect.h,A.ct);yield++T/V}return I(Z,function(t){return t.map(t=>t?t.finish():new Uint8Array(0))}(O))}function X(t,A,e,r,o,s=0,i=Lt,c,l){if(it.weighted?.(t,A,e,r,o,s,i,c,l))return;const f=r+2,a=Kt&&Kt[0].length>=2*f?Kt:Array.from({length:6},(t,n)=>new Int32Array(n<5?2*f:8));Kt=null;for(const t of a)t.fill(0);const[g,I,B,u,E,h]=a;let Q=0;const C=(n,e,r=St,o=0)=>{t?M(t,A[n],r,e,o):d(r,e,A[n],o)},y=()=>{if(Q){if(Q>Mt.minLength)C(h[0],0),C(h[1],Q-Mt.minLength-1,Mt.F,Mt.J);else for(let t=0;t<Q;t++)C(h[t],0);Q=0}};for(let t=0,A=0;t<o;t++){const o=1&t?0:f,a=1&t?f:0;for(let f=0;f<r;f++,A++){const w=f?e[A-1]:t?e[A-r]:0,p=t?e[A-r]:w,d=f+1<r&&t?e[A-r+1]:p,M=a+f,S=f<r-1?M+1:M,D=f?M-1:M;let U=Ht(g[M]+g[S]+g[D],13),b=Ht(I[M]+I[S]+I[D],12),R=Ht(B[M]+B[S]+B[D],12),G=Ht(u[M]+u[S]+u[D],12);const m=8*p,q=8*w,k=8*d,N=f?E[o+f-1]:0,J=E[M],F=E[D],H=E[S],L=J+N;let K=N;Math.abs(J)>Math.abs(K)&&(K=J),Math.abs(F)>Math.abs(K)&&(K=F),Math.abs(H)>Math.abs(K)&&(K=H);const x=i[kt[K<-501?0:K>501?1002:K+501]];l&&(l[A]=K);const v=q+k-m,W=m-(16*(L+H)>>5),P=q-(10*(L+F)>>5),Y=m-(7*(F+J+H)>>5),X=27-Math.clz32(U+b+R+G);U>>=X,b>>=X,R>>=X,G>>=X;const V=U+b+R+G;let T=Math.floor(((V>>1)-1+v*U+W*b+P*R+Y*G)*Nt[V-1]/16777216);if((J^N|J^F)<=0){const t=Math.min(q,k,m),n=Math.max(q,k,m);T=T<t?t:T>n?n:T}const Z=e[A],O=Z-(T+3>>3)-s;c?c[A]=n(O):0===O?(Q<8&&(h[Q]=x),Q++):(y(),C(x,n(O)));const j=8*Z,z=Math.abs(v-j)+3>>3,_=Math.abs(W-j)+3>>3,$=Math.abs(P-j)+3>>3,tt=Math.abs(Y-j)+3>>3;E[o+f]=T-j,g[o+f]=z,I[o+f]=_,B[o+f]=$,u[o+f]=tt,g[a+f+1]+=z,I[a+f+1]+=_,B[a+f+1]+=$,u[a+f+1]+=tt}}y(),Kt=a}function V(t,A,e,r,o){const s=new Uint32Array(A*e);if(6===r)return X(null,null,t,A,e,0,void 0,s,o),s;for(let o=0,i=0;o<e;o++)for(let e=0;e<A;e++,i++){const c=e?t[i-1]:o?t[i-A]:0,l=o?t[i-A]:c,f=e&&o?t[i-A-1]:c,a=3===r?(c+l)/2|0:Math.max(Math.min(c,l),Math.min(Math.max(c,l),c+l-f));s[i]=n(t[i]-a)}return s}function T(t,n,A=1){const e=Array.from({length:A},()=>new Uint32Array(Dt)),r=[],o=(t,A,o=0)=>{const s=n?n[t]:0;r.push(A,o,s),d(o?Mt.F:St,A,e[s],o)};for(let n=0;n<t.length;){let A=1;if(!t[n])for(;n+A<t.length&&!t[n+A];)A++;if(o(n,t[n]),A>Mt.minLength)o(n+1,A-1-Mt.minLength,Mt.J);else for(let t=1;t<A;t++)o(n+t,0);n+=A}return{At:e,it:r}}function Z(t,n,A,e,r){const o=T(t,Uint8Array.from(n,t=>{let n=0,A=r.length;for(;n<A;){const e=n+A>>1;t>r[e]?n=e+1:A=e}return n}),r.length+1),s=o.At.length,i=o.At.map(t=>t.some(t=>t)),c=new Float64Array(s+1).fill(1/0),l=new Uint8Array(s+1);c[0]=0;for(let t=1;t<=s;t++){const n=new Uint32Array(Dt);let A=0;for(let e=t-1;e>=0;e--){if(i[e]){for(let t=0;t<Dt;t++)n[t]+=o.At[e][t];A=vt(n)}const r=c[e]+A+24;r<c[t]&&(c[t]=r,l[t]=e)}}const f=[];for(let t=s;t;t=l[t])f.unshift([l[t],t]);const a=f.map(()=>D(A)),g=new Uint8Array(s),I=f.map(([t,n],A)=>{const e=new Uint32Array(Dt);for(let r=t;r<n;r++){g[r]=A;for(let t=0;t<Dt;t++)e[t]+=o.At[r][t]}return e});for(let t=2;t<o.it.length;t+=3)o.it[t]=g[o.it[t]];const B=(t,n)=>{if(t===n)return a[t];const A=t+n>>1;return U(e,r[f[A][1]-1],B(A+1,n),B(t,A))};return{leaves:a,W:B(0,f.length-1),At:I,it:o.it}}function O(t,n,A,e){const r=new Int32Array(n*A);for(let o=0,s=0;o<A;o++)for(let A=0;A<n;A++,s++){const i=A?t[s-1]:o?t[s-n]:0,c=o?t[s-n]:i,l=A&&o?t[s-n-1]:i;r[s]=9===e?i+c-l:i-l}return r}function j(t){const n=new ft(512),A=k(n,G(n,t.W),t.At,n=>t.leaves.indexOf(n));let e=n.nt;return t.At.forEach((t,n)=>{const{M:r}=A[n+1].code;for(let n=0;n<t.length;n++)e+=t[n]*((r[n]||0)+xt(n))}),e}function z(t,n,A,e){return t.map(t=>{let r;for(const o of[5,3,6]){const s=6===o?new Int32Array(n*A):null,i=V(t,n,A,o,s),c=D(o),l=[{...T(i),leaves:[c],W:c}];if(s&&l.push(Z(i,s,o,15,Wt)),e>=6&&5===o)for(const e of[9,10]){const r=O(t,n,A,e),s=9===e?Pt:Wt;l.push(Z(i,r,o,e,s))}for(const t of l){const n=j(t);(!r||n<r.et)&&(r={...t,et:n})}}return r})}function _(t,n){const A=n.flatMap(t=>t.leaves),e=k(t,G(t,R(n.map(t=>t.W))),n.flatMap(t=>t.At),t=>A.indexOf(t));return()=>{for(let r=0;r<n.length;r++){const{it:o}=n[r],s=n[r].leaves.map(t=>e[A.indexOf(t)+1].code);for(let n=0;n<o.length;n+=3){const A=o[n+1];M(t,s[o[n+2]],A?Mt.F:St,o[n],A)}}}}function*$(t,n,A,e,o,s=4,g=!1,B){const{channels:u}=e,E=l(n,A),h=E.o*E.i,Q=g?e.palette:null;if(g&&!Q)return null;const C={channels:u,alpha:e.alpha,palette:Q&&Q.colours,rung:s},y=new ft(256);i(y,n,A,e.colour,e.alpha,{colorSpace:o}),c(y,{alpha:e.alpha});const w=Q?[{type:"palette",Y:0,V:u,T:Q.colours.length}]:u>=3?[{type:"rct",Y:0,X:6}]:[];let p;if(Q){const t=Q.colours.length,n=new Int16Array(t*u);Q.colours.forEach((A,e)=>{for(let r=0;r<u;r++)n[r*t+e]=Q.byte(A,r)}),p=z([n],t,u,s)}const d=new ft(4096),M=[];let S=0;const U=t=>{S+=t.length,r(S),M.push(t)};if(d.write(1,1),d.write(1,1),E.u){const e=Array.from({length:Q?1:u},()=>new Int16Array(65536));H(C)(e,t,n,0,0,n,A);const r=_(d,[...p||[],...z(e,n,A,s)]);return q(d,{tt:w}),r(),U(d.finish()),(yield 1)?null:I(y,M)}let b;if(p)b=_(d,p);else{const t=Array.from({length:u},()=>D(5));k(d,G(d,R(t)),t.map(()=>new Uint32Array(Dt)),n=>t.indexOf(n))}q(d,{tt:w}),b&&b(),U(d.finish());for(let t=0;t<E.I*E.B+1;t++)M.push(new Uint8Array(0));const m=function(t){const n=H(t),A=Array.from({length:t.palette?1:t.channels},()=>new Int16Array(65536));return(e,r,o,s,i,c)=>{n(A,e,r,o,s,i,c);const l=new ft(i*c*A.length+256);return q(l,{$:!1}),_(l,z(A,i,c,t.rung))(),l.finish()}}(C);return null===(yield*a({pooled:B,kind:"local",setup:C,at:t=>(t+1)/h,stop:()=>!0},h,e=>U(m(t,n,...f(E,n,A,e))),(t,n)=>U(n)))?null:I(y,M)}function tt(t,n){const A=Math.floor(t/7),e=t%7,r=A%3,o=(A+1+Math.floor(A/3))%3,s=(A+2-Math.floor(A/3))%3;return{type:t,fill(t,A,i,c,l,f,a){for(let g=0;g<a;g++)for(let a=0,I=g*f,B=4*((l+g)*i+c);a<f;a++,I++,B+=4){const i=A[B+r],c=A[B+o],l=A[B+s];if(6===e){const n=i-l,A=l+(n>>1),e=c-A;t[0][I]=A+(e>>1),t[1][I]=n,t[2][I]=e}else t[0][I]=i,t[1][I]=c-(e>>1==1?i:e>>1==2?i+l>>1:0),t[2][I]=l-(1&e?i:0);4===n&&(t[3][I]=A[B+3])}}}}function nt(n,A,e,r,o){const{quality:s,colorSpace:i}=function(t={},n=100){if(null===t||"object"!=typeof t)throw ut("JXL_INPUT","Options are an object: {quality, colorSpace}.");if(void 0!==t.quality&&(n=t.quality),"number"!=typeof n||!Number.isFinite(n)||n<1||n>100)throw ut("JXL_INPUT","Quality is a number from 1 to 100.");const A=void 0===t.colorSpace?"srgb":t.colorSpace;if("srgb"!==A&&"display-p3"!==A)throw ut("JXL_INPUT","The colour space is srgb or display-p3.");return{quality:n,colorSpace:A}}(r),c=void 0===r?.effort?1:r.effort;if(!Number.isInteger(c)||c<1||c>9)throw ut("JXL_INPUT","Effort is a whole number from 1 to 9.");return function(t,n,A,e){if(function(t,n,A=ct){if(!Number.isInteger(t)||!Number.isInteger(n)||t<1||n<1)throw ut("JXL_INPUT","A picture is at least one pixel wide and high, in whole pixels.");if(t>A.edge||n>A.edge)throw ut("JXL_DIMENSIONS","A picture is at most "+A.edge+" pixels on a side.");if(t*n>A.pixels)throw ut("JXL_DIMENSIONS","A picture is at most "+A.pixels.toLocaleString("en-US")+" pixels.")}(n,A,e),!(t instanceof Uint8Array||t instanceof Uint8ClampedArray))throw ut("JXL_INPUT","Pixels are a Uint8Array or Uint8ClampedArray of RGBA bytes.");if(t.length!==n*A*4)throw ut("JXL_INPUT","Pixels are width * height * 4 bytes: straight (not premultiplied) RGBA, row by row.")}(n,A,e),function*(n,A,e,r,o,s,i){const c=F(n,A,e);if(r<100){if(!c.palette)return yield*Y(n,A,e,{quality:r,shape:c,colorSpace:o});const s=yield*t(K(n,A,e,{shape:c,colorSpace:o}),0,2);let i;try{i=yield*t(Y(n,A,e,{quality:r,shape:c,colorSpace:o}),1,2)}catch(t){if("JXL_SIZE"!==t.code&&(!(t instanceof RangeError)||t.code))throw t;i=s}return s.length<=i.length?s:i}if(s<2)return yield*K(n,A,e,{shape:c,colorSpace:o,pooled:i});let l=yield*t(K(n,A,e,{shape:c,colorSpace:o,pooled:i}),0,2);const f=c.palette?{...c,palette:null}:c;if(s>=4){const t=[rt(n,A,e,f,o,3,i)];c.palette&&t.push($(n,A,e,c,o,4,!0,i)),s>=6&&(t.push($(n,A,e,c,o,6,!1,i)),c.palette&&t.push($(n,A,e,c,o,6,!0,i))),t.push(function*(t,n,A,e,r,o){if(3!==e.colour||n*A<4096)return null;const s=Math.min(n,32),i=Math.min(A,32),c=Array.from({length:e.channels},()=>new Int16Array(s*i)),l=[6,...Array.from({length:42},(t,n)=>n).filter(t=>6!==t)];let f;for(let r=0;r<l.length;r++){const o=tt(l[r],e.channels),a=[5,3].map(t=>({H:t,At:Array.from({length:3},()=>new Uint32Array(1057))}));for(let e=0;e<3;e++){o.fill(c,t,n,Math.floor((n-s)*e/2),Math.floor((A-i)*e/2),s,i);for(const t of a)for(let n=0;n<3;n++)N(null,t.At[n],c[n],s,i,D(t.H),!0)}const g=new ft(32);o.type&&m(g,{type:"rct",Y:0,X:o.type});let I=g.nt;for(let t=0;t<3;t++)I+=Math.min(...a.map(n=>J(n.At[t])[1].et));if((!f||I<f.et)&&(f={rct:o,et:I}),yield(r+1)/(4*l.length))return null}if(6===f.rct.type)return null;const a=K(t,n,A,{shape:{...e,palette:null},colorSpace:r,rct:f.rct,pooled:o});let g,I;for(;!(g=a.next(I)).done;){const t=g.value,n="number"==typeof t;if(I=yield n?.25+.75*t:{...t,at:n=>.25+.75*t.at(n),stop:n=>t.at(n)<1},n?I&&t<1:!I)return null}return g.value}(n,A,e,c,o,i));for(let n=0;n<t.length;n++)try{let A,e,r=!1;for(;!(A=t[n].next(e)).done;)r=Yt(e=yield at(A.value,A=>.5+(n+A)/(2*t.length)));if(A.value&&A.value.length<l.length&&(l=A.value),r)return l}catch(t){if("JXL_SIZE"!==t.code&&(!(t instanceof RangeError)||t.code))throw t}return l}try{const r=yield*t(rt(n,A,e,f,o,s,i),1,2);r&&r.length<l.length&&(l=r)}catch(t){if("JXL_SIZE"!==t.code&&(!(t instanceof RangeError)||t.code))throw t}return l}(n,A,e,s,i,c,o&&s>=100&&!l(A,e).u)}function At(t){const n=Q(t),A=new ft(128);C(A,n);let e=A.nt;for(let A=0;A<t.length;A++)t[A]&&(e+=t[A]*(n.M[A]+Xt(A)));return e}function et(t){const{channels:n,first:A,plans:e}=t,r=H(t),o=A?.map(t=>D(t)),s=Array.from({length:n},()=>new Int16Array(65536));return(t,A,i,c,l,f,a)=>{if(r(s,t,A,i,c,l,f),!e){for(let t=0;t<n;t++)N(null,a[t],s[t],l,f,o[t]),X(null,a.slice(n+t*Tt,n+(t+1)*Tt),s[t],l,f,0,Zt);return}const g=a||new ft(l*f*n+64);return a||q(g,{$:!0,tt:[]}),e.forEach(({ct:t,S:n,lt:A},e)=>{6===t.H?X(g,n,s[e],l,f,0,A):N(g,n[0],s[e],l,f,t)}),a?void 0:g.finish()}}function*rt(t,n,A,e,r,o,s){function*B(o){const{W:l,leaves:f,At:g}=P(o),B=u>=3?[{type:"rct",Y:0,X:6}]:[],C=new ft(256);i(C,n,A,e.colour,e.alpha,{colorSpace:r}),c(C,{alpha:e.alpha});const y=new ft(4096);y.write(1,1),y.write(1,1);const p=k(y,G(y,l),g,t=>f.indexOf(t));q(y,{$:!0,tt:B});const d={...Q,plans:o.map(t=>({ct:t.leaves[0],S:t.leaves.map(t=>p[f.indexOf(t)+1].code),lt:t.lt}))},M=et(d),S=[];if(E.u)M(t,n,0,0,n,A,y),T=yield.5+ ++V/(2*X.length*h),S.push(y.finish());else{S.push(y.finish());for(let t=0;t<E.I*E.B+1;t++)S.push(new Uint8Array(0));const A=V,e=S.length,r=(t,n)=>{S[e+t]=n};if(T=yield*a({pooled:s,kind:"search",setup:d,at:t=>.5+(A+t+1)/(2*X.length*h),stop:t=>t+1<h},h,A=>r(A,M(t,n,...w(A))),r),null===T)return null;V+=h}return I(C,S)}const{channels:u}=e,E=l(n,A),h=E.o*E.i,Q={channels:u,alpha:e.alpha,palette:null},C=H(Q),y=Array.from({length:u},()=>new Int16Array(1024)),w=t=>f(E,n,A,t),p=Math.min(n,32),d=Math.min(A,32),M=[pt,wt].map(t=>({H:t,At:y.map(()=>new Uint32Array(Dt))}));for(const e of[0,.5,1]){C(y,t,n,Math.floor((n-p)*e),Math.floor((A-d)*e),p,d);for(const t of M)for(let n=0;n<u;n++)N(null,t.At[n],y[n],p,d,D(t.H))}const S=y.map((t,n)=>D(M[At(M[1].At[n])<At(M[0].At[n])?1:0].H)),b=Tt,m=y.map(()=>new Uint32Array(Dt)),J=y.map(()=>Array.from({length:b},()=>new Uint32Array(Dt))),F=[...m,...J.flat()],L={...Q,first:S.map(t=>t.H)},K=et(L);if(null===(yield*a({pooled:s,kind:"search",setup:{...L,sizes:F.map(t=>t.length)},at:t=>(t+1)/(2*h),stop:()=>!0},h,A=>K(t,n,...w(A),F),(t,n)=>g(F,n))))return null;const x=y.map((t,n)=>{const A={ft:At(m[n]),leaves:[S[n]],At:[m[n]],cuts:[]},e=Vt(J[n]),r=At(e);return r<A.ft?{ft:r,leaves:[D(6)],At:[e],cuts:[]}:A}),v=o<3?x:x.map((t,n)=>{const A=J[n].map(t=>t.some(t=>t)),e=new Float64Array(b+1).fill(1/0),r=new Int32Array(b+1);e[0]=0;for(let t=1;t<=b;t++){const o=new Uint32Array(Dt);let s=0;for(let i=t-1;i>=0;i--){if(A[i]){const t=J[n][i];for(let n=0;n<Dt;n++)o[n]+=t[n];s=At(o)}const c=e[i]+s+24;c<e[t]&&(e[t]=c,r[t]=i)}}if(!(e[b]<t.ft))return t;const o=[];for(let t=b;t>0;t=r[t])o.unshift([r[t],t]);return{ft:e[b],leaves:o.map(()=>D(6)),At:o.map(([t,A])=>Vt(J[n].slice(t,A))),cuts:o.slice(0,-1).map(([,t])=>qt[t-1]),lt:Int32Array.from({length:b},(t,n)=>o.findIndex(([t,A])=>n>=t&&n<A))}}),W=[x,v].filter((t,n)=>n?t.some((t,n)=>t!==x[n]):t.some((t,n)=>t.leaves[0]!==S[n]));if(!W.length)return null;const P=t=>({W:R(t.map(t=>((t,n)=>{const A=(e,r)=>{if(e===r)return t[e];const o=e+r>>1;return U(15,n[o],A(o+1,r),A(e,o))};return A(0,t.length-1)})(t.leaves,t.cuts))),leaves:t.flatMap(t=>t.leaves),At:t.flatMap(t=>t.At)}),Y=t=>{const{W:n,leaves:A,At:e}=P(t),r=new ft(4096),o=k(r,G(r,n),e,t=>A.indexOf(t));let s=r.nt;return e.forEach((t,n)=>{const{M:A}=o[n+1].code;for(let n=0;n<t.length;n++)t[n]&&(s+=t[n]*(A[n]+Xt(n)))}),s};let X=W;if(W.length>1){const[t,n]=W.map(Y),A=27*(E.u?1:h+1)+8;n+A<=t?X=[W[1]]:t+A<=n?X=[W[0]]:n<t&&(X=[W[1],W[0]])}let V=0,T=!1,Z=null;for(const t of X){const n=yield*B(t);if(!n)return Z;if((!Z||n.length<Z.length||n.length===Z.length&&t===W[0])&&(Z=n),T)return Z}return Z}function ot(t,n,A,e){return function(t){let n;for(;!(n=t.next()).done;);return n.value}(st(t,n,A,e))}function st(t,n,A,e){return function(t){const n=function*(){let A,e;for(;!(A=o(()=>t.next(n.hurry))).done;)yield e=A.value;return e<1&&(yield 1),n.bytes=(r((s=A.value).length),s);var s}();return n.bytes=null,n.hurry=!1,n}(nt(t,n,A,e))}const it={channel:null,weighted:null,fill:null},ct=Object.freeze({bytes:16777216,pixels:24e6,edge:16384}),lt=[1];for(let t=1;t<=32;t++)lt.push(2*lt[t-1]);class ft{constructor(t=4096){this.bytes=new Uint8Array(t),this.at=0,this.gt=0,this.pending=0}write(t,n){if(!(n>=0&&n<lt[t]))throw new Error("bit write out of range: "+t+" bits, "+n);let A=this.gt+n*(1<<this.pending),e=this.pending+t;this.at+5>=this.bytes.length&&this.grow();const r=this.bytes;for(;e>=8;)r[this.at++]=255&A,A=Math.floor(A/256),e-=8;this.gt=A,this.pending=e}t(t,n){for(let A=0;A<4;A++){const[e,r]=t[A];if(n>=r&&n-r<lt[e])return this.write(2,A),void(e&&this.write(e,n-r))}throw new Error("U32 value out of range: "+n)}A(){this.pending&&(this.at+1>=this.bytes.length&&this.grow(),this.bytes[this.at++]=this.gt,this.gt=0,this.pending=0)}get nt(){return 8*this.at+this.pending}grow(t=0){const n=ct.bytes+64;if(this.at+t+16>n)throw Object.assign(new Error("The encoded picture exceeds 16 MiB."),{code:"JXL_SIZE"});const A=new Uint8Array(Math.min(n,Math.max(2*this.bytes.length,this.at+t+16)));A.set(this.bytes.subarray(0,this.at)),this.bytes=A}append(t){if(this.at+t.at+8>=this.bytes.length&&this.grow(t.at+8),this.pending)for(let n=0;n<t.at;n++)this.write(8,t.bytes[n]);else this.bytes.set(t.bytes.subarray(0,t.at),this.at),this.at+=t.at;t.pending&&this.write(t.pending,t.gt)}finish(){const t=this.at+(this.pending?1:0),n=this.bytes.slice(0,t);return this.pending&&(n[this.at]=this.gt),n}}const at=(t,n)=>"number"==typeof t?n(t):{...t,at:A=>n(t.at(A))},gt="AGFzbQEAAAABFAJgBn9/f39/fwBgB39/f39/f38AAhEBA2VudgZtZW1vcnkCAQGAAQMDAgABBxMCCHJlc2lkdWFsAAAEZmlsbAABCpYIAtUEAgV7CH8gAUECdCENA0BBACELA0ACQCAMQQBHIAtBAEdxIAtBBGogAU0gA0EDRiADQQVGcnFxBEAgAEEEa/0ABAAhBiAAIA1r/QAEACEHIAYgB/2uASEKIANBA0YEQCAKIApBH/2sAUEB/RH9Tv2uAUEB/awBIQkFIAAgDWtBBGv9AAQAIQggBiAH/bYBIAYgB/24ASAKIAj9sQH9tgH9uAEhCQsgAP0ABAAgCf2xASAE/RH9sQEhCSAFIAlBAf2rASAJQR/9rAH9Uf0LBAAgAEEQaiEAIAVBEGohBSALQQRqIQsMAQtBACESIAMEQCALBH8gAEEEaygCAAUgDAR/IAAgDWsoAgAFQQALCyEOIAwEfyAAIA1rKAIABSAOCyEPIAtBAEcgDEEAR3EEfyAAIA1rQQRrKAIABSAOCyEQIA4gD2ogEGshESADQQFGBEAgDiESCyADQQJGBEAgDyESCyADQQNGBEAgDiAPakECbSESCyADQQRGBEAgDiAPIBEgDmsgESAOa0EfdXMgESAOa0EfdWsgESAPayARIA9rQR91cyARIA9rQR91a0gbIRILIANBBUYEQCAOIA8gDiAPSBsgDiAPIA4gD0obIBEgDiAPIA4gD0obIBFIGyAOIA8gDiAPSBsgDiAPIA4gD0obIBEgDiAPIA4gD0obIBFIG0obIRILCyAFIAAoAgAgEmsgBGtBAXQgACgCACASayAEa0EfdXM2AgAgBUEEaiEFIABBBGohACALQQFqIQsLIAsgAUkNAAsgDEEBaiEMIAwgAkkNAAsLvAMCB3sIfwJAA0AgFUEEaiABSw0BIAD9AAQAIQcgB0H/Af0R/U4hCCACQQNPBEAgB0EI/a0BQf8B/RH9TiEJIAdBEP2tAUH/Af0R/U4hCiAIIAr9sQEhCyAKIAtBAf2sAf2uASENIAkgDf2xASEMIAMgDSAMQQH9rAH9rgH9CwQAIAQgC/0LBAAgBSAM/QsEACACQQRGBEAgBiAHQRj9rQH9CwQACwUgAyAI/QsEACACQQJGBEAgBCAHQRj9rQH9CwQACwsgA0EQaiEDIARBEGohBCAFQRBqIQUgBkEQaiEGIABBEGohACAVQQRqIRUMAAsLAkADQCAVIAFPDQEgACgCACEOIA5B/wFxIQ8gAkEDTwRAIA5BCHZB/wFxIRAgDkEQdkH/AXEhESAPIBFrIRIgESASQQF1aiEUIBAgFGshEyADIBQgE0EBdWo2AgAgBCASNgIAIAUgEzYCACACQQRGBEAgBiAOQRh2NgIACwUgAyAPNgIAIAJBAkYEQCAEIA5BGHY2AgALCyADQQRqIQMgBEEEaiEEIAVBBGohBSAGQQRqIQYgAEEEaiEAIBVBAWohFSAVIAFJDQALCws=",{configureKernels:It,kernelMode:Bt}=(()=>{function t(t,n,A,e,r=C,s=0){const{scalar:i,i32:f,u8:a}=B,I=s||g;if(!Q(t)||!n.length||n.length>34)return!1;if(t){f.fill(0,410624,410624+n.length*g*2);for(let t=0;t<n.length;t++){const A=n[t];if(!A?.M||!A?.S||A.M.length>g)return!1;for(let n=0;n<A.M.length;n++)f[410624+2*(t*g+n)]=A.M[n],f[410624+2*(t*g+n)+1]=A.S[n]}}else for(let t=0;t<n.length;t++){if(!(n[t]instanceof Uint32Array)||n[t].length!==I)return!1;f.set(n[t],410624+t*I)}const u=i.It(o,e,A,l,c,t?1:0,t?t.gt:0,t?t.pending:0,r.split,r.R,r.G,s);if(t)t.at+u+8>=t.bytes.length&&t.grow(u+8),t.bytes.set(a.subarray(c,c+u),t.at),t.at+=u,t.gt=f[278530],t.pending=f[278531];else for(let t=0;t<n.length;t++)n[t].set(f.subarray(410624+t*I,410624+(t+1)*I));return!0}function n(n,A,e,s,i,c,l){const f=c.config||C;if(!h(e,s,i,c.offset)||1!==c.L||!Number.isInteger(c.H)||c.H<0||c.H>5||!Q(n)||(a=f,!(Number.isInteger(a.split)&&Number.isInteger(a.R)&&Number.isInteger(a.G)&&a.split>=0&&a.split<=15&&a.R>=0&&a.G>=0&&a.R+a.G<=a.split&&(1<<a.split)+(19-a.split<<a.R+a.G)<=224)))return!1;var a;if(l&&(n||!(A instanceof Uint32Array)||A.length<34||A.length>4129))return!1;const g=s*i;return!(n&&n.at+8*g+32>ct.bytes)&&(B.i32.set(e.subarray(0,g),r>>2),("simd"===u?B.simd:B.scalar).st(r,s,i,c.H,c.offset,o),t(n,[A],g,0,f,l?A.length:0))}function A(n,A,e,c,l,f,g,I,u){if(!h(e,c,l,f)||!Q(n))return!1;const E=c*l,{i32:C,scalar:y}=B;return!(n&&n.at+8*E+32>ct.bytes)&&(!I||I instanceof Uint32Array&&!(I.length<E))&&(!u||u instanceof Int32Array&&!(u.length<E))&&34===g.length&&!g.some(t=>!Number.isInteger(t)||t<0||t>=34)&&!(!I&&g.some(t=>t>=A.length))&&(C.set(e.subarray(0,E),r>>2),C.set(g,5168),C.fill(0,524288,524288+10*(c+2)),y.weighted(r,c,l,f,o,s,i,20672,16656,16,272,a),I?(I.set(C.subarray(o>>2,(o>>2)+E)),u&&u.set(C.subarray(147456,147456+E)),!0):(u&&u.set(C.subarray(147456,147456+E)),t(n,A,E,i)))}function e(t,n,A,e,c,l,a,g){const I=c*l;if(I<1||I>65536||a<1||a>4)return!1;const{u8:E,i32:h}=B;for(let r=0;r<l;r++){const o=4*((e+r)*n+A);E.set(t.subarray(o,o+4*c),f+r*c*4)}("simd"===u?B.simd:B.scalar).fill(f,I,a,r,o,s,i);for(let t=0;t<a;t++){const n=[r,o,s,i][t]>>2;g[t].set(h.subarray(n,n+I))}return!0}const r=65536,o=327680,s=589824,i=851968,c=1114128,l=1642496,f=1769472,a=2097152,g=257,I=[-500,-392,-255,-191,-127,-95,-63,-47,-31,-23,-15,-11,-7,-4,-3,-1,0,1,3,5,7,11,15,23,31,47,63,95,127,191,255,392,500];let B,u="off";const E=t=>Uint8Array.from(atob(t),t=>t.charCodeAt(0)),h=(t,n,A,e)=>t instanceof Int16Array&&Number.isInteger(n)&&Number.isInteger(A)&&n>0&&A>0&&n<=16384&&n*A<=65536&&t.length>=n*A&&Number.isInteger(e)&&Math.abs(e)<=32768,Q=t=>!t||t instanceof ft&&t.write===ft.prototype.write&&t.grow===ft.prototype.grow,C={split:0,R:0,G:0};return{configureKernels:function(t="auto",r){if(!["off","auto","scalar","simd"].includes(t))throw new RangeError("Unknown JXL kernel mode: "+t);if(it.channel=it.weighted=it.fill=null,u="off","off"===t)return u;try{if("object"!=typeof WebAssembly||!WebAssembly.validate||1!==new Uint8Array(new Uint32Array([1]).buffer)[0])return u;const o="scalar"!==t&>&&WebAssembly.validate(E("AGFzbQEAAAABBQFgAAF/AwIBAAcJAQVwcm9iZQAACgsBCQBBAP0R/RsACw=="));if("scalar"!==t&&!o)return u;if(B||=function(){const t=new WebAssembly.Memory({initial:48,maximum:128}),n=new Map(Object.entries(new WebAssembly.Instance(new WebAssembly.Module(E("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")),{env:{memory:t}}).exports)),A={st:n.get("residual"),It:n.get("tokens"),fill:n.get("fill"),weighted:n.get("weighted")},e=new Uint8Array(t.buffer),r=new Int32Array(t.buffer);for(let t=0;t<64;t++)r[4+t]=Math.floor(16777216/(t+1));for(let t=12;t<=13;t++)for(let n=0;n<2048;n++){const A=Math.max(0,26-Math.clz32(n+1));r[68+2048*(t-12)+n]=4+(t*r[4+(n>>A)]>>A)}for(let t=0;t<1003;t++)r[4164+t]=I.filter(n=>n<t-501).length;return{memory:t,scalar:A,simd:null,u8:e,i32:r}}(),o&&!B.simd){const t=new Map(Object.entries(new WebAssembly.Instance(new WebAssembly.Module(E(gt)),{env:{memory:B.memory}}).exports));B.simd={st:t.get("residual"),fill:t.get("fill")}}u=o?"simd":"scalar";const s=r?new Map(Object.entries(r)):null;s&&!s.get("channel")||(it.channel=n),s&&!s.get("weighted")||(it.weighted=A),s&&!s.get("fill")||(it.fill=e)}catch{u="off",it.channel=it.weighted=it.fill=null}return u},kernelMode:function(){return u}}})(),ut=(t,n)=>Object.assign(new Error(n),{code:t}),Et=256,ht=[1,2,3,4,0,5,17,6,16,7,8,9,10,11,12,13,14,15],Qt=[2,4,3,2,2,4],Ct=[0,7,3,2,1,15],yt=[0,0,0],wt=3,pt=5,dt=y(4),Mt=Object.freeze({J:224,minLength:7,F:dt}),St=y(0),Dt=257,Ut=[y(0),y(4),y(4,1,1),y(3,0,1)],bt=(t,n,A,e)=>A?e?t[n]+256*t[n+3]:t[n]:t[n]+256*t[n+1]+65536*t[n+2]+(e?16777216*t[n+3]:0),Rt=(t,n)=>t+n+(t>n?1:0)>>1,Gt=1024,mt=8192,qt=[-500,-392,-255,-191,-127,-95,-63,-47,-31,-23,-15,-11,-7,-4,-3,-1,0,1,3,5,7,11,15,23,31,47,63,95,127,191,255,392,500],kt=Int8Array.from({length:1003},(t,n)=>qt.filter(t=>t<n-501).length),Nt=Int32Array.from({length:64},(t,n)=>Math.floor(16777216/(n+1))),Jt=(t,n)=>{const A=Math.max(0,26-Math.clz32(t+1));return 4+(n*Nt[t>>A]>>A)},Ft=[12,13].map(t=>Int32Array.from({length:2048},(n,A)=>Jt(A,t))),Ht=(t,n)=>t<2048?Ft[n-12][t]:Jt(t,n),Lt=new Int32Array(qt.length+1);let Kt;const xt=t=>Math.max(0,t<224?t-1:t-236),vt=t=>{const n=Q(t),A=new ft(128);C(A,n);let e=A.nt;for(let A=0;A<t.length;A++)t[A]&&(e+=t[A]*(n.M[A]+xt(A)));return e},Wt=[-127,-31,-7,-1,0,1,7,31,127],Pt=[-191,-127,-63,-31,-7,-1,0,7,31,63,127,191,255],Yt=t=>null===t||("object"==typeof t?t.hurried:t),Xt=t=>Math.max(0,t<224?t-1:t-236),Vt=t=>{const n=new Uint32Array(Dt);for(const A of t)for(let t=0;t<Dt;t++)n[t]+=A[t];return n},Tt=qt.length+1,Zt=Int32Array.from({length:Tt},(t,n)=>n);It("auto");export{ct as LIMITS,It as configureKernels,ot as encode,st as encodeSteps,Bt as kernelMode};
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
// Build-time only.
|
|
3
|
-
//
|
|
2
|
+
// Build-time only: regenerates kernels-bytes.mjs from the kernels-*.wat sources. Needs wabt@1.0.37
|
|
3
|
+
// (npm install --no-save wabt@1.0.37, or set WABT_MODULE to its index.js). Run with node; --check compares without writing.
|
|
4
4
|
import {readFile, writeFile} from 'node:fs/promises';
|
|
5
5
|
import {fileURLToPath, pathToFileURL} from 'node:url';
|
|
6
6
|
import {resolve} from 'node:path';
|
|
7
7
|
import {existsSync} from 'node:fs';
|
|
8
|
-
|
|
8
|
+
// Beside the module directory in the workstation, beside the build script and the source directory in the package.
|
|
9
|
+
const here = new URL('./', import.meta.url), flat = existsSync(new URL('jxl/kernels-scalar.wat', here));
|
|
10
|
+
const directory = flat ? new URL('jxl/', here) : here;
|
|
9
11
|
const specifier = process.env.WABT_MODULE ? pathToFileURL(resolve(process.env.WABT_MODULE)).href : 'wabt';
|
|
10
12
|
let factory;
|
|
11
13
|
try { ({default: factory} = await import(specifier)); }
|
|
@@ -23,7 +25,7 @@ for (const [name, symbol] of [['scalar','SCALAR'], ['simd','SIMD'], ['probe','SI
|
|
|
23
25
|
console.log(`${name}: ${buffer.length} WebAssembly bytes`);
|
|
24
26
|
} finally { wat.destroy(); }
|
|
25
27
|
}
|
|
26
|
-
const target = new URL('kernels-bytes.mjs',
|
|
28
|
+
const target = new URL(flat ? 'jxl/kernels-bytes.mjs' : '../src/kernels-bytes.mjs', here);
|
|
27
29
|
if (process.argv.includes('--check')) {
|
|
28
30
|
if (text !== await readFile(target, 'utf8')) throw new Error('kernels-bytes.mjs differs from the WAT build');
|
|
29
31
|
} else await writeFile(target, text);
|
package/package.json
CHANGED
|
@@ -1,69 +1,62 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rapier-jxl",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.1",
|
|
4
4
|
"description": "A JPEG XL encoder in pure JavaScript for the browser, workers, Node and Deno: lossless and lossy, the core one file of 21.3 kB (9.3 kB gzipped); photographs and JPEGs are optional doors. Optional inlined WebAssembly SIMD kernels; no runtime dependencies.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
|
-
"main": "./index.mjs",
|
|
8
|
-
"types": "./index.d.mts",
|
|
7
|
+
"main": "./src/index.mjs",
|
|
8
|
+
"types": "./src/index.d.mts",
|
|
9
9
|
"exports": {
|
|
10
10
|
".": {
|
|
11
|
-
"types": "./index.d.mts",
|
|
12
|
-
"default": "./index.mjs"
|
|
11
|
+
"types": "./src/index.d.mts",
|
|
12
|
+
"default": "./src/index.mjs"
|
|
13
13
|
},
|
|
14
14
|
"./min": {
|
|
15
|
-
"types": "./index.d.mts",
|
|
16
|
-
"default": "./rapier-jxl.min.mjs"
|
|
15
|
+
"types": "./src/index.d.mts",
|
|
16
|
+
"default": "./dist/rapier-jxl.min.mjs"
|
|
17
17
|
},
|
|
18
18
|
"./jpeg": {
|
|
19
|
-
"types": "./jpeg.d.mts",
|
|
20
|
-
"default": "./jpeg.mjs"
|
|
19
|
+
"types": "./src/jpeg.d.mts",
|
|
20
|
+
"default": "./src/jpeg.mjs"
|
|
21
21
|
},
|
|
22
22
|
"./photo": {
|
|
23
|
-
"types": "./photo.d.mts",
|
|
24
|
-
"default": "./photo.mjs"
|
|
23
|
+
"types": "./src/photo.d.mts",
|
|
24
|
+
"default": "./src/photo.mjs"
|
|
25
25
|
},
|
|
26
26
|
"./jpeg-ans": {
|
|
27
|
-
"types": "./jpeg-ans.d.mts",
|
|
28
|
-
"default": "./jpeg-ans.mjs"
|
|
27
|
+
"types": "./src/jpeg-ans.d.mts",
|
|
28
|
+
"default": "./src/jpeg-ans.mjs"
|
|
29
29
|
},
|
|
30
30
|
"./photo-ans": {
|
|
31
|
-
"types": "./photo-ans.d.mts",
|
|
32
|
-
"default": "./photo-ans.mjs"
|
|
31
|
+
"types": "./src/photo-ans.d.mts",
|
|
32
|
+
"default": "./src/photo-ans.mjs"
|
|
33
33
|
},
|
|
34
34
|
"./effort": {
|
|
35
|
-
"types": "./effort.d.mts",
|
|
36
|
-
"default": "./effort.mjs"
|
|
35
|
+
"types": "./src/effort.d.mts",
|
|
36
|
+
"default": "./src/effort.mjs"
|
|
37
37
|
},
|
|
38
|
-
"./writer": "./writer.mjs",
|
|
38
|
+
"./writer": "./src/writer.mjs",
|
|
39
39
|
"./package.json": "./package.json",
|
|
40
40
|
"./kernels": {
|
|
41
|
-
"types": "./kernel-control.d.mts",
|
|
42
|
-
"default": "./kernels.mjs"
|
|
41
|
+
"types": "./src/kernel-control.d.mts",
|
|
42
|
+
"default": "./src/kernels.mjs"
|
|
43
43
|
},
|
|
44
44
|
"./wasm": {
|
|
45
|
-
"types": "./wasm.d.mts",
|
|
46
|
-
"default": "./wasm.mjs"
|
|
45
|
+
"types": "./src/wasm.d.mts",
|
|
46
|
+
"default": "./src/wasm.mjs"
|
|
47
47
|
}
|
|
48
48
|
},
|
|
49
49
|
"files": [
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
-
"
|
|
53
|
-
"KERNELS.md",
|
|
54
|
-
"README.md",
|
|
55
|
-
"AGENTS.md",
|
|
56
|
-
"ENCODER-COMPARISON.md",
|
|
50
|
+
"src",
|
|
51
|
+
"dist",
|
|
52
|
+
"kernels",
|
|
57
53
|
"LICENSE",
|
|
58
|
-
"
|
|
59
|
-
"
|
|
60
|
-
"public/encoder-sizes.json",
|
|
61
|
-
"public/measure-encoders.mjs",
|
|
62
|
-
"public/examples"
|
|
54
|
+
"README.md",
|
|
55
|
+
"AGENTS.md"
|
|
63
56
|
],
|
|
64
57
|
"sideEffects": [
|
|
65
|
-
"./wasm.mjs",
|
|
66
|
-
"./wasm.min.mjs"
|
|
58
|
+
"./src/wasm.mjs",
|
|
59
|
+
"./dist/wasm.min.mjs"
|
|
67
60
|
],
|
|
68
61
|
"engines": {
|
|
69
62
|
"node": ">=18"
|
|
@@ -93,9 +86,9 @@
|
|
|
93
86
|
"rapier"
|
|
94
87
|
],
|
|
95
88
|
"scripts": {
|
|
96
|
-
"test": "node --test \"
|
|
97
|
-
"fuzz:scale": "node
|
|
98
|
-
"build:kernels": "node build
|
|
89
|
+
"test": "node --test \"test/*.test.mjs\"",
|
|
90
|
+
"fuzz:scale": "node test/fuzz-shards.mjs",
|
|
91
|
+
"build:kernels": "node kernels/build.mjs"
|
|
99
92
|
},
|
|
100
93
|
"devDependencies": {
|
|
101
94
|
"jxl-oxide-wasm": "0.12.6",
|
package/ENCODER-COMPARISON.md
DELETED
|
@@ -1,185 +0,0 @@
|
|
|
1
|
-
# Encoder payloads measured on 30 September 2026
|
|
2
|
-
|
|
3
|
-
Rapier JXL is the smallest JavaScript or WebAssembly JPEG XL encoder among the published payloads measured here.
|
|
4
|
-
A bounded survey, not proof of a global minimum; the encoders differ in what they cover.
|
|
5
|
-
|
|
6
|
-
| Encoder / entry | Version | Minified JS + WASM bytes | gzip bytes | Included capability |
|
|
7
|
-
| --- | --- | ---: | ---: | --- |
|
|
8
|
-
| Rapier JXL core | 2.2.0 | 21,326 | 9,271 | 8-bit lossless RGBA, lossy modular with exact alpha |
|
|
9
|
-
| Rapier JXL effort door | 2.2.0 | 33,584 | 13,793 | The core, and the weighted predictor searched for lossless |
|
|
10
|
-
| Rapier JXL JPEG door | 2.2.0 | 32,354 | 13,505 | JPEG coefficients, orientation; no JPEG reconstruction |
|
|
11
|
-
| Rapier JXL photo door | 2.2.0 | 33,011 | 13,616 | 8-bit photographic VarDCT, exact alpha; q100 lossless |
|
|
12
|
-
| [jSquash](https://github.com/jamsinclair/jSquash/tree/main/packages/jxl) | 1.3.0 | 1,388,572 | 525,782 | 8-bit lossless/lossy RGBA |
|
|
13
|
-
| [Discourse's jSquash package](https://www.npmjs.com/package/@discourse/jxl) | 1.3.0 | 1,388,572 | 525,782 | The same encoder bytes as jSquash |
|
|
14
|
-
| [Lacinak's jSquash fork](https://github.com/kelaci/jSquash) | 1.3.0-kelaci.0 | 2,071,514 | 844,866 | High bit-depth input options |
|
|
15
|
-
| [squoosh-kit](https://github.com/bnowak008/squoosh-kit/tree/main/packages/jxl) | 0.2.10 | 1,371,789 | 511,927 | 8-bit lossless/lossy RGBA |
|
|
16
|
-
| [icodec](https://github.com/Kaciras/icodec) | 0.6.0 | 2,474,954 | 900,957 | 8 to 16-bit lossless/lossy pixels |
|
|
17
|
-
| [Cornerstone libjxl](https://github.com/cornerstonejs/codecs/tree/main/packages/libjxl) | 1.1.1 | 2,575,008 | 936,242 | 1 to 16-bit grayscale/RGB; DICOM-oriented API |
|
|
18
|
-
| [jxl-wasm](https://github.com/saschanaz/jxl-wasm) | 0.7.0 | 2,533,758 | 961,538 | libjxl CLI, pixels and reversible JPEG |
|
|
19
|
-
| [jpeg-to-jxl](https://github.com/ChefJulio/jpeg-to-jxl) | 0.2.0 | 2,732,858 | 1,063,406 | Reversible JPEG recompression, with decode |
|
|
20
|
-
| [Squoosh library](https://github.com/GoogleChromeLabs/squoosh/tree/dev/libsquoosh) | 0.5.3 | 1,615,596 | 539,210 | Shared multi-codec JavaScript and one JXL encoder WASM |
|
|
21
|
-
|
|
22
|
-
Bytes are decimal. JavaScript is minified with Terser 5.51.2 (two compress passes, mangling, licence comments
|
|
23
|
-
kept), WASM is unchanged, each resource is gzipped alone at level 9, then summed: delivery bytes, not tarball
|
|
24
|
-
sizes. Every file, URL, npm integrity and SHA-256 is in [`public/encoder-sizes.json`](public/encoder-sizes.json).
|
|
25
|
-
The jSquash, fork, squoosh-kit and icodec rows count the encoder factory and its WASM only, without wrappers,
|
|
26
|
-
workers or decoders, which favours them. Size says nothing about correctness or compression quality.
|
|
27
|
-
|
|
28
|
-
## Reproduce
|
|
29
|
-
|
|
30
|
-
```sh
|
|
31
|
-
npm install --ignore-scripts
|
|
32
|
-
node public/measure-encoders.mjs .encoder-size-cache encoder-sizes.json
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
The script fetches the pinned npm archives in `public/encoders.json`, checks their integrity, reads the listed
|
|
36
|
-
members in memory and minifies them. It never runs downloaded code. Rapier's own bytes come from its stager.
|
|
37
|
-
|
|
38
|
-
## Quality at matched bytes, 30 September 2026
|
|
39
|
-
|
|
40
|
-
A small encoder does not mean small or good pictures. This measures Rapier's readable source against the
|
|
41
|
-
[libjxl v0.12.0 reference](https://github.com/libjxl/libjxl/releases/tag/v0.12.0) (`cjxl`, `djxl` and
|
|
42
|
-
`butteraugli_main` from the official Linux x86-64 static archive, SHA-256
|
|
43
|
-
`5318a1ea40adad76d023e0c17a03d4627f8282f83cb2b575e69be8e74f1ff456`) on eleven inputs: four synthetic
|
|
44
|
-
textures, the bundled Grace Hopper JPEG, three generated drawings and three generated paintings. It is not a
|
|
45
|
-
representative collection. Each Rapier stream sets a byte budget; the native encoder, at effort 7 with its mode
|
|
46
|
-
left to `cjxl`, is searched over distances for the largest stream within that budget (a gap of at most 0.5%
|
|
47
|
-
counts as matched). Where native distance 0 already fits, the row is marked **†**: an exact stream in fewer
|
|
48
|
-
bytes, not a match. Both outputs are decoded by the same pinned `djxl` to 8-bit sRGB; alpha is byte-exact in
|
|
49
|
-
every selected decode. PSNR and RGB SSIM are computed over the three RGB channels (single-scale SSIM, 11 × 11
|
|
50
|
-
Gaussian, no downsampling); alpha-bearing inputs are matted on white for the table. Butteraugli is the
|
|
51
|
-
reference tool at 80 nits, the worse of the white and black mattes for alpha inputs. Higher PSNR and SSIM and
|
|
52
|
-
lower Butteraugli are that metric's preference, not a human verdict. **R / N** is Rapier / native.
|
|
53
|
-
|
|
54
|
-
### The photo door
|
|
55
|
-
|
|
56
|
-
Native is within 0.402% of the budget in all 20 rows, and better on PSNR and SSIM in 19 of 20 and on
|
|
57
|
-
Butteraugli in 19 of 20; the exceptions are Grace q99 (Rapier's PSNR and SSIM) and lit surface q99 (Rapier's
|
|
58
|
-
Butteraugli).
|
|
59
|
-
|
|
60
|
-
| Input · Rapier q | Rapier bytes | Native bytes | Native d | PSNR dB R / N ↑ | RGB SSIM R / N ↑ | Butteraugli R / N ↓ |
|
|
61
|
-
| --- | ---: | ---: | ---: | ---: | ---: | ---: |
|
|
62
|
-
| Wood grain · 50 | 6,351 | 6,335 | 5.061 | 33.459 / 37.501 | 0.833394 / 0.920358 | 7.9959 / 3.8476 |
|
|
63
|
-
| Wood grain · 80 | 11,640 | 11,632 | 2.246 | 36.866 / 39.628 | 0.900685 / 0.942440 | 4.0035 / 1.8251 |
|
|
64
|
-
| Wood grain · 90 | 18,713 | 18,713 | 1.226 | 38.910 / 40.727 | 0.929675 / 0.953458 | 2.3318 / 1.5172 |
|
|
65
|
-
| Wood grain · 99 | 76,863 | 76,842 | 0.327 | 45.530 / 47.954 | 0.983684 / 0.991316 | 0.9762 / 0.6128 |
|
|
66
|
-
| Landscape · 50 | 4,729 | 4,710 | 4.944 | 34.594 / 38.053 | 0.852275 / 0.908469 | 8.5642 / 3.4545 |
|
|
67
|
-
| Landscape · 80 | 7,932 | 7,921 | 2.438 | 37.305 / 39.502 | 0.891356 / 0.921732 | 4.1410 / 2.1015 |
|
|
68
|
-
| Landscape · 90 | 12,725 | 12,723 | 1.508 | 39.050 / 40.389 | 0.912417 / 0.931579 | 3.1272 / 1.6892 |
|
|
69
|
-
| Landscape · 99 | 64,221 | 64,192 | 0.377 | 45.545 / 47.492 | 0.977931 / 0.986445 | 1.0067 / 0.6164 |
|
|
70
|
-
| Folded texture · 50 | 3,563 | 3,552 | 5.427 | 35.334 / 38.643 | 0.839685 / 0.908679 | 7.2341 / 4.0082 |
|
|
71
|
-
| Folded texture · 80 | 6,525 | 6,514 | 2.468 | 38.175 / 40.176 | 0.894762 / 0.927122 | 3.6812 / 2.2637 |
|
|
72
|
-
| Folded texture · 90 | 10,046 | 10,046 | 1.668 | 39.618 / 40.820 | 0.917830 / 0.934923 | 2.2918 / 1.6726 |
|
|
73
|
-
| Folded texture · 99 | 57,111 | 57,111 | 0.412 | 45.611 / 47.539 | 0.979148 / 0.986739 | 0.9172 / 0.7164 |
|
|
74
|
-
| Lit surface · 50 | 2,825 | 2,825 | 2.909 | 38.241 / 40.292 | 0.891825 / 0.915090 | 4.4182 / 2.4656 |
|
|
75
|
-
| Lit surface · 80 | 4,107 | 4,107 | 2.314 | 39.474 / 40.530 | 0.903290 / 0.918372 | 3.1575 / 2.1072 |
|
|
76
|
-
| Lit surface · 90 | 5,465 | 5,453 | 1.988 | 40.214 / 40.738 | 0.912497 / 0.921402 | 2.2827 / 1.9999 |
|
|
77
|
-
| Lit surface · 99 | 47,155 | 47,152 | 0.466 | 45.664 / 46.636 | 0.975682 / 0.980349 | 0.9476 / 1.1255 |
|
|
78
|
-
| Grace Hopper · 50 | 15,990 | 15,982 | 5.451 | 29.546 / 30.676 | 0.778970 / 0.807254 | 6.6973 / 4.5990 |
|
|
79
|
-
| Grace Hopper · 80 | 34,419 | 34,409 | 2.338 | 33.675 / 34.477 | 0.862229 / 0.899859 | 3.8410 / 3.0344 |
|
|
80
|
-
| Grace Hopper · 90 | 56,543 | 56,519 | 1.110 | 38.605 / 38.944 | 0.950222 / 0.970007 | 2.3300 / 1.4546 |
|
|
81
|
-
| Grace Hopper · 99 | 110,542 | 110,533 | 0.173 | 49.948 / 47.182 | 0.996348 / 0.995977 | 0.4889 / 0.3406 |
|
|
82
|
-
|
|
83
|
-
### The core's lossy modular on drawings and paintings
|
|
84
|
-
|
|
85
|
-
Fourteen rows are matched within 0.127%. In the ten **†** rows an exact native stream fits in 3.052% to
|
|
86
|
-
51.144% fewer bytes. Native SSIM and Butteraugli are better in all 24 rows; PSNR favours Rapier for paint-0001
|
|
87
|
-
and paint-0002 at q80 and q90.
|
|
88
|
-
|
|
89
|
-
| Input · Rapier q | Rapier bytes | Native bytes | Native d | PSNR dB R / N ↑ | RGB SSIM R / N ↑ | Butteraugli R / N ↓ |
|
|
90
|
-
| --- | ---: | ---: | ---: | ---: | ---: | ---: |
|
|
91
|
-
| recipe-0000 · 50 | 14,972 | 14,953 | 1.102 | 37.276 / 45.992 | 0.989901 / 0.996956 | 3.9870 / 1.0352 |
|
|
92
|
-
| recipe-0000 · 80 | 20,051 | 19,439† | 0 | 42.493 / ∞ | 0.995389 / 1.000000 | 2.6508 / 0.0000 |
|
|
93
|
-
| recipe-0000 · 90 | 25,232 | 19,439† | 0 | 46.614 / ∞ | 0.997777 / 1.000000 | 1.4840 / 0.0000 |
|
|
94
|
-
| recipe-0000 · 99 | 39,788 | 19,439† | 0 | 58.188 / ∞ | 0.999803 / 1.000000 | 0.5505 / 0.0000 |
|
|
95
|
-
| recipe-0001 · 50 | 31,284 | 31,279 | 1.642 | 44.663 / 51.571 | 0.998111 / 0.999252 | 3.6761 / 0.9379 |
|
|
96
|
-
| recipe-0001 · 80 | 37,226 | 35,491† | 0 | 49.928 / ∞ | 0.999293 / 1.000000 | 2.1718 / 0.0000 |
|
|
97
|
-
| recipe-0001 · 90 | 43,439 | 35,491† | 0 | 53.998 / ∞ | 0.999699 / 1.000000 | 0.7681 / 0.0000 |
|
|
98
|
-
| recipe-0001 · 99 | 60,225 | 35,491† | 0 | 63.163 / ∞ | 0.999953 / 1.000000 | 0.2608 / 0.0000 |
|
|
99
|
-
| recipe-0002 · 50 | 18,746 | 18,736 | 1.651 | 34.484 / 40.065 | 0.978619 / 0.992176 | 5.0667 / 1.4144 |
|
|
100
|
-
| recipe-0002 · 80 | 27,036 | 27,025 | 0.749 | 39.856 / 43.976 | 0.990765 / 0.995802 | 2.5048 / 1.0876 |
|
|
101
|
-
| recipe-0002 · 90 | 35,330 | 35,306 | 0.425 | 44.044 / 46.482 | 0.995583 / 0.997393 | 1.7128 / 0.6129 |
|
|
102
|
-
| recipe-0002 · 99 | 59,624 | 36,102† | 0 | 55.523 / ∞ | 0.999602 / 1.000000 | 0.5762 / 0.0000 |
|
|
103
|
-
| paint-0000 · 50 | 45,505 | 45,498 | 1.336 | 36.020 / 40.143 | 0.975668 / 0.991663 | 4.7640 / 1.5576 |
|
|
104
|
-
| paint-0000 · 80 | 54,652 | 54,618 | 0.684 | 39.900 / 43.518 | 0.988270 / 0.995770 | 2.7126 / 0.9569 |
|
|
105
|
-
| paint-0000 · 90 | 65,877 | 65,843 | 0.289 | 43.809 / 47.922 | 0.994447 / 0.998212 | 1.5637 / 0.6630 |
|
|
106
|
-
| paint-0000 · 99 | 97,769 | 74,658† | 0 | 54.474 / ∞ | 0.999312 / 1.000000 | 0.5388 / 0.0000 |
|
|
107
|
-
| paint-0001 · 50 | 61,462 | 61,442 | 1.680 | 33.606 / 34.830 | 0.956089 / 0.972432 | 7.1021 / 1.8314 |
|
|
108
|
-
| paint-0001 · 80 | 75,929 | 75,926 | 0.830 | 37.751 / 37.312 | 0.980393 / 0.982498 | 3.5325 / 1.1308 |
|
|
109
|
-
| paint-0001 · 90 | 93,451 | 93,451 | 0.343 | 41.285 / 40.730 | 0.990186 / 0.990973 | 1.9406 / 0.8474 |
|
|
110
|
-
| paint-0001 · 99 | 143,736 | 124,100† | 0 | 51.793 / ∞ | 0.998622 / 1.000000 | 0.6179 / 0.0000 |
|
|
111
|
-
| paint-0002 · 50 | 81,312 | 81,304 | 2.020 | 32.334 / 34.083 | 0.937986 / 0.962754 | 5.7590 / 2.1400 |
|
|
112
|
-
| paint-0002 · 80 | 98,676 | 98,622 | 1.055 | 36.749 / 36.598 | 0.972358 / 0.976745 | 3.1658 / 1.3790 |
|
|
113
|
-
| paint-0002 · 90 | 119,652 | 119,651 | 0.472 | 40.420 / 39.711 | 0.986313 / 0.987143 | 1.8052 / 1.1247 |
|
|
114
|
-
| paint-0002 · 99 | 187,934 | 170,069† | 0 | 50.304 / ∞ | 0.997853 / 1.000000 | 0.5696 / 0.0000 |
|
|
115
|
-
|
|
116
|
-
### The JPEG carrier against reversible recompression
|
|
117
|
-
|
|
118
|
-
`transcode` against `cjxl --lossless_jpeg=1`. The contracts differ: Rapier carries the coefficients and the
|
|
119
|
-
orientation and cannot rebuild the JPEG file; native also stores the reconstruction data and rebuilt every
|
|
120
|
-
accepted original exactly. So a smaller Rapier row is not a like-for-like win. Seven inputs are tiny conformance fixtures;
|
|
121
|
-
Grace is the one photograph.
|
|
122
|
-
|
|
123
|
-
| JPEG input | Original bytes | Rapier carrier | Native reversible | JPEG rebuilt by native |
|
|
124
|
-
| --- | ---: | ---: | ---: | --- |
|
|
125
|
-
| grey-sequential.jpg | 141 | 117 | 177 | yes |
|
|
126
|
-
| quant-before-scan.jpg | 141 | 120 | 181 | yes |
|
|
127
|
-
| quant-after-scan.jpg | 210 | 120 | refused | no reconstruction data possible |
|
|
128
|
-
| colour-sequential.jpg | 925 | 499 | 662 | yes |
|
|
129
|
-
| colour-progressive-restarts.jpg | 1,367 | 464 | 820 | yes |
|
|
130
|
-
| decoder-difference.jpg | 925 | 499 | 662 | yes |
|
|
131
|
-
| reconstruction-difference.jpg | 925 | 510 | 676 | yes |
|
|
132
|
-
| grace-hopper.jpg | 86,089 | 60,543 | 58,773 | yes |
|
|
133
|
-
|
|
134
|
-
### Inputs and commands
|
|
135
|
-
|
|
136
|
-
Textures are the first four `synthetic-photo` seeds of `tools/corpus/jxl-images.mjs` at 512 × 384; drawings and
|
|
137
|
-
paintings the first three seeds of each kind at the same size, through the real Draw and Paint owners with the
|
|
138
|
-
bundled Geist fonts and pinned `@napi-rs/canvas` 0.1.100. Grace is the public-domain fixture in
|
|
139
|
-
`public/test/photo-corpus/`, decoded once with `ffmpeg -pix_fmt rgba` at its native size.
|
|
140
|
-
|
|
141
|
-
| Input | Dimensions | Seed | Pixels with alpha < 255 | RGBA SHA-256 |
|
|
142
|
-
| --- | ---: | ---: | ---: | --- |
|
|
143
|
-
| Wood grain | 512 × 384 | 3399228925 | 0 | `cfc2495231eb53c4d423ab5ea7692e3cafce6160f07cc51942b910a89d5ffab7` |
|
|
144
|
-
| Landscape | 512 × 384 | 1351084136 | 0 | `c6c33cc695b19538ec6780647e32fd4f22b24872292d22707f26ab9ad1a0cef2` |
|
|
145
|
-
| Folded texture | 512 × 384 | 3597906643 | 0 | `57a0f40e8e14eb0b9fe5286dbfec7bc7783b1e748c6888ea44791f088b0ea106` |
|
|
146
|
-
| Lit surface | 512 × 384 | 1549761854 | 0 | `d998747e1c427144424c4d59f6795f88a2d2983a341dcba54b5a6b346e4f0a0d` |
|
|
147
|
-
| Grace Hopper | 512 × 600 | — | 0 | `af6a4dc548da3797b814f4be1b4489effe658ad13ba842d839628d01ba3ee39f` |
|
|
148
|
-
| recipe-0000 | 512 × 384 | 2385324683 | 23,538 | `6d8240cac5db3c3db509125658ba32cb919537b113ae9f0877856fe6c091e67f` |
|
|
149
|
-
| recipe-0001 | 512 × 384 | 337179894 | 163,701 | `7a5acaf7274bbadfabaa351f0dd3a7931818a438424d17ae555a2c2f72338b9f` |
|
|
150
|
-
| recipe-0002 | 512 × 384 | 2584002401 | 20,928 | `08ce520f30a10897b4acbb630e8d39aeeb97d53e02b50ac721ad80260fd2484c` |
|
|
151
|
-
| paint-0000 | 512 × 384 | 744793156 | 194,804 | `ad9467838000b99434d7f7cb041111cd0bad8f64fe2511ce98d0d106ebd147a3` |
|
|
152
|
-
| paint-0001 | 512 × 384 | 2991615663 | 193,919 | `a3af498e21cade0969d0b3fa63118316a18601aa23bd1b35ffc561e70a123237` |
|
|
153
|
-
| paint-0002 | 512 × 384 | 943470874 | 191,708 | `d2c586460a91e5bcb4c213080f46e4945d674ed6920230f50b2ab396076ea3c1` |
|
|
154
|
-
|
|
155
|
-
```sh
|
|
156
|
-
cjxl INPUT.pam OUTPUT.jxl --distance=D --effort=7 --num_threads=0 \
|
|
157
|
-
--alpha_distance=0 --resampling=1 --ec_resampling=1 --keep_invisible=1 --premultiply=0 --container=0 \
|
|
158
|
-
-x color_space=RGB_D65_SRG_Per_SRG --quiet
|
|
159
|
-
djxl INPUT.jxl OUTPUT.pam --bits_per_sample=8 --color_space=RGB_D65_SRG_Per_SRG --num_threads=0 --quiet
|
|
160
|
-
butteraugli_main REFERENCE.ppm DECODED.ppm --intensity_target 80
|
|
161
|
-
cjxl INPUT.jpg OUTPUT.jxl --lossless_jpeg=1 --effort=7 --num_threads=0 --quiet
|
|
162
|
-
djxl OUTPUT.jxl RECONSTRUCTED.jpg --reconstruct_jpeg --num_threads=0 --quiet
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
From `repo/` in the development checkout, `tools/probes/jxl-quality.mjs --section=photo|modular|jpeg` makes
|
|
166
|
-
the inputs, encodes, runs the bracket search and writes `photo.json`, `modular.json` and `jpeg.json`;
|
|
167
|
-
`tools/probes/jxl-quality-metrics.py` computes the metrics (Python 3.12, NumPy 2.3, SciPy 1.17). The full
|
|
168
|
-
candidate pools, byte brackets, hashes and metric components are in the development receipts.
|
|
169
|
-
|
|
170
|
-
## Found but not ranked
|
|
171
|
-
|
|
172
|
-
| Project | Why not |
|
|
173
|
-
| --- | --- |
|
|
174
|
-
| [jxl-oxide-wasm](https://github.com/tirr-c/jxl-oxide-wasm) 0.12.6 (1,707,757 bytes, 612,548 gzip) | Decoder only |
|
|
175
|
-
| [jxl.js](https://github.com/niutech/jxl.js), jxl-rs-polyfill, TurboJXL, PureJsImage's codec | Decoders |
|
|
176
|
-
| [libjxl](https://github.com/libjxl/libjxl/blob/main/doc/building_wasm.md) WASM build | No published encoder payload; the libjxl-based packages above stand for it |
|
|
177
|
-
| [jixel](https://github.com/awxkee/jixel) `d84b45ff` | No published WASM |
|
|
178
|
-
| [libjxl-tiny](https://github.com/libjxl/libjxl-tiny) `8eae1817` | No published WASM |
|
|
179
|
-
| [Hydrium](https://github.com/Traneptora/hydrium) `45227f35` | Native executables only |
|
|
180
|
-
| [Imazen jxl-encoder](https://github.com/imazen/jxl-encoder) `0d79a23e` | No published WASM |
|
|
181
|
-
| webcvt's jsquash-jxl adapter | The jSquash encoder, already measured |
|
|
182
|
-
| sharp, libvips, the `cjxl` npm wrapper | Native binaries |
|
|
183
|
-
|
|
184
|
-
Searched: npm's `jpeg-xl`, `jpegxl`, `jxl` and `jixel` results, upstream repositories, the web. A smaller usable
|
|
185
|
-
encoder published later belongs in this table, and the claim changes with it.
|
package/KERNELS.md
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
# Optional integer kernels
|
|
2
|
-
|
|
3
|
-
The small `index.mjs` and `effort.mjs` doors remain JavaScript. To opt in, import
|
|
4
|
-
`encode` / `encodeSteps` from `rapier-jxl/wasm` instead of `rapier-jxl/effort`.
|
|
5
|
-
This door keeps the effort API, automatically tries SIMD, and falls back to the
|
|
6
|
-
reference JavaScript if WebAssembly or SIMD is absent or blocked by policy.
|
|
7
|
-
It changes neither lossless bytes nor the hurry rule. Rapier's full image worker
|
|
8
|
-
opts in automatically; the document-only worker still ships no encoder.
|
|
9
|
-
|
|
10
|
-
The public repository also builds **`wasm.min.mjs`**, one self-contained module.
|
|
11
|
-
The package marks these two entry modules as side-effectful so bundlers retain
|
|
12
|
-
their automatic backend configuration.
|
|
13
|
-
Do not combine `kernels.min.mjs` with a separately bundled core: each bundle would
|
|
14
|
-
own different hooks. There is deliberately no separate minified control door.
|
|
15
|
-
Readable modules can share controls through `rapier-jxl/kernels`:
|
|
16
|
-
|
|
17
|
-
```js
|
|
18
|
-
import {encode, configureKernels, kernelMode} from 'rapier-jxl/wasm';
|
|
19
|
-
configureKernels('auto'); // 'off', 'scalar', or 'simd' are explicit alternatives
|
|
20
|
-
const bytes = encode(rgba, width, height, {effort: 3, quality: 100});
|
|
21
|
-
console.log(kernelMode()); // the actual backend, not merely the requested one
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
Configure once before an encode, not inside its progress callback. Controls are
|
|
25
|
-
per JavaScript realm; workers have independent arenas. A second argument selects
|
|
26
|
-
kernels for deterministic benchmarks, for example `{channel: true, weighted:
|
|
27
|
-
false, fill: false}`. This only changes where arithmetic runs, never its result.
|
|
28
|
-
|
|
29
|
-
## What ships
|
|
30
|
-
|
|
31
|
-
`kernels-scalar.wat` implements prediction, weighted prediction and property
|
|
32
|
-
extraction, token histograms and a bulk bit writer. `kernels-simd.wat` implements
|
|
33
|
-
four-pixel average/gradient prediction and RGBA-to-planar conversion; rows and
|
|
34
|
-
odd tails take an explicit scalar path. Weighted prediction stays scalar: its
|
|
35
|
-
west-error state is sequential. Both modules use bounded integer arithmetic,
|
|
36
|
-
including signed i64 floor division for the weighted average. No relaxed SIMD,
|
|
37
|
-
floating-point WASM, imports other than private memory, network access, shared
|
|
38
|
-
memory, threads, or runtime dependencies are used.
|
|
39
|
-
|
|
40
|
-
The private arena is 3 MiB per enabled realm, reused synchronously. No views escape.
|
|
41
|
-
Groups are at most 65,536 samples; Int16 planes, unit multipliers and bounded
|
|
42
|
-
offsets are admitted. Other planes and custom writers keep the JavaScript path.
|
|
43
|
-
Non-little-endian hosts keep JavaScript as well. The existing input and output
|
|
44
|
-
limits remain in force. SIMD detection calls `WebAssembly.validate` on the tiny
|
|
45
|
-
`kernels-probe.wat` module; failure does not disable the encoder.
|
|
46
|
-
|
|
47
|
-
## Rebuild
|
|
48
|
-
|
|
49
|
-
The checked-in `kernels-bytes.mjs` contains generated base64 bytes, not source to
|
|
50
|
-
edit. In the Rapier tree run `node repo/images/build-jxl-kernels.mjs`; in a staged
|
|
51
|
-
public repository run `node build-jxl-kernels.mjs`. Install **wabt 1.0.37** only as
|
|
52
|
-
a build tool. `WABT_MODULE` may point to its `index.js` outside the source tree.
|
|
53
|
-
Add `--check` to reject a generated file that differs. No compiler ships in the
|
|
54
|
-
inline encoder. Source and build script are retained in the public package.
|
|
55
|
-
|
|
56
|
-
The JX/3 handoff records the bootstrap compiler used in its network-restricted
|
|
57
|
-
sandbox and the outstanding independent wabt rebuild. Do not describe that
|
|
58
|
-
handoff as a wabt-certified build until `--check` has been run with wabt.
|