@u1f992/pdfdiff 0.2.0 → 0.2.2
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/.github/workflows/gh-pages.yml +6 -1
- package/dist/browser.js +1219 -19
- package/dist/browser.js.map +1 -1
- package/dist/cli-png-worker.d.ts +13 -0
- package/dist/cli-png-worker.d.ts.map +1 -0
- package/dist/cli-png-worker.js +303 -0
- package/dist/cli-png-worker.js.map +1 -0
- package/dist/cli.js +240 -26
- package/dist/cli.js.map +1 -1
- package/dist/diff.d.ts +2 -1
- package/dist/diff.d.ts.map +1 -1
- package/dist/image.d.ts.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.html +6 -1
- package/dist/index.js +123 -15
- package/dist/index.js.map +1 -1
- package/dist/pdf.d.ts.map +1 -1
- package/dist/perf.d.ts +16 -0
- package/dist/perf.d.ts.map +1 -0
- package/dist/squoosh_png_bg.wasm +0 -0
- package/dist/style.css +12 -0
- package/dist/transferable.d.ts +7 -0
- package/dist/transferable.d.ts.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/worker.d.ts +9 -0
- package/dist/worker.d.ts.map +1 -1
- package/dist/worker.js +274 -88
- package/dist/worker.js.map +1 -1
- package/package.json +5 -2
- package/rollup.config.js +20 -0
- package/scripts/version.ts +35 -0
- package/src/browser.ts +119 -5
- package/src/cli-png-worker.ts +59 -0
- package/src/cli.ts +106 -21
- package/src/diff.ts +99 -34
- package/src/image.ts +3 -0
- package/src/index.html +6 -1
- package/src/index.ts +53 -27
- package/src/pdf.ts +9 -1
- package/src/perf.ts +94 -0
- package/src/style.css +12 -0
- package/src/transferable.ts +30 -0
- package/src/worker.ts +77 -54
package/dist/pdf.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pdf.d.ts","sourceRoot":"","sources":["../src/pdf.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"pdf.d.ts","sourceRoot":"","sources":["../src/pdf.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAG9C,wBAAiB,SAAS,CAAC,GAAG,EAAE,KAAK,CAAC,QAAQ,wDAI7C;AA8BD,wBAAsB,WAAW,CAC/B,IAAI,EAAE,KAAK,CAAC,IAAI,EAChB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,OAAO,yBAqBf"}
|
package/dist/perf.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type Counters = Readonly<Record<string, number>>;
|
|
2
|
+
export type Span = {
|
|
3
|
+
stop(): void;
|
|
4
|
+
};
|
|
5
|
+
type Perf = {
|
|
6
|
+
readonly enabled: boolean;
|
|
7
|
+
span(key: string): Span;
|
|
8
|
+
incr(key: string, delta?: number): void;
|
|
9
|
+
setMax(key: string, value: number): void;
|
|
10
|
+
merge(other: Counters): void;
|
|
11
|
+
dump(): Counters;
|
|
12
|
+
reset(): void;
|
|
13
|
+
};
|
|
14
|
+
export declare const perf: Perf;
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=perf.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"perf.d.ts","sourceRoot":"","sources":["../src/perf.ts"],"names":[],"mappings":"AAiCA,MAAM,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAExD,MAAM,MAAM,IAAI,GAAG;IAAE,IAAI,IAAI,IAAI,CAAA;CAAE,CAAC;AAEpC,KAAK,IAAI,GAAG;IACV,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,KAAK,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC7B,IAAI,IAAI,QAAQ,CAAC;IACjB,KAAK,IAAI,IAAI,CAAC;CACf,CAAC;AAgDF,eAAO,MAAM,IAAI,EAAE,IAAuC,CAAC"}
|
|
Binary file
|
package/dist/style.css
CHANGED
|
@@ -11,9 +11,21 @@
|
|
|
11
11
|
.diff-table {
|
|
12
12
|
border: 1px solid black;
|
|
13
13
|
border-collapse: collapse;
|
|
14
|
+
width: 100%;
|
|
15
|
+
table-layout: fixed;
|
|
14
16
|
}
|
|
15
17
|
|
|
16
18
|
.diff-table th,
|
|
17
19
|
.diff-table td {
|
|
18
20
|
border: 1px solid black;
|
|
19
21
|
}
|
|
22
|
+
|
|
23
|
+
.diff-table img {
|
|
24
|
+
display: block;
|
|
25
|
+
max-width: 100%;
|
|
26
|
+
height: auto;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
body.hide-no-diff .diff-details.no-diff {
|
|
30
|
+
display: none;
|
|
31
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Slice a typed-array view into a standalone backing buffer of the same kind
|
|
3
|
+
* (ArrayBuffer in, ArrayBuffer out; SharedArrayBuffer in, SharedArrayBuffer
|
|
4
|
+
* out). The buffer kind is preserved through the generic parameter.
|
|
5
|
+
*/
|
|
6
|
+
export declare function sliceBackingBuffer<TArrayBuffer extends ArrayBufferLike>(src: Uint8Array<TArrayBuffer> | Uint8ClampedArray<TArrayBuffer>): TArrayBuffer;
|
|
7
|
+
//# sourceMappingURL=transferable.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transferable.d.ts","sourceRoot":"","sources":["../src/transferable.ts"],"names":[],"mappings":"AAiBA;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,YAAY,SAAS,eAAe,EACrE,GAAG,EAAE,UAAU,CAAC,YAAY,CAAC,GAAG,iBAAiB,CAAC,YAAY,CAAC,GAC9D,YAAY,CAKd"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,UAAU,CAAC"}
|
package/dist/worker.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type Pallet } from "./diff.ts";
|
|
2
2
|
import { type AlignStrategy } from "./image.ts";
|
|
3
|
+
import { type Counters } from "./perf.ts";
|
|
3
4
|
export type InitMessage = {
|
|
4
5
|
type: "init";
|
|
5
6
|
aBytes: Uint8Array;
|
|
@@ -14,6 +15,9 @@ export type PageMessage = {
|
|
|
14
15
|
type: "page";
|
|
15
16
|
index: number;
|
|
16
17
|
};
|
|
18
|
+
export type LoadedMessage = {
|
|
19
|
+
type: "loaded";
|
|
20
|
+
};
|
|
17
21
|
export type ReadyMessage = {
|
|
18
22
|
type: "ready";
|
|
19
23
|
};
|
|
@@ -38,5 +42,10 @@ export type PageResultMessage = {
|
|
|
38
42
|
addition: [number, number][];
|
|
39
43
|
deletion: [number, number][];
|
|
40
44
|
modification: [number, number][];
|
|
45
|
+
perf?: Counters | undefined;
|
|
46
|
+
};
|
|
47
|
+
export type ErrorMessage = {
|
|
48
|
+
type: "error";
|
|
49
|
+
message: string;
|
|
41
50
|
};
|
|
42
51
|
//# sourceMappingURL=worker.d.ts.map
|
package/dist/worker.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAkB,KAAK,MAAM,EAAE,MAAM,WAAW,CAAC;AACxD,OAAO,EAGL,KAAK,aAAa,EACnB,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAkB,KAAK,MAAM,EAAE,MAAM,WAAW,CAAC;AACxD,OAAO,EAGL,KAAK,aAAa,EACnB,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAQ,KAAK,QAAQ,EAAE,MAAM,WAAW,CAAC;AAGhD,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,UAAU,CAAC;IACnB,MAAM,EAAE,UAAU,CAAC;IACnB,SAAS,EAAE,UAAU,GAAG,IAAI,CAAC;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,aAAa,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,QAAQ,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,OAAO,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,YAAY,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,WAAW,CAAA;KAAE,CAAC;IACxD,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,WAAW,CAAA;KAAE,CAAC;IACxD,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,WAAW,CAAA;KAAE,CAAC;IAC3D,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC;IAC7B,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC;IAC7B,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC;IACjC,IAAI,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;CAC7B,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC"}
|
package/dist/worker.js
CHANGED
|
@@ -3212,6 +3212,82 @@ read:function(e,t,i,r,n){var a,o,s=8*n-r-1,l=(1<<s)-1,u=l>>1,h=-7,c=i?n-1:0,f=i?
|
|
|
3212
3212
|
* rgbquant.ts - part of Image Quantization Library
|
|
3213
3213
|
*/"function"==typeof setImmediate?setImmediate:"undefined"!=typeof process&&(null==process||process.nextTick);const QuantizeOptionsSchema=z.object({colors:z.number().optional(),colorDistanceFormula:z.union([z.literal("cie94-textiles"),z.literal("cie94-graphic-arts"),z.literal("ciede2000"),z.literal("color-metric"),z.literal("euclidean"),z.literal("euclidean-bt709-noalpha"),z.literal("euclidean-bt709"),z.literal("manhattan"),z.literal("manhattan-bt709"),z.literal("manhattan-nommyde"),z.literal("pngquant")]).optional(),paletteQuantization:z.union([z.literal("neuquant"),z.literal("neuquant-float"),z.literal("rgbquant"),z.literal("wuquant")]).optional(),imageQuantization:z.union([z.literal("nearest"),z.literal("riemersma"),z.literal("floyd-steinberg"),z.literal("false-floyd-steinberg"),z.literal("stucki"),z.literal("atkinson"),z.literal("jarvis"),z.literal("burkes"),z.literal("sierra"),z.literal("two-sierra"),z.literal("sierra-lite")]).optional()}),methods={quantize(e,t){const{colors:i,colorDistanceFormula:r,paletteQuantization:n,imageQuantization:a}=QuantizeOptionsSchema.parse(t),o=utils_exports.PointContainer.fromUint8Array(e.bitmap.data,e.bitmap.width,e.bitmap.height),s=applyPaletteSync(o,buildPaletteSync([o],{colors:i,colorDistanceFormula:r,paletteQuantization:n}),{colorDistanceFormula:r,imageQuantization:a});return e.bitmap.data=Buffer.from(s.toUint8Array()),e}};var parseBmfontAscii=function(e){if(!e)throw new Error("no data provided");var t={pages:[],chars:[],kernings:[]},i=(e=e.toString().trim()).split(/\r\n?|\n/g);if(0===i.length)throw new Error("no data in BMFont file");for(var r=0;r<i.length;r++){var n=splitLine(i[r],r);if(n)if("page"===n.key){if("number"!=typeof n.data.id)throw new Error("malformed file at line "+r+" -- needs page id=N");if("string"!=typeof n.data.file)throw new Error("malformed file at line "+r+' -- needs page file="path"');t.pages[n.data.id]=n.data.file;}else "chars"===n.key||"kernings"===n.key||("char"===n.key?t.chars.push(n.data):"kerning"===n.key?t.kernings.push(n.data):t[n.key]=n.data);}return t};function splitLine(e,t){if(!(e=e.replace(/\t+/g," ").trim()))return null;var i=e.indexOf(" ");if(-1===i)throw new Error("no named row at line "+t);var r=e.substring(0,i);e=(e=(e=(e=e.substring(i+1)).replace(/letter=[\'\"]\S+[\'\"]/gi,"")).split("=")).map((function(e){return e.trim().match(/(".*?"|[^"\s]+)+(?=\s*|\s*$)/g)}));for(var n=[],a=0;a<e.length;a++){var o=e[a];0===a?n.push({key:o[0],data:""}):a===e.length-1?n[n.length-1].data=parseData(o[0]):(n[n.length-1].data=parseData(o[0]),n.push({key:o[1],data:""}));}var s={key:r,data:{}};return n.forEach((function(e){s.data[e.key]=e.data;})),s}function parseData(e){return e&&0!==e.length?0===e.indexOf('"')||0===e.indexOf("'")?e.substring(1,e.length-1):-1!==e.indexOf(",")?parseIntList$1(e):parseInt(e,10):""}function parseIntList$1(e){return e.split(",").map((function(e){return parseInt(e,10)}))}getDefaultExportFromCjs(parseBmfontAscii);var GLYPH_DESIGNER_ERROR="chasrset",parseAttribs=function(e){for(var t in e=Object.assign({},e),GLYPH_DESIGNER_ERROR in e&&(e.charset=e[GLYPH_DESIGNER_ERROR],delete e[GLYPH_DESIGNER_ERROR]),e)"face"!==t&&"charset"!==t&&(e[t]="padding"===t||"spacing"===t?parseIntList(e[t]):parseInt(e[t],10));return e};function parseIntList(e){return e.split(",").map((function(e){return parseInt(e,10)}))}var xmlParseFromString=void 0!==self.DOMParser?function(e){return (new self.DOMParser).parseFromString(e,"application/xml")}:void 0!==self.ActiveXObject&&new self.ActiveXObject("Microsoft.XMLDOM")?function(e){var t=new self.ActiveXObject("Microsoft.XMLDOM");return t.async="false",t.loadXML(e),t}:function(e){var t=document.createElement("div");return t.innerHTML=e,t},parseAttributes=parseAttribs,parseFromString=xmlParseFromString,NAME_MAP={scaleh:"scaleH",scalew:"scaleW",stretchh:"stretchH",lineheight:"lineHeight",alphachnl:"alphaChnl",redchnl:"redChnl",greenchnl:"greenChnl",bluechnl:"blueChnl"},browser=function(e){e=e.toString();var t=parseFromString(e),i={pages:[],chars:[],kernings:[]};["info","common"].forEach((function(e){var r=t.getElementsByTagName(e)[0];r&&(i[e]=parseAttributes(getAttribs(r)));}));var r=t.getElementsByTagName("pages")[0];if(!r)throw new Error("malformed file -- no <pages> element");for(var n=r.getElementsByTagName("page"),a=0;a<n.length;a++){var o=n[a],s=parseInt(o.getAttribute("id"),10),l=o.getAttribute("file");if(isNaN(s))throw new Error('malformed file -- page "id" attribute is NaN');if(!l)throw new Error('malformed file -- needs page "file" attribute');i.pages[parseInt(s,10)]=l;}return ["chars","kernings"].forEach((function(e){var r=t.getElementsByTagName(e)[0];if(r)for(var n=e.substring(0,e.length-1),a=r.getElementsByTagName(n),o=0;o<a.length;o++){var s=a[o];i[e].push(parseAttributes(getAttribs(s)));}})),i};function getAttribs(e){return getAttribList(e).reduce((function(e,t){return e[mapName(t.nodeName)]=t.nodeValue,e}),{})}function getAttribList(e){for(var t=[],i=0;i<e.attributes.length;i++)t.push(e.attributes[i]);return t}function mapName(e){return NAME_MAP[e.toLowerCase()]||e}getDefaultExportFromCjs(browser);var HEADER$1=[66,77,70],parseBmfontBinary=function(e){if(e.length<6)throw new Error("invalid buffer length for BMFont");var t=HEADER$1.every((function(t,i){return e.readUInt8(i)===t}));if(!t)throw new Error("BMFont missing BMF byte header");var i=3;if(e.readUInt8(i++)>3)throw new Error("Only supports BMFont Binary v3 (BMFont App v1.10)");for(var r={kernings:[],chars:[]},n=0;n<5;n++)i+=readBlock(r,e,i);return r};function readBlock(e,t,i){if(i>t.length-1)return 0;var r=t.readUInt8(i++),n=t.readInt32LE(i);switch(i+=4,r){case 1:e.info=readInfo(t,i);break;case 2:e.common=readCommon(t,i);break;case 3:e.pages=readPages(t,i,n);break;case 4:e.chars=readChars(t,i,n);break;case 5:e.kernings=readKernings(t,i,n);}return 5+n}function readInfo(e,t){var i={};i.size=e.readInt16LE(t);var r=e.readUInt8(t+2);return i.smooth=r>>7&1,i.unicode=r>>6&1,i.italic=r>>5&1,i.bold=r>>4&1,r>>3&1&&(i.fixedHeight=1),i.charset=e.readUInt8(t+3)||"",i.stretchH=e.readUInt16LE(t+4),i.aa=e.readUInt8(t+6),i.padding=[e.readInt8(t+7),e.readInt8(t+8),e.readInt8(t+9),e.readInt8(t+10)],i.spacing=[e.readInt8(t+11),e.readInt8(t+12)],i.outline=e.readUInt8(t+13),i.face=readStringNT(e,t+14),i}function readCommon(e,t){var i={};return i.lineHeight=e.readUInt16LE(t),i.base=e.readUInt16LE(t+2),i.scaleW=e.readUInt16LE(t+4),i.scaleH=e.readUInt16LE(t+6),i.pages=e.readUInt16LE(t+8),e.readUInt8(t+10),i.packed=0,i.alphaChnl=e.readUInt8(t+11),i.redChnl=e.readUInt8(t+12),i.greenChnl=e.readUInt8(t+13),i.blueChnl=e.readUInt8(t+14),i}function readPages(e,t,i){for(var r=[],n=readNameNT(e,t),a=n.length+1,o=i/a,s=0;s<o;s++)r[s]=e.slice(t,t+n.length).toString("utf8"),t+=a;return r}function readChars(e,t,i){for(var r=[],n=i/20,a=0;a<n;a++){var o={},s=20*a;o.id=e.readUInt32LE(t+0+s),o.x=e.readUInt16LE(t+4+s),o.y=e.readUInt16LE(t+6+s),o.width=e.readUInt16LE(t+8+s),o.height=e.readUInt16LE(t+10+s),o.xoffset=e.readInt16LE(t+12+s),o.yoffset=e.readInt16LE(t+14+s),o.xadvance=e.readInt16LE(t+16+s),o.page=e.readUInt8(t+18+s),o.chnl=e.readUInt8(t+19+s),r[a]=o;}return r}function readKernings(e,t,i){for(var r=[],n=i/10,a=0;a<n;a++){var o={},s=10*a;o.first=e.readUInt32LE(t+0+s),o.second=e.readUInt32LE(t+4+s),o.amount=e.readInt16LE(t+8+s),r[a]=o;}return r}function readNameNT(e,t){for(var i=t;i<e.length&&0!==e[i];i++);return e.slice(t,i)}function readStringNT(e,t){return readNameNT(e,t).toString("utf8")}getDefaultExportFromCjs(parseBmfontBinary);function e(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}const t=e=>{if(!e)return null;const i={};switch(e.type){case "ELEMENT":{let n={};const a=E(e.value.attributes),o=t(e.value.children);if(a&&(n=Object.assign(n,a)),o){const t=r(e.value.children);n=Object.assign(n,t);}i[e.value.type]=n;break}case "ATTRIBUTE":{const t=e.value;i[t.name]=t.value;break}case "CONTENT":return {content:e.value}}return i},r=e=>e&&Array.isArray(e)&&0!==e.length?n(e)?{content:e[0].value}:{children:e.map(t)}:null,n=e=>e&&Array.isArray(e)&&1===e.length&&"CONTENT"===e[0].type,E=e=>e&&Array.isArray(e)?e.map(t).reduce(((e,t)=>Object.assign(e,t)),{}):null;var s={convert:e=>t(e.value.children[0])},a={Token:(e,t)=>({type:e,value:t}),TOKEN_TYPE:{OPEN_BRACKET:"OPEN_BRACKET",ELEMENT_TYPE:"ELEMENT_TYPE",CLOSE_ELEMENT:"CLOSE_ELEMENT",ATTRIB_NAME:"ATTRIB_NAME",ATTRIB_VALUE:"ATTRIB_VALUE",ASSIGN:"ASSIGN",CLOSE_BRACKET:"CLOSE_BRACKET",CONTENT:"CONTENT",EOF:"EOF"}};const{Token:T,TOKEN_TYPE:u}=a,c=T("EOF"),l=e=>" "===e||"\n"===e||"\r"===e||"\t"===e,o=e=>e.replace(/'/g,'"');var N={createLexer:function(e){let t=null,i=(e=>{let t=0;for(;t<e.length&&l(e[t]);)t++;return ((e,t)=>{if(e.startsWith("<?xml",t)){const i=e.length;for(;t<i;)if("?"!==e[t])t++;else {if(">"===e[t+1])return t+2;t++;}}return t})(e,t)})(e),r=[];const n=()=>e[i],a=()=>t!==c&&i<e.length,s=e=>'"'===e||"'"===e,h=()=>{for(;a()&&l(e[i]);)i++;},f=t=>{if(a()){if("<"===e[i]){let t="<";return i++,a()&&"/"===e[i]?(i++,t="</"):a()&&"!"===e[i]&&"-"===e[i+1]&&"-"===e[i+2]&&(i++,i++,i++,t="\x3c!--"),t}if("/"===n()){let e="/";return i++,a()&&">"===n()&&(i++,e="/>"),e}if("="===e[i]||">"===e[i]){const t=e[i];return i++,t}}return d(!!t)},d=t=>{const r=t?/[^>=<]/u:/[a-zA-Z0-9_:-]/;let n=i;for(;a()&&e[i].match(r);)i++;return o(e.substring(n,i))},p=()=>{const l=i;h();const m=i-l;if(a())if(t&&t.type===u.OPEN_BRACKET){h();const e=f(false);t=T(u.ELEMENT_TYPE,e),r.push(e);}else if(t&&t.type===u.ASSIGN){a()&&s(n())&&i++;let r=i;for(;a()&&!s(n());)i++;const l=o(e.substring(r,i));i++,t=T(u.ATTRIB_VALUE,l);}else {h();let o=f(true);switch(o){case "=":t=t.type===u.ATTRIB_NAME?T(u.ASSIGN):T(u.CONTENT,o);break;case "</":{const n=i;for(;">"!==e[i];)i++;t=T(u.CLOSE_ELEMENT,e.substring(n,i)),i++,r.pop();break}case "/>":{const e=r.pop();t=T(u.CLOSE_ELEMENT,e);break}case "\x3c!--":{const t=["!","-","-"];for(;a()&&(">"!==t[2]||"-"!==t[1]||"-"!==t[0]);)t.shift(),t.push(e[i]),i++;return p()}case ">":t=T(u.CLOSE_BRACKET);break;case "<":t=T(u.OPEN_BRACKET);break;default:if(o&&o.length>0){if(t.type===u.CLOSE_BRACKET){let e="";"<"!==n()&&(e=d(true)),t=T(u.CONTENT,o+e);}else if(t.type!==u.ATTRIB_NAME&&t.type!==u.CONTENT)t.type===u.CLOSE_ELEMENT?(o=" ".repeat(m)+o,t=T(u.CONTENT,o)):t=T(u.ATTRIB_NAME,o);else {const e=" ".repeat(m)+o;t=T(u.CONTENT,e);}break}{const t='Unknown Syntax : "'+e[i]+'"';throw new Error(t)}}}else t=c;return t};return {peek:n,next:p,hasNext:a}}};const{createLexer:i}=N,{Token:p,TOKEN_TYPE:O}=a,[A,f,C,h]=["ROOT","ELEMENT","ATTRIBUTE","CONTENT"],_=(e,t)=>({type:e,value:t}),L=e=>_(h,e),y=(e,t,i)=>_(f,{type:e,attributes:t,children:i}),v=(e,t)=>_(C,{name:e,value:t}),S=(e,t)=>{const i=[];for(;e.hasNext();){const r=e.next();switch(r.type){case O.OPEN_BRACKET:{const t=e.next(),[r,n]=R(e);let a=[];n.type!==O.CLOSE_ELEMENT&&(a=S(e,t)),a&&a.length>0&&a[0].type===O.CONTENT&&(a=b(a)),i.push(y(t.value,r,a));break}case O.CLOSE_ELEMENT:if(r.value===t.value)return i;break;case O.CONTENT:i.push(L(r.value));break;case O.EOF:return i;default:throw new Error(`Unknown Lexem type: ${r.type} "${r.value}, scoping element: ${t.value}"`)}}return i},R=e=>{const t=[];let i=e.peek();if(!e.hasNext()||i&&i.type===O.CLOSE_BRACKET||i&&i.type===O.CLOSE_ELEMENT)return [t,i];for(i=e.next();e.hasNext()&&i&&i.type!==O.CLOSE_BRACKET&&i.type!==O.CLOSE_ELEMENT;){const r=i;e.next();const n=e.next(),a=v(r.value,n.value);t.push(a),i=e.next();}return [t,i]};function b(e){let t=[],i="";return e.forEach((e=>{e.type===O.CONTENT?i+=e.value:(i.length&&(t.push(L(i)),i=""),t.push(e));})),i.length&&t.push(L(i)),t}var B={transpile:function(e,t){const r=(e=>_(A,{children:S(e,p(A,"ROOT"))}))(i(e));return t?t.convert(r):r}};const M=s,{transpile:x}=B;var k=e({convertXML:function(e,t){return x(e,t||M)},createAST:function(e){return x(e)}}),simpleXmlToJson_min=k,xmlPackage=getDefaultExportFromCjs(simpleXmlToJson_min);const {convertXML:convertXML}=xmlPackage;createJimp({formats:[png]});Buffer.from([66,77,70,3]);var pixelmatch_1=pixelmatch;const defaultOptions={threshold:.1,includeAA:false,alpha:.1,aaColor:[255,255,0],diffColor:[255,0,0],diffColorAlt:null,diffMask:false};function pixelmatch(e,t,i,r,n,a){if(!isPixelData(e)||!isPixelData(t)||i&&!isPixelData(i))throw new Error("Image data: Uint8Array, Uint8ClampedArray or Buffer expected.");if(e.length!==t.length||i&&i.length!==e.length)throw new Error("Image sizes do not match.");if(e.length!==r*n*4)throw new Error("Image data size does not match width/height.");a=Object.assign({},defaultOptions,a);const o=r*n,s=new Uint32Array(e.buffer,e.byteOffset,o),l=new Uint32Array(t.buffer,t.byteOffset,o);let u=true;for(let e=0;e<o;e++)if(s[e]!==l[e]){u=false;break}if(u){if(i&&!a.diffMask)for(let t=0;t<o;t++)drawGrayPixel(e,4*t,a.alpha,i);return 0}const h=35215*a.threshold*a.threshold;let c=0;for(let o=0;o<n;o++)for(let s=0;s<r;s++){const l=4*(o*r+s),u=colorDelta(e,t,l,l);Math.abs(u)>h?a.includeAA||!antialiased(e,s,o,r,n,t)&&!antialiased(t,s,o,r,n,e)?(i&&drawPixel(i,l,...u<0&&a.diffColorAlt||a.diffColor),c++):i&&!a.diffMask&&drawPixel(i,l,...a.aaColor):i&&(a.diffMask||drawGrayPixel(e,l,a.alpha,i));}return c}function isPixelData(e){return ArrayBuffer.isView(e)&&1===e.constructor.BYTES_PER_ELEMENT}function antialiased(e,t,i,r,n,a){const o=Math.max(t-1,0),s=Math.max(i-1,0),l=Math.min(t+1,r-1),u=Math.min(i+1,n-1),h=4*(i*r+t);let c,f,d,p,m=t===o||t===l||i===s||i===u?1:0,_=0,g=0;for(let n=o;n<=l;n++)for(let a=s;a<=u;a++){if(n===t&&a===i)continue;const o=colorDelta(e,e,h,4*(a*r+n),true);if(0===o){if(m++,m>2)return false}else o<_?(_=o,c=n,f=a):o>g&&(g=o,d=n,p=a);}return 0!==_&&0!==g&&(hasManySiblings(e,c,f,r,n)&&hasManySiblings(a,c,f,r,n)||hasManySiblings(e,d,p,r,n)&&hasManySiblings(a,d,p,r,n))}function hasManySiblings(e,t,i,r,n){const a=Math.max(t-1,0),o=Math.max(i-1,0),s=Math.min(t+1,r-1),l=Math.min(i+1,n-1),u=4*(i*r+t);let h=t===a||t===s||i===o||i===l?1:0;for(let n=a;n<=s;n++)for(let a=o;a<=l;a++){if(n===t&&a===i)continue;const o=4*(a*r+n);if(e[u]===e[o]&&e[u+1]===e[o+1]&&e[u+2]===e[o+2]&&e[u+3]===e[o+3]&&h++,h>2)return true}return false}function colorDelta(e,t,i,r,n){let a=e[i+0],o=e[i+1],s=e[i+2],l=e[i+3],u=t[r+0],h=t[r+1],c=t[r+2],f=t[r+3];if(l===f&&a===u&&o===h&&s===c)return 0;l<255&&(l/=255,a=blend(a,l),o=blend(o,l),s=blend(s,l)),f<255&&(f/=255,u=blend(u,f),h=blend(h,f),c=blend(c,f));const d=rgb2y(a,o,s),p=rgb2y(u,h,c),m=d-p;if(n)return m;const _=rgb2i(a,o,s)-rgb2i(u,h,c),g=rgb2q(a,o,s)-rgb2q(u,h,c),b=.5053*m*m+.299*_*_+.1957*g*g;return d>p?-b:b}function rgb2y(e,t,i){return .29889531*e+.58662247*t+.11448223*i}function rgb2i(e,t,i){return .59597799*e-.2741761*t-.32180189*i}function rgb2q(e,t,i){return .21147017*e-.52261711*t+.31114694*i}function blend(e,t){return 255+(e-255)*t}function drawPixel(e,t,i,r,n){e[t+0]=i,e[t+1]=r,e[t+2]=n,e[t+3]=255;}function drawGrayPixel(e,t,i,r){const n=blend(rgb2y(e[t+0],e[t+1],e[t+2]),i*e[t+3]/255);drawPixel(r,t,n,n,n);}getDefaultExportFromCjs(pixelmatch_1);const defaultPlugins=[methods$h,methods$g,methods$f,methods$e,methods$c,methods$a,methods$b,methods$9,methods$8,methods$7,methods$6,methods$5,methods$4,methods$3,methods$d,methods$2,methods$1,methods],defaultFormats=[bmp,msBmp,gif,jpeg$2,png,tiff];({bmp:bmp().mime,gif:gif().mime,jpeg:jpeg$2().mime,png:png().mime,tiff:tiff().mime});const Jimp=createJimp({formats:defaultFormats,plugins:defaultPlugins});
|
|
3214
3214
|
|
|
3215
|
+
/*
|
|
3216
|
+
* Copyright (C) 2025 Koutaro Mukai
|
|
3217
|
+
*
|
|
3218
|
+
* This program is free software: you can redistribute it and/or modify
|
|
3219
|
+
* it under the terms of the GNU General Public License as published by
|
|
3220
|
+
* the Free Software Foundation, either version 3 of the License, or
|
|
3221
|
+
* (at your option) any later version.
|
|
3222
|
+
*
|
|
3223
|
+
* This program is distributed in the hope that it will be useful,
|
|
3224
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
3225
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
3226
|
+
* GNU General Public License for more details.
|
|
3227
|
+
*
|
|
3228
|
+
* You should have received a copy of the GNU General Public License
|
|
3229
|
+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
3230
|
+
*/
|
|
3231
|
+
const _enabled = (() => {
|
|
3232
|
+
try {
|
|
3233
|
+
if (typeof process !== "undefined" &&
|
|
3234
|
+
process.env &&
|
|
3235
|
+
process.env.PDFDIFF_PROFILE === "1") {
|
|
3236
|
+
return true;
|
|
3237
|
+
}
|
|
3238
|
+
}
|
|
3239
|
+
catch {
|
|
3240
|
+
// process not available (e.g. in some browser worker environments)
|
|
3241
|
+
}
|
|
3242
|
+
const g = globalThis;
|
|
3243
|
+
return g.__PDFDIFF_PROFILE__ === true;
|
|
3244
|
+
})();
|
|
3245
|
+
const _counters = Object.create(null);
|
|
3246
|
+
const _NOOP_SPAN = Object.freeze({ stop() { } });
|
|
3247
|
+
const _noop = () => { };
|
|
3248
|
+
const _emptyDump = () => Object.freeze({});
|
|
3249
|
+
const _realPerf = {
|
|
3250
|
+
enabled: true,
|
|
3251
|
+
span(key) {
|
|
3252
|
+
const t0 = performance.now();
|
|
3253
|
+
return {
|
|
3254
|
+
stop() {
|
|
3255
|
+
_counters[key] = (_counters[key] ?? 0) + (performance.now() - t0);
|
|
3256
|
+
},
|
|
3257
|
+
};
|
|
3258
|
+
},
|
|
3259
|
+
incr(key, delta = 1) {
|
|
3260
|
+
_counters[key] = (_counters[key] ?? 0) + delta;
|
|
3261
|
+
},
|
|
3262
|
+
setMax(key, value) {
|
|
3263
|
+
const cur = _counters[key];
|
|
3264
|
+
if (cur === undefined || value > cur)
|
|
3265
|
+
_counters[key] = value;
|
|
3266
|
+
},
|
|
3267
|
+
merge(other) {
|
|
3268
|
+
for (const k of Object.keys(other)) {
|
|
3269
|
+
_counters[k] = (_counters[k] ?? 0) + other[k];
|
|
3270
|
+
}
|
|
3271
|
+
},
|
|
3272
|
+
dump() {
|
|
3273
|
+
return { ..._counters };
|
|
3274
|
+
},
|
|
3275
|
+
reset() {
|
|
3276
|
+
for (const k of Object.keys(_counters))
|
|
3277
|
+
delete _counters[k];
|
|
3278
|
+
},
|
|
3279
|
+
};
|
|
3280
|
+
const _noopPerf = {
|
|
3281
|
+
enabled: false,
|
|
3282
|
+
span: () => _NOOP_SPAN,
|
|
3283
|
+
incr: _noop,
|
|
3284
|
+
setMax: _noop,
|
|
3285
|
+
merge: _noop,
|
|
3286
|
+
dump: _emptyDump,
|
|
3287
|
+
reset: _noop,
|
|
3288
|
+
};
|
|
3289
|
+
const perf = _enabled ? _realPerf : _noopPerf;
|
|
3290
|
+
|
|
3215
3291
|
/*
|
|
3216
3292
|
* Copyright (C) 2025 Koutaro Mukai
|
|
3217
3293
|
*
|
|
@@ -3266,6 +3342,7 @@ function alignSize(images, align) {
|
|
|
3266
3342
|
: alignImage(img, largerWidth, largerHeight, align));
|
|
3267
3343
|
}
|
|
3268
3344
|
function composeLayers(canvasWidth, canvasHeight, layers) {
|
|
3345
|
+
const _span = perf.span("image.compose_ms");
|
|
3269
3346
|
const canvas = createEmptyImage(canvasWidth, canvasHeight);
|
|
3270
3347
|
const dData = canvas.bitmap.data;
|
|
3271
3348
|
for (const [image, opacity] of layers) {
|
|
@@ -3293,6 +3370,7 @@ function composeLayers(canvasWidth, canvasHeight, layers) {
|
|
|
3293
3370
|
}
|
|
3294
3371
|
}
|
|
3295
3372
|
}
|
|
3373
|
+
_span.stop();
|
|
3296
3374
|
return canvas;
|
|
3297
3375
|
}
|
|
3298
3376
|
|
|
@@ -3313,54 +3391,119 @@ function composeLayers(canvasWidth, canvasHeight, layers) {
|
|
|
3313
3391
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
3314
3392
|
*/
|
|
3315
3393
|
function drawDifference(a, b, mask, pallet, align) {
|
|
3316
|
-
const
|
|
3394
|
+
const sAlign = perf.span("diff.align_ms");
|
|
3395
|
+
let aNew;
|
|
3396
|
+
let bNew;
|
|
3397
|
+
let maskNew;
|
|
3398
|
+
if (mask !== null) {
|
|
3399
|
+
[aNew, bNew, maskNew] = alignSize([a, b, mask], align);
|
|
3400
|
+
}
|
|
3401
|
+
else {
|
|
3402
|
+
[aNew, bNew] = alignSize([a, b], align);
|
|
3403
|
+
maskNew = null;
|
|
3404
|
+
}
|
|
3405
|
+
sAlign.stop();
|
|
3317
3406
|
const width = aNew.width;
|
|
3318
3407
|
const height = aNew.height;
|
|
3319
3408
|
const aData = aNew.bitmap.data;
|
|
3320
3409
|
const bData = bNew.bitmap.data;
|
|
3321
|
-
const mData = maskNew.bitmap.data;
|
|
3410
|
+
const mData = maskNew !== null ? maskNew.bitmap.data : null;
|
|
3411
|
+
const sCreate = perf.span("diff.createEmpty_ms");
|
|
3322
3412
|
const diffImage = createEmptyImage(width, height);
|
|
3323
3413
|
const dData = diffImage.bitmap.data;
|
|
3414
|
+
sCreate.stop();
|
|
3324
3415
|
const addition = [];
|
|
3325
3416
|
const deletion = [];
|
|
3326
3417
|
const modification = [];
|
|
3327
|
-
|
|
3328
|
-
|
|
3329
|
-
|
|
3330
|
-
|
|
3331
|
-
|
|
3332
|
-
|
|
3333
|
-
|
|
3334
|
-
|
|
3335
|
-
aData[idx
|
|
3336
|
-
|
|
3337
|
-
|
|
3338
|
-
|
|
3339
|
-
|
|
3340
|
-
|
|
3341
|
-
|
|
3342
|
-
|
|
3343
|
-
|
|
3344
|
-
|
|
3345
|
-
target
|
|
3346
|
-
color
|
|
3347
|
-
|
|
3348
|
-
|
|
3349
|
-
|
|
3350
|
-
|
|
3418
|
+
const sScan = perf.span("diff.scan_ms");
|
|
3419
|
+
let diffPixels = 0;
|
|
3420
|
+
if (mData !== null) {
|
|
3421
|
+
for (let x = 0; x < width; x++) {
|
|
3422
|
+
for (let y = 0; y < height; y++) {
|
|
3423
|
+
const idx = (y * width + x) * 4;
|
|
3424
|
+
if (mData[idx + 3] !== 0)
|
|
3425
|
+
continue;
|
|
3426
|
+
const aAlpha = aData[idx + 3];
|
|
3427
|
+
const bAlpha = bData[idx + 3];
|
|
3428
|
+
if (aAlpha === bAlpha &&
|
|
3429
|
+
aData[idx] === bData[idx] &&
|
|
3430
|
+
aData[idx + 1] === bData[idx + 1] &&
|
|
3431
|
+
aData[idx + 2] === bData[idx + 2]) {
|
|
3432
|
+
continue;
|
|
3433
|
+
}
|
|
3434
|
+
if (aAlpha === 0 && bAlpha === 0)
|
|
3435
|
+
continue;
|
|
3436
|
+
let target;
|
|
3437
|
+
let color;
|
|
3438
|
+
if (aAlpha === 0) {
|
|
3439
|
+
target = addition;
|
|
3440
|
+
color = pallet.addition;
|
|
3441
|
+
}
|
|
3442
|
+
else if (bAlpha === 0) {
|
|
3443
|
+
target = deletion;
|
|
3444
|
+
color = pallet.deletion;
|
|
3445
|
+
}
|
|
3446
|
+
else {
|
|
3447
|
+
target = modification;
|
|
3448
|
+
color = pallet.modification;
|
|
3449
|
+
}
|
|
3450
|
+
target.push([x, y]);
|
|
3451
|
+
diffPixels++;
|
|
3452
|
+
dData[idx] = color[0];
|
|
3453
|
+
dData[idx + 1] = color[1];
|
|
3454
|
+
dData[idx + 2] = color[2];
|
|
3455
|
+
dData[idx + 3] = color[3];
|
|
3351
3456
|
}
|
|
3352
|
-
|
|
3353
|
-
|
|
3354
|
-
|
|
3457
|
+
}
|
|
3458
|
+
}
|
|
3459
|
+
else {
|
|
3460
|
+
for (let x = 0; x < width; x++) {
|
|
3461
|
+
for (let y = 0; y < height; y++) {
|
|
3462
|
+
const idx = (y * width + x) * 4;
|
|
3463
|
+
const aAlpha = aData[idx + 3];
|
|
3464
|
+
const bAlpha = bData[idx + 3];
|
|
3465
|
+
if (aAlpha === bAlpha &&
|
|
3466
|
+
aData[idx] === bData[idx] &&
|
|
3467
|
+
aData[idx + 1] === bData[idx + 1] &&
|
|
3468
|
+
aData[idx + 2] === bData[idx + 2]) {
|
|
3469
|
+
continue;
|
|
3470
|
+
}
|
|
3471
|
+
if (aAlpha === 0 && bAlpha === 0)
|
|
3472
|
+
continue;
|
|
3473
|
+
let target;
|
|
3474
|
+
let color;
|
|
3475
|
+
if (aAlpha === 0) {
|
|
3476
|
+
target = addition;
|
|
3477
|
+
color = pallet.addition;
|
|
3478
|
+
}
|
|
3479
|
+
else if (bAlpha === 0) {
|
|
3480
|
+
target = deletion;
|
|
3481
|
+
color = pallet.deletion;
|
|
3482
|
+
}
|
|
3483
|
+
else {
|
|
3484
|
+
target = modification;
|
|
3485
|
+
color = pallet.modification;
|
|
3486
|
+
}
|
|
3487
|
+
target.push([x, y]);
|
|
3488
|
+
diffPixels++;
|
|
3489
|
+
dData[idx] = color[0];
|
|
3490
|
+
dData[idx + 1] = color[1];
|
|
3491
|
+
dData[idx + 2] = color[2];
|
|
3492
|
+
dData[idx + 3] = color[3];
|
|
3355
3493
|
}
|
|
3356
|
-
target.push([x, y]);
|
|
3357
|
-
dData[idx] = color[0];
|
|
3358
|
-
dData[idx + 1] = color[1];
|
|
3359
|
-
dData[idx + 2] = color[2];
|
|
3360
|
-
dData[idx + 3] = color[3];
|
|
3361
3494
|
}
|
|
3362
3495
|
}
|
|
3363
|
-
|
|
3496
|
+
sScan.stop();
|
|
3497
|
+
perf.incr("diff.diffPixels", diffPixels);
|
|
3498
|
+
perf.incr("diff.totalPixels", width * height);
|
|
3499
|
+
perf.incr("diff.pages");
|
|
3500
|
+
return {
|
|
3501
|
+
diff: diffImage,
|
|
3502
|
+
addition,
|
|
3503
|
+
deletion,
|
|
3504
|
+
modification,
|
|
3505
|
+
hasDiff: diffPixels > 0,
|
|
3506
|
+
};
|
|
3364
3507
|
}
|
|
3365
3508
|
|
|
3366
3509
|
/*
|
|
@@ -3406,13 +3549,45 @@ function pixmapToRGBA(pixmap) {
|
|
|
3406
3549
|
}
|
|
3407
3550
|
async function pageToImage(page, dpi, alpha) {
|
|
3408
3551
|
const zoom = dpi / 72;
|
|
3552
|
+
const sToPixmap = perf.span("pdf.toPixmap_ms");
|
|
3409
3553
|
const pixmap = page.toPixmap([zoom, 0, 0, zoom, 0, 0], ColorSpace.DeviceRGB, alpha);
|
|
3410
3554
|
const width = pixmap.getWidth();
|
|
3411
3555
|
const height = pixmap.getHeight();
|
|
3556
|
+
sToPixmap.stop();
|
|
3557
|
+
const sRgba = perf.span("pdf.pixmapToRGBA_ms");
|
|
3412
3558
|
const data = pixmapToRGBA(pixmap);
|
|
3413
3559
|
pixmap.destroy();
|
|
3414
3560
|
page.destroy();
|
|
3415
|
-
|
|
3561
|
+
sRgba.stop();
|
|
3562
|
+
const sFromBitmap = perf.span("pdf.fromBitmap_ms");
|
|
3563
|
+
const result = Jimp.fromBitmap({ width, height, data });
|
|
3564
|
+
sFromBitmap.stop();
|
|
3565
|
+
return result;
|
|
3566
|
+
}
|
|
3567
|
+
|
|
3568
|
+
/*
|
|
3569
|
+
* Copyright (C) 2025 Koutaro Mukai
|
|
3570
|
+
*
|
|
3571
|
+
* This program is free software: you can redistribute it and/or modify
|
|
3572
|
+
* it under the terms of the GNU General Public License as published by
|
|
3573
|
+
* the Free Software Foundation, either version 3 of the License, or
|
|
3574
|
+
* (at your option) any later version.
|
|
3575
|
+
*
|
|
3576
|
+
* This program is distributed in the hope that it will be useful,
|
|
3577
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
3578
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
3579
|
+
* GNU General Public License for more details.
|
|
3580
|
+
*
|
|
3581
|
+
* You should have received a copy of the GNU General Public License
|
|
3582
|
+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
3583
|
+
*/
|
|
3584
|
+
/**
|
|
3585
|
+
* Slice a typed-array view into a standalone backing buffer of the same kind
|
|
3586
|
+
* (ArrayBuffer in, ArrayBuffer out; SharedArrayBuffer in, SharedArrayBuffer
|
|
3587
|
+
* out). The buffer kind is preserved through the generic parameter.
|
|
3588
|
+
*/
|
|
3589
|
+
function sliceBackingBuffer(src) {
|
|
3590
|
+
return src.buffer.slice(src.byteOffset, src.byteOffset + src.byteLength);
|
|
3416
3591
|
}
|
|
3417
3592
|
|
|
3418
3593
|
/*
|
|
@@ -3435,15 +3610,8 @@ let pdfA;
|
|
|
3435
3610
|
let pdfB;
|
|
3436
3611
|
let pdfMask;
|
|
3437
3612
|
let opts;
|
|
3438
|
-
function toTransferable(src) {
|
|
3439
|
-
const view = src instanceof Uint8Array || src instanceof Uint8ClampedArray
|
|
3440
|
-
? src
|
|
3441
|
-
: Uint8Array.from(src);
|
|
3442
|
-
const out = new ArrayBuffer(view.byteLength);
|
|
3443
|
-
new Uint8Array(out).set(view);
|
|
3444
|
-
return out;
|
|
3445
|
-
}
|
|
3446
3613
|
async function processPage(index) {
|
|
3614
|
+
const sLoad = perf.span("worker.pageToImageAll_ms");
|
|
3447
3615
|
const [pageA, pageB, pageMask] = (await Promise.all([
|
|
3448
3616
|
index < pdfA.countPages()
|
|
3449
3617
|
? pageToImage(pdfA.loadPage(index), opts.dpi, opts.alpha)
|
|
@@ -3453,63 +3621,81 @@ async function processPage(index) {
|
|
|
3453
3621
|
: createEmptyImage(1, 1),
|
|
3454
3622
|
index < pdfMask.countPages()
|
|
3455
3623
|
? pageToImage(pdfMask.loadPage(index), opts.dpi, opts.alpha)
|
|
3456
|
-
:
|
|
3624
|
+
: Promise.resolve(null),
|
|
3457
3625
|
]));
|
|
3458
|
-
|
|
3459
|
-
const
|
|
3626
|
+
sLoad.stop();
|
|
3627
|
+
const sDiff = perf.span("worker.drawDifference_ms");
|
|
3628
|
+
const { diff: diffLayer, addition, deletion, modification, hasDiff, } = drawDifference(pageA, pageB, pageMask, opts.pallet, opts.align);
|
|
3629
|
+
sDiff.stop();
|
|
3630
|
+
const sCompose = perf.span("worker.composeLayers_ms");
|
|
3631
|
+
const layers = [
|
|
3460
3632
|
[pageA, 0.2],
|
|
3461
3633
|
[pageB, 0.2],
|
|
3462
|
-
|
|
3463
|
-
|
|
3634
|
+
];
|
|
3635
|
+
if (hasDiff)
|
|
3636
|
+
layers.push([diffLayer, 1]);
|
|
3637
|
+
const diff = composeLayers(pageA.width, pageA.height, layers);
|
|
3638
|
+
sCompose.stop();
|
|
3639
|
+
const sXfer = perf.span("worker.toTransferable_ms");
|
|
3640
|
+
const aBuf = sliceBackingBuffer(pageA.bitmap.data);
|
|
3641
|
+
const bBuf = sliceBackingBuffer(pageB.bitmap.data);
|
|
3642
|
+
const dBuf = sliceBackingBuffer(diff.bitmap.data);
|
|
3643
|
+
sXfer.stop();
|
|
3644
|
+
perf.incr("worker.pages");
|
|
3645
|
+
let pagePerf;
|
|
3646
|
+
if (perf.enabled) {
|
|
3647
|
+
pagePerf = perf.dump();
|
|
3648
|
+
perf.reset();
|
|
3649
|
+
}
|
|
3464
3650
|
return {
|
|
3465
3651
|
type: "pageResult",
|
|
3466
3652
|
index,
|
|
3467
|
-
a: {
|
|
3468
|
-
|
|
3469
|
-
|
|
3470
|
-
data: toTransferable(pageA.bitmap.data),
|
|
3471
|
-
},
|
|
3472
|
-
b: {
|
|
3473
|
-
width: pageB.width,
|
|
3474
|
-
height: pageB.height,
|
|
3475
|
-
data: toTransferable(pageB.bitmap.data),
|
|
3476
|
-
},
|
|
3477
|
-
diff: {
|
|
3478
|
-
width: diff.width,
|
|
3479
|
-
height: diff.height,
|
|
3480
|
-
data: toTransferable(diff.bitmap.data),
|
|
3481
|
-
},
|
|
3653
|
+
a: { width: pageA.width, height: pageA.height, data: aBuf },
|
|
3654
|
+
b: { width: pageB.width, height: pageB.height, data: bBuf },
|
|
3655
|
+
diff: { width: diff.width, height: diff.height, data: dBuf },
|
|
3482
3656
|
addition,
|
|
3483
3657
|
deletion,
|
|
3484
3658
|
modification,
|
|
3659
|
+
perf: pagePerf,
|
|
3485
3660
|
};
|
|
3486
3661
|
}
|
|
3487
3662
|
self.addEventListener("message", async (e) => {
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
|
|
3491
|
-
|
|
3492
|
-
|
|
3493
|
-
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
|
|
3499
|
-
|
|
3500
|
-
|
|
3501
|
-
|
|
3502
|
-
pdfA.
|
|
3503
|
-
|
|
3504
|
-
|
|
3663
|
+
try {
|
|
3664
|
+
const msg = e.data;
|
|
3665
|
+
if (msg.type === "init") {
|
|
3666
|
+
pdfA = PDFDocument.openDocument(msg.aBytes, "application/pdf");
|
|
3667
|
+
pdfB = PDFDocument.openDocument(msg.bBytes, "application/pdf");
|
|
3668
|
+
pdfMask = msg.maskBytes
|
|
3669
|
+
? PDFDocument.openDocument(msg.maskBytes, "application/pdf")
|
|
3670
|
+
: new PDFDocument();
|
|
3671
|
+
opts = {
|
|
3672
|
+
dpi: msg.dpi,
|
|
3673
|
+
alpha: msg.alpha,
|
|
3674
|
+
pallet: msg.pallet,
|
|
3675
|
+
align: msg.align,
|
|
3676
|
+
};
|
|
3677
|
+
if (pdfA.countPages() > 0)
|
|
3678
|
+
pdfA.loadPage(0).destroy();
|
|
3679
|
+
const ready = { type: "ready" };
|
|
3680
|
+
self.postMessage(ready);
|
|
3681
|
+
}
|
|
3682
|
+
else if (msg.type === "page") {
|
|
3683
|
+
const result = await processPage(msg.index);
|
|
3684
|
+
self.postMessage(result, [
|
|
3685
|
+
result.a.data,
|
|
3686
|
+
result.b.data,
|
|
3687
|
+
result.diff.data,
|
|
3688
|
+
]);
|
|
3689
|
+
}
|
|
3505
3690
|
}
|
|
3506
|
-
|
|
3507
|
-
const
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
|
|
3511
|
-
|
|
3512
|
-
]);
|
|
3691
|
+
catch (err) {
|
|
3692
|
+
const errorMsg = {
|
|
3693
|
+
type: "error",
|
|
3694
|
+
message: err instanceof Error ? `${err.message}\n${err.stack}` : String(err),
|
|
3695
|
+
};
|
|
3696
|
+
self.postMessage(errorMsg);
|
|
3513
3697
|
}
|
|
3514
3698
|
});
|
|
3699
|
+
const loaded = { type: "loaded" };
|
|
3700
|
+
self.postMessage(loaded);
|
|
3515
3701
|
//# sourceMappingURL=worker.js.map
|