@embedpdf/engines 2.11.0 → 2.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/dist/browser-B5n5EUyW.cjs +2 -0
  2. package/dist/browser-B5n5EUyW.cjs.map +1 -0
  3. package/dist/{browser-BISJ9naB.js → browser-BKLM0ThC.js} +98 -6
  4. package/dist/browser-BKLM0ThC.js.map +1 -0
  5. package/dist/{direct-engine-cyecHjwI.js → direct-engine-B7gUkBcT.js} +158 -11
  6. package/dist/direct-engine-B7gUkBcT.js.map +1 -0
  7. package/dist/direct-engine-DDe3a0AP.cjs +2 -0
  8. package/dist/direct-engine-DDe3a0AP.cjs.map +1 -0
  9. package/dist/index.cjs +1 -1
  10. package/dist/index.js +3 -3
  11. package/dist/lib/converters/index.cjs +1 -1
  12. package/dist/lib/converters/index.js +1 -1
  13. package/dist/lib/image-encoder/bmp.d.ts +13 -0
  14. package/dist/lib/image-encoder/image-encoder-worker.d.ts +1 -1
  15. package/dist/lib/image-encoder/worker-pool.d.ts +1 -1
  16. package/dist/lib/pdfium/engine.d.ts +16 -0
  17. package/dist/lib/pdfium/index.cjs +1 -1
  18. package/dist/lib/pdfium/index.js +4 -4
  19. package/dist/lib/pdfium/web/direct-engine.cjs +1 -1
  20. package/dist/lib/pdfium/web/direct-engine.js +3 -3
  21. package/dist/lib/pdfium/web/worker-engine.cjs +1 -1
  22. package/dist/lib/pdfium/web/worker-engine.cjs.map +1 -1
  23. package/dist/lib/pdfium/web/worker-engine.js +130 -5
  24. package/dist/lib/pdfium/web/worker-engine.js.map +1 -1
  25. package/dist/{pdf-engine-Dj-haWhC.js → pdf-engine-D9v0RfKe.js} +3 -3
  26. package/dist/pdf-engine-D9v0RfKe.js.map +1 -0
  27. package/dist/pdf-engine-DeiICuca.cjs +2 -0
  28. package/dist/pdf-engine-DeiICuca.cjs.map +1 -0
  29. package/dist/preact/index.cjs +1 -1
  30. package/dist/preact/index.js +1 -1
  31. package/dist/react/index.cjs +1 -1
  32. package/dist/react/index.js +1 -1
  33. package/dist/svelte/index.cjs +1 -1
  34. package/dist/svelte/index.js +1 -1
  35. package/dist/vue/index.cjs +1 -1
  36. package/dist/vue/index.js +1 -1
  37. package/package.json +4 -4
  38. package/dist/browser-13mzox-R.cjs +0 -2
  39. package/dist/browser-13mzox-R.cjs.map +0 -1
  40. package/dist/browser-BISJ9naB.js.map +0 -1
  41. package/dist/direct-engine-BNQEVS9L.cjs +0 -2
  42. package/dist/direct-engine-BNQEVS9L.cjs.map +0 -1
  43. package/dist/direct-engine-cyecHjwI.js.map +0 -1
  44. package/dist/pdf-engine-BoFryxxe.cjs +0 -2
  45. package/dist/pdf-engine-BoFryxxe.cjs.map +0 -1
  46. package/dist/pdf-engine-Dj-haWhC.js.map +0 -1
@@ -0,0 +1,2 @@
1
+ "use strict";function e(e,t,r){const n=t*r*4,a=e=>[255&e,e>>>8&255,e>>>16&255,e>>>24&255],o=new Uint8Array([66,77,...a(66+n),0,0,0,0,66,0,0,0,40,0,0,0,...a(t),...a(-r),1,0,32,0,3,0,0,0,...a(n),0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,255,0,0,0,0,255,0]);return new Blob([o,new Uint8Array(e.buffer,e.byteOffset,e.byteLength)],{type:"image/bmp"})}class t extends Error{constructor(e){super(e),this.name="ImageConverterError"}}const r=(r,n="image/png",a)=>{const o=r();if("image/bmp"===n)return Promise.resolve(e(o.data,o.width,o.height));if("undefined"==typeof document)return Promise.reject(new t("document is not available. This converter requires a browser environment."));const i=new ImageData(o.data,o.width,o.height);return new Promise((e,r)=>{const o=document.createElement("canvas");o.width=i.width,o.height=i.height,o.getContext("2d").putImageData(i,0,0),o.toBlob(n=>{n?e(n):r(new t("Canvas toBlob returned null"))},n,a)})};exports.ImageConverterError=t,exports.browserImageDataToBlobConverter=r,exports.createHybridImageConverter=function(t){const n=async(n,a="image/png",o)=>{const i=n();if("image/bmp"===a)return e(i.data,i.width,i.height);try{const e=new Uint8ClampedArray(i.data);return await t.encode({data:e,width:i.width,height:i.height},a,o)}catch(s){return console.warn("Worker encoding failed, falling back to main-thread Canvas:",s),r(n,a,o)}};return n.destroy=()=>t.destroy(),n},exports.createWorkerPoolImageConverter=function(t){const r=(r,n="image/png",a)=>{const o=r();if("image/bmp"===n)return Promise.resolve(e(o.data,o.width,o.height));const i=new Uint8ClampedArray(o.data);return t.encode({data:i,width:o.width,height:o.height},n,a)};return r.destroy=()=>t.destroy(),r};
2
+ //# sourceMappingURL=browser-B5n5EUyW.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-B5n5EUyW.cjs","sources":["../src/lib/image-encoder/bmp.ts","../src/lib/converters/browser.ts"],"sourcesContent":["/**\n * Creates an uncompressed BMP blob from raw RGBA pixel data.\n *\n * Uses BI_BITFIELDS with channel masks matching RGBA byte order, so no\n * per-pixel byte swapping is needed. Top-down row order (negative height)\n * avoids row flipping. The result is a valid BMP that all modern browsers\n * can decode natively in `<img>` elements.\n *\n * This is dramatically faster than PNG/WebP/JPEG encoding via canvas.toBlob()\n * because it performs no compression — just a 66-byte header prepended to the\n * raw pixel buffer.\n */\nexport function rgbaToBmpBlob(rgba: Uint8ClampedArray, width: number, height: number): Blob {\n const pixels = width * height * 4;\n const headerLength = 66;\n const le32 = (v: number) => [v & 0xff, (v >>> 8) & 0xff, (v >>> 16) & 0xff, (v >>> 24) & 0xff];\n\n // prettier-ignore\n const header = new Uint8Array([\n 0x42, 0x4D, // 'BM' signature\n ...le32(headerLength + pixels), // file size\n 0, 0, 0, 0, // reserved\n headerLength, 0, 0, 0, // pixel data offset\n 40, 0, 0, 0, // DIB header size\n ...le32(width), // width\n ...le32(-height), // height (negative = top-down)\n 1, 0, // color planes\n 32, 0, // bits per pixel\n 3, 0, 0, 0, // compression = BI_BITFIELDS\n ...le32(pixels), // image data size\n 0, 0, 0, 0, // h resolution\n 0, 0, 0, 0, // v resolution\n 0, 0, 0, 0, // colors in palette\n 0, 0, 0, 0, // important colors\n 0xFF, 0, 0, 0, // R channel mask\n 0, 0xFF, 0, 0, // G channel mask\n 0, 0, 0xFF, 0, // B channel mask\n ]);\n\n return new Blob(\n [header, new Uint8Array(rgba.buffer as ArrayBuffer, rgba.byteOffset, rgba.byteLength)],\n { type: 'image/bmp' },\n );\n}\n","import type { ImageConversionTypes } from '@embedpdf/models';\nimport type { ImageDataConverter, LazyImageData } from './types';\nimport { ImageEncoderWorkerPool } from '../image-encoder';\nimport { rgbaToBmpBlob } from '../image-encoder/bmp';\n\n// ============================================================================\n// Error Classes\n// ============================================================================\n\nexport class ImageConverterError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'ImageConverterError';\n }\n}\n\n// ============================================================================\n// Browser Converters\n// ============================================================================\n\n/**\n * Main-thread Canvas-based image converter\n * Simple and works everywhere, but blocks the main thread during encoding\n *\n * Use this as a fallback when worker-based encoding isn't available\n */\nexport const browserImageDataToBlobConverter: ImageDataConverter<Blob> = (\n getImageData: LazyImageData,\n imageType: ImageConversionTypes = 'image/png',\n quality?: number,\n): Promise<Blob> => {\n const pdfImage = getImageData();\n\n // Fast path: BMP needs no canvas — just a header prepended to raw pixels\n if (imageType === 'image/bmp') {\n return Promise.resolve(rgbaToBmpBlob(pdfImage.data, pdfImage.width, pdfImage.height));\n }\n\n if (typeof document === 'undefined') {\n return Promise.reject(\n new ImageConverterError(\n 'document is not available. This converter requires a browser environment.',\n ),\n );\n }\n\n const imageData = new ImageData(pdfImage.data, pdfImage.width, pdfImage.height);\n\n return new Promise((resolve, reject) => {\n const canvas = document.createElement('canvas');\n canvas.width = imageData.width;\n canvas.height = imageData.height;\n canvas.getContext('2d')!.putImageData(imageData, 0, 0);\n\n canvas.toBlob(\n (blob) => {\n if (blob) {\n resolve(blob);\n } else {\n reject(new ImageConverterError('Canvas toBlob returned null'));\n }\n },\n imageType,\n quality,\n );\n });\n};\n\n/**\n * Worker pool image converter using OffscreenCanvas in dedicated workers\n * Non-blocking - encoding happens off the main thread\n *\n * This is the preferred approach for performance\n *\n * @param workerPool - Instance of ImageEncoderWorkerPool\n * @returns ImageDataConverter function with destroy() for cleanup\n */\nexport function createWorkerPoolImageConverter(\n workerPool: ImageEncoderWorkerPool,\n): ImageDataConverter<Blob> {\n const converter: ImageDataConverter<Blob> = (\n getImageData: LazyImageData,\n imageType: ImageConversionTypes = 'image/png',\n quality?: number,\n ): Promise<Blob> => {\n const pdfImage = getImageData();\n\n // Fast path: BMP needs no worker round-trip\n if (imageType === 'image/bmp') {\n return Promise.resolve(rgbaToBmpBlob(pdfImage.data, pdfImage.width, pdfImage.height));\n }\n\n // Copy the data since we'll transfer it to another worker\n const dataCopy = new Uint8ClampedArray(pdfImage.data);\n\n return workerPool.encode(\n {\n data: dataCopy,\n width: pdfImage.width,\n height: pdfImage.height,\n },\n imageType,\n quality,\n );\n };\n\n // Attach destroy method to clean up worker pool\n converter.destroy = () => workerPool.destroy();\n\n return converter;\n}\n\n/**\n * Hybrid converter: Worker pool (OffscreenCanvas) → Main thread Canvas fallback\n *\n * Best of both worlds:\n * - Primary: Non-blocking worker-based encoding with OffscreenCanvas\n * - Fallback: Main-thread Canvas for older browsers without OffscreenCanvas in workers\n *\n * @param workerPool - Instance of ImageEncoderWorkerPool\n * @returns ImageDataConverter function with destroy() for cleanup\n */\nexport function createHybridImageConverter(\n workerPool: ImageEncoderWorkerPool,\n): ImageDataConverter<Blob> {\n const converter: ImageDataConverter<Blob> = async (\n getImageData: LazyImageData,\n imageType: ImageConversionTypes = 'image/png',\n quality?: number,\n ): Promise<Blob> => {\n const pdfImage = getImageData();\n\n // Fast path: BMP needs no worker round-trip\n if (imageType === 'image/bmp') {\n return rgbaToBmpBlob(pdfImage.data, pdfImage.width, pdfImage.height);\n }\n\n try {\n // Try worker pool encoding first (OffscreenCanvas in worker)\n const dataCopy = new Uint8ClampedArray(pdfImage.data);\n\n return await workerPool.encode(\n {\n data: dataCopy,\n width: pdfImage.width,\n height: pdfImage.height,\n },\n imageType,\n quality,\n );\n } catch (error) {\n // Fallback to main-thread Canvas\n console.warn('Worker encoding failed, falling back to main-thread Canvas:', error);\n return browserImageDataToBlobConverter(getImageData, imageType, quality);\n }\n };\n\n // Attach destroy method to clean up worker pool\n converter.destroy = () => workerPool.destroy();\n\n return converter;\n}\n"],"names":["rgbaToBmpBlob","rgba","width","height","pixels","le32","v","header","Uint8Array","Blob","buffer","byteOffset","byteLength","type","ImageConverterError","Error","constructor","message","super","this","name","browserImageDataToBlobConverter","getImageData","imageType","quality","pdfImage","Promise","resolve","data","document","reject","imageData","ImageData","canvas","createElement","getContext","putImageData","toBlob","blob","workerPool","converter","async","dataCopy","Uint8ClampedArray","encode","error","console","warn","destroy"],"mappings":"aAYO,SAASA,EAAcC,EAAyBC,EAAeC,GACpE,MAAMC,EAASF,EAAQC,EAAS,EAE1BE,EAAQC,GAAc,CAAK,IAAJA,EAAWA,IAAM,EAAK,IAAOA,IAAM,GAAM,IAAOA,IAAM,GAAM,KAGnFC,EAAS,IAAIC,WAAW,CAC5B,GAAM,MACHH,EANgB,GAMID,GACvB,EAAG,EAAG,EAAG,EAPU,GAQL,EAAG,EAAG,EACpB,GAAI,EAAG,EAAG,KACPC,EAAKH,MACLG,GAAMF,GACT,EAAG,EACH,GAAI,EACJ,EAAG,EAAG,EAAG,KACNE,EAAKD,GACR,EAAG,EAAG,EAAG,EACT,EAAG,EAAG,EAAG,EACT,EAAG,EAAG,EAAG,EACT,EAAG,EAAG,EAAG,EACT,IAAM,EAAG,EAAG,EACZ,EAAG,IAAM,EAAG,EACZ,EAAG,EAAG,IAAM,IAGd,OAAO,IAAIK,KACT,CAACF,EAAQ,IAAIC,WAAWP,EAAKS,OAAuBT,EAAKU,WAAYV,EAAKW,aAC1E,CAAEC,KAAM,aAEZ,CClCO,MAAMC,UAA4BC,MACvC,WAAAC,CAAYC,GACVC,MAAMD,GACNE,KAAKC,KAAO,qBACd,EAaK,MAAMC,EAA4D,CACvEC,EACAC,EAAkC,YAClCC,KAEA,MAAMC,EAAWH,IAGjB,GAAkB,cAAdC,EACF,OAAOG,QAAQC,QAAQ3B,EAAcyB,EAASG,KAAMH,EAASvB,MAAOuB,EAAStB,SAG/E,GAAwB,oBAAb0B,SACT,OAAOH,QAAQI,OACb,IAAIhB,EACF,8EAKN,MAAMiB,EAAY,IAAIC,UAAUP,EAASG,KAAMH,EAASvB,MAAOuB,EAAStB,QAExE,OAAO,IAAIuB,QAAQ,CAACC,EAASG,KAC3B,MAAMG,EAASJ,SAASK,cAAc,UACtCD,EAAO/B,MAAQ6B,EAAU7B,MACzB+B,EAAO9B,OAAS4B,EAAU5B,OAC1B8B,EAAOE,WAAW,MAAOC,aAAaL,EAAW,EAAG,GAEpDE,EAAOI,OACJC,IACKA,EACFX,EAAQW,GAERR,EAAO,IAAIhB,EAAoB,iCAGnCS,EACAC,iHA2DC,SACLe,GAEA,MAAMC,EAAsCC,MAC1CnB,EACAC,EAAkC,YAClCC,KAEA,MAAMC,EAAWH,IAGjB,GAAkB,cAAdC,EACF,OAAOvB,EAAcyB,EAASG,KAAMH,EAASvB,MAAOuB,EAAStB,QAG/D,IAEE,MAAMuC,EAAW,IAAIC,kBAAkBlB,EAASG,MAEhD,aAAaW,EAAWK,OACtB,CACEhB,KAAMc,EACNxC,MAAOuB,EAASvB,MAChBC,OAAQsB,EAAStB,QAEnBoB,EACAC,EAEJ,OAASqB,GAGP,OADAC,QAAQC,KAAK,8DAA+DF,GACrExB,EAAgCC,EAAcC,EAAWC,EAClE,GAMF,OAFAgB,EAAUQ,QAAU,IAAMT,EAAWS,UAE9BR,CACT,yCApFO,SACLD,GAEA,MAAMC,EAAsC,CAC1ClB,EACAC,EAAkC,YAClCC,KAEA,MAAMC,EAAWH,IAGjB,GAAkB,cAAdC,EACF,OAAOG,QAAQC,QAAQ3B,EAAcyB,EAASG,KAAMH,EAASvB,MAAOuB,EAAStB,SAI/E,MAAMuC,EAAW,IAAIC,kBAAkBlB,EAASG,MAEhD,OAAOW,EAAWK,OAChB,CACEhB,KAAMc,EACNxC,MAAOuB,EAASvB,MAChBC,OAAQsB,EAAStB,QAEnBoB,EACAC,IAOJ,OAFAgB,EAAUQ,QAAU,IAAMT,EAAWS,UAE9BR,CACT"}
@@ -1,10 +1,97 @@
1
+ function rgbaToBmpBlob(rgba, width, height) {
2
+ const pixels = width * height * 4;
3
+ const headerLength = 66;
4
+ const le32 = (v) => [v & 255, v >>> 8 & 255, v >>> 16 & 255, v >>> 24 & 255];
5
+ const header = new Uint8Array([
6
+ 66,
7
+ 77,
8
+ // 'BM' signature
9
+ ...le32(headerLength + pixels),
10
+ // file size
11
+ 0,
12
+ 0,
13
+ 0,
14
+ 0,
15
+ // reserved
16
+ headerLength,
17
+ 0,
18
+ 0,
19
+ 0,
20
+ // pixel data offset
21
+ 40,
22
+ 0,
23
+ 0,
24
+ 0,
25
+ // DIB header size
26
+ ...le32(width),
27
+ // width
28
+ ...le32(-height),
29
+ // height (negative = top-down)
30
+ 1,
31
+ 0,
32
+ // color planes
33
+ 32,
34
+ 0,
35
+ // bits per pixel
36
+ 3,
37
+ 0,
38
+ 0,
39
+ 0,
40
+ // compression = BI_BITFIELDS
41
+ ...le32(pixels),
42
+ // image data size
43
+ 0,
44
+ 0,
45
+ 0,
46
+ 0,
47
+ // h resolution
48
+ 0,
49
+ 0,
50
+ 0,
51
+ 0,
52
+ // v resolution
53
+ 0,
54
+ 0,
55
+ 0,
56
+ 0,
57
+ // colors in palette
58
+ 0,
59
+ 0,
60
+ 0,
61
+ 0,
62
+ // important colors
63
+ 255,
64
+ 0,
65
+ 0,
66
+ 0,
67
+ // R channel mask
68
+ 0,
69
+ 255,
70
+ 0,
71
+ 0,
72
+ // G channel mask
73
+ 0,
74
+ 0,
75
+ 255,
76
+ 0
77
+ // B channel mask
78
+ ]);
79
+ return new Blob(
80
+ [header, new Uint8Array(rgba.buffer, rgba.byteOffset, rgba.byteLength)],
81
+ { type: "image/bmp" }
82
+ );
83
+ }
1
84
  class ImageConverterError extends Error {
2
85
  constructor(message) {
3
86
  super(message);
4
87
  this.name = "ImageConverterError";
5
88
  }
6
89
  }
7
- const browserImageDataToBlobConverter = (getImageData, imageType = "image/webp", quality) => {
90
+ const browserImageDataToBlobConverter = (getImageData, imageType = "image/png", quality) => {
91
+ const pdfImage = getImageData();
92
+ if (imageType === "image/bmp") {
93
+ return Promise.resolve(rgbaToBmpBlob(pdfImage.data, pdfImage.width, pdfImage.height));
94
+ }
8
95
  if (typeof document === "undefined") {
9
96
  return Promise.reject(
10
97
  new ImageConverterError(
@@ -12,7 +99,6 @@ const browserImageDataToBlobConverter = (getImageData, imageType = "image/webp",
12
99
  )
13
100
  );
14
101
  }
15
- const pdfImage = getImageData();
16
102
  const imageData = new ImageData(pdfImage.data, pdfImage.width, pdfImage.height);
17
103
  return new Promise((resolve, reject) => {
18
104
  const canvas = document.createElement("canvas");
@@ -33,8 +119,11 @@ const browserImageDataToBlobConverter = (getImageData, imageType = "image/webp",
33
119
  });
34
120
  };
35
121
  function createWorkerPoolImageConverter(workerPool) {
36
- const converter = (getImageData, imageType = "image/webp", quality) => {
122
+ const converter = (getImageData, imageType = "image/png", quality) => {
37
123
  const pdfImage = getImageData();
124
+ if (imageType === "image/bmp") {
125
+ return Promise.resolve(rgbaToBmpBlob(pdfImage.data, pdfImage.width, pdfImage.height));
126
+ }
38
127
  const dataCopy = new Uint8ClampedArray(pdfImage.data);
39
128
  return workerPool.encode(
40
129
  {
@@ -50,9 +139,12 @@ function createWorkerPoolImageConverter(workerPool) {
50
139
  return converter;
51
140
  }
52
141
  function createHybridImageConverter(workerPool) {
53
- const converter = async (getImageData, imageType = "image/webp", quality) => {
142
+ const converter = async (getImageData, imageType = "image/png", quality) => {
143
+ const pdfImage = getImageData();
144
+ if (imageType === "image/bmp") {
145
+ return rgbaToBmpBlob(pdfImage.data, pdfImage.width, pdfImage.height);
146
+ }
54
147
  try {
55
- const pdfImage = getImageData();
56
148
  const dataCopy = new Uint8ClampedArray(pdfImage.data);
57
149
  return await workerPool.encode(
58
150
  {
@@ -77,4 +169,4 @@ export {
77
169
  browserImageDataToBlobConverter as b,
78
170
  createHybridImageConverter as c
79
171
  };
80
- //# sourceMappingURL=browser-BISJ9naB.js.map
172
+ //# sourceMappingURL=browser-BKLM0ThC.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-BKLM0ThC.js","sources":["../src/lib/image-encoder/bmp.ts","../src/lib/converters/browser.ts"],"sourcesContent":["/**\n * Creates an uncompressed BMP blob from raw RGBA pixel data.\n *\n * Uses BI_BITFIELDS with channel masks matching RGBA byte order, so no\n * per-pixel byte swapping is needed. Top-down row order (negative height)\n * avoids row flipping. The result is a valid BMP that all modern browsers\n * can decode natively in `<img>` elements.\n *\n * This is dramatically faster than PNG/WebP/JPEG encoding via canvas.toBlob()\n * because it performs no compression — just a 66-byte header prepended to the\n * raw pixel buffer.\n */\nexport function rgbaToBmpBlob(rgba: Uint8ClampedArray, width: number, height: number): Blob {\n const pixels = width * height * 4;\n const headerLength = 66;\n const le32 = (v: number) => [v & 0xff, (v >>> 8) & 0xff, (v >>> 16) & 0xff, (v >>> 24) & 0xff];\n\n // prettier-ignore\n const header = new Uint8Array([\n 0x42, 0x4D, // 'BM' signature\n ...le32(headerLength + pixels), // file size\n 0, 0, 0, 0, // reserved\n headerLength, 0, 0, 0, // pixel data offset\n 40, 0, 0, 0, // DIB header size\n ...le32(width), // width\n ...le32(-height), // height (negative = top-down)\n 1, 0, // color planes\n 32, 0, // bits per pixel\n 3, 0, 0, 0, // compression = BI_BITFIELDS\n ...le32(pixels), // image data size\n 0, 0, 0, 0, // h resolution\n 0, 0, 0, 0, // v resolution\n 0, 0, 0, 0, // colors in palette\n 0, 0, 0, 0, // important colors\n 0xFF, 0, 0, 0, // R channel mask\n 0, 0xFF, 0, 0, // G channel mask\n 0, 0, 0xFF, 0, // B channel mask\n ]);\n\n return new Blob(\n [header, new Uint8Array(rgba.buffer as ArrayBuffer, rgba.byteOffset, rgba.byteLength)],\n { type: 'image/bmp' },\n );\n}\n","import type { ImageConversionTypes } from '@embedpdf/models';\nimport type { ImageDataConverter, LazyImageData } from './types';\nimport { ImageEncoderWorkerPool } from '../image-encoder';\nimport { rgbaToBmpBlob } from '../image-encoder/bmp';\n\n// ============================================================================\n// Error Classes\n// ============================================================================\n\nexport class ImageConverterError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'ImageConverterError';\n }\n}\n\n// ============================================================================\n// Browser Converters\n// ============================================================================\n\n/**\n * Main-thread Canvas-based image converter\n * Simple and works everywhere, but blocks the main thread during encoding\n *\n * Use this as a fallback when worker-based encoding isn't available\n */\nexport const browserImageDataToBlobConverter: ImageDataConverter<Blob> = (\n getImageData: LazyImageData,\n imageType: ImageConversionTypes = 'image/png',\n quality?: number,\n): Promise<Blob> => {\n const pdfImage = getImageData();\n\n // Fast path: BMP needs no canvas — just a header prepended to raw pixels\n if (imageType === 'image/bmp') {\n return Promise.resolve(rgbaToBmpBlob(pdfImage.data, pdfImage.width, pdfImage.height));\n }\n\n if (typeof document === 'undefined') {\n return Promise.reject(\n new ImageConverterError(\n 'document is not available. This converter requires a browser environment.',\n ),\n );\n }\n\n const imageData = new ImageData(pdfImage.data, pdfImage.width, pdfImage.height);\n\n return new Promise((resolve, reject) => {\n const canvas = document.createElement('canvas');\n canvas.width = imageData.width;\n canvas.height = imageData.height;\n canvas.getContext('2d')!.putImageData(imageData, 0, 0);\n\n canvas.toBlob(\n (blob) => {\n if (blob) {\n resolve(blob);\n } else {\n reject(new ImageConverterError('Canvas toBlob returned null'));\n }\n },\n imageType,\n quality,\n );\n });\n};\n\n/**\n * Worker pool image converter using OffscreenCanvas in dedicated workers\n * Non-blocking - encoding happens off the main thread\n *\n * This is the preferred approach for performance\n *\n * @param workerPool - Instance of ImageEncoderWorkerPool\n * @returns ImageDataConverter function with destroy() for cleanup\n */\nexport function createWorkerPoolImageConverter(\n workerPool: ImageEncoderWorkerPool,\n): ImageDataConverter<Blob> {\n const converter: ImageDataConverter<Blob> = (\n getImageData: LazyImageData,\n imageType: ImageConversionTypes = 'image/png',\n quality?: number,\n ): Promise<Blob> => {\n const pdfImage = getImageData();\n\n // Fast path: BMP needs no worker round-trip\n if (imageType === 'image/bmp') {\n return Promise.resolve(rgbaToBmpBlob(pdfImage.data, pdfImage.width, pdfImage.height));\n }\n\n // Copy the data since we'll transfer it to another worker\n const dataCopy = new Uint8ClampedArray(pdfImage.data);\n\n return workerPool.encode(\n {\n data: dataCopy,\n width: pdfImage.width,\n height: pdfImage.height,\n },\n imageType,\n quality,\n );\n };\n\n // Attach destroy method to clean up worker pool\n converter.destroy = () => workerPool.destroy();\n\n return converter;\n}\n\n/**\n * Hybrid converter: Worker pool (OffscreenCanvas) → Main thread Canvas fallback\n *\n * Best of both worlds:\n * - Primary: Non-blocking worker-based encoding with OffscreenCanvas\n * - Fallback: Main-thread Canvas for older browsers without OffscreenCanvas in workers\n *\n * @param workerPool - Instance of ImageEncoderWorkerPool\n * @returns ImageDataConverter function with destroy() for cleanup\n */\nexport function createHybridImageConverter(\n workerPool: ImageEncoderWorkerPool,\n): ImageDataConverter<Blob> {\n const converter: ImageDataConverter<Blob> = async (\n getImageData: LazyImageData,\n imageType: ImageConversionTypes = 'image/png',\n quality?: number,\n ): Promise<Blob> => {\n const pdfImage = getImageData();\n\n // Fast path: BMP needs no worker round-trip\n if (imageType === 'image/bmp') {\n return rgbaToBmpBlob(pdfImage.data, pdfImage.width, pdfImage.height);\n }\n\n try {\n // Try worker pool encoding first (OffscreenCanvas in worker)\n const dataCopy = new Uint8ClampedArray(pdfImage.data);\n\n return await workerPool.encode(\n {\n data: dataCopy,\n width: pdfImage.width,\n height: pdfImage.height,\n },\n imageType,\n quality,\n );\n } catch (error) {\n // Fallback to main-thread Canvas\n console.warn('Worker encoding failed, falling back to main-thread Canvas:', error);\n return browserImageDataToBlobConverter(getImageData, imageType, quality);\n }\n };\n\n // Attach destroy method to clean up worker pool\n converter.destroy = () => workerPool.destroy();\n\n return converter;\n}\n"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { init } from "@embedpdf/pdfium";
2
- import { Rotation, NoopLogger, PdfTaskHelper, PdfErrorCode, pdfDateToDate, PdfJavaScriptActionTrigger, PdfAnnotationSubtype, isUuidV4, uuidV4, PdfJavaScriptWidgetEventType, PDF_ANNOT_AACTION_EVENT, PDF_FORM_FIELD_TYPE, PdfPageFlattenFlag, stripPdfUnwantedMarkers, PdfAnnotationName, PdfAnnotationColorType, PdfAnnotationBorderStyle, PdfStandardFont, PDF_FORM_FIELD_FLAG, webColorToPdfColor, pdfColorToWebColor, PdfAnnotationLineEnding, PdfStampFit, PdfTrappedStatus, pdfAlphaToWebOpacity, webOpacityToPdfAlpha, PdfAnnotationReplyType, dateToPdfDate, quadToRect, rectToQuad, PdfPageObjectType, flagsToNames, namesToFlags, AppearanceMode, Task, toIntRect, transformRect, buildUserToDeviceMatrix, AP_MODE_NORMAL, AP_MODE_ROLLOVER, AP_MODE_DOWN, PdfZoomMode, PdfActionType } from "@embedpdf/models";
3
- import { P as PdfEngine } from "./pdf-engine-Dj-haWhC.js";
4
- import { b as browserImageDataToBlobConverter } from "./browser-BISJ9naB.js";
2
+ import { Rotation, NoopLogger, PdfTaskHelper, PdfErrorCode, pdfDateToDate, PdfJavaScriptActionTrigger, PdfAnnotationSubtype, isUuidV4, uuidV4, PdfJavaScriptWidgetEventType, PDF_ANNOT_AACTION_EVENT, PDF_FORM_FIELD_TYPE, PdfPageFlattenFlag, stripPdfUnwantedMarkers, PdfAnnotationName, PdfAnnotationColorType, PdfAnnotationBorderStyle, PdfStandardFont, PDF_FORM_FIELD_FLAG, webColorToPdfColor, pdfColorToWebColor, PdfAnnotationLineEnding, getImageMetadata, PdfStampFit, PdfTrappedStatus, pdfAlphaToWebOpacity, webOpacityToPdfAlpha, PdfAnnotationReplyType, dateToPdfDate, quadToRect, rectToQuad, PdfPageObjectType, flagsToNames, namesToFlags, AppearanceMode, Task, toIntRect, transformRect, buildUserToDeviceMatrix, AP_MODE_NORMAL, AP_MODE_ROLLOVER, AP_MODE_DOWN, PdfZoomMode, PdfActionType } from "@embedpdf/models";
3
+ import { P as PdfEngine } from "./pdf-engine-D9v0RfKe.js";
4
+ import { b as browserImageDataToBlobConverter } from "./browser-BKLM0ThC.js";
5
5
  function readString(wasmModule, readChars, parseChars, defaultLength = 100) {
6
6
  let buffer = wasmModule.wasmExports.malloc(defaultLength);
7
7
  for (let i = 0; i < defaultLength; i++) {
@@ -4104,9 +4104,42 @@ class PdfiumNative {
4104
4104
  if (stampName && !this.setAnnotationName(annotationPtr, stampName)) {
4105
4105
  return false;
4106
4106
  }
4107
- if (context && "appearance" in context && context.appearance) {
4108
- if (!this.setAppearanceFromPdf(docPtr, annotationPtr, context.appearance)) {
4109
- return false;
4107
+ if (context && "data" in context && context.data) {
4108
+ const meta = getImageMetadata(context.data);
4109
+ if (!meta) return false;
4110
+ if (meta.mimeType === "application/pdf") {
4111
+ if (!this.setAppearanceFromPdf(docPtr, annotationPtr, context.data)) {
4112
+ return false;
4113
+ }
4114
+ } else {
4115
+ for (let i = this.pdfiumModule.FPDFAnnot_GetObjectCount(annotationPtr) - 1; i >= 0; i--) {
4116
+ this.pdfiumModule.FPDFAnnot_RemoveObject(annotationPtr, i);
4117
+ }
4118
+ if (meta.mimeType === "image/png") {
4119
+ if (!this.addPngImageObject(
4120
+ doc,
4121
+ docPtr,
4122
+ page,
4123
+ pagePtr,
4124
+ annotationPtr,
4125
+ annotation.rect,
4126
+ context.data
4127
+ )) {
4128
+ return false;
4129
+ }
4130
+ } else if (meta.mimeType === "image/jpeg") {
4131
+ if (!this.addJpegImageObject(
4132
+ doc,
4133
+ docPtr,
4134
+ page,
4135
+ pagePtr,
4136
+ annotationPtr,
4137
+ annotation.rect,
4138
+ context.data
4139
+ )) {
4140
+ return false;
4141
+ }
4142
+ }
4110
4143
  }
4111
4144
  } else if (context && "imageData" in context && context.imageData) {
4112
4145
  for (let i = this.pdfiumModule.FPDFAnnot_GetObjectCount(annotationPtr) - 1; i >= 0; i--) {
@@ -4123,6 +4156,10 @@ class PdfiumNative {
4123
4156
  )) {
4124
4157
  return false;
4125
4158
  }
4159
+ } else if (context && "appearance" in context && context.appearance) {
4160
+ if (!this.setAppearanceFromPdf(docPtr, annotationPtr, context.appearance)) {
4161
+ return false;
4162
+ }
4126
4163
  }
4127
4164
  if (!this.applyBaseAnnotationProperties(doc, page, pagePtr, annotationPtr, annotation)) {
4128
4165
  return false;
@@ -4203,10 +4240,10 @@ class PdfiumNative {
4203
4240
  return false;
4204
4241
  }
4205
4242
  const matrixPtr = this.memoryManager.malloc(6 * 4);
4206
- this.pdfiumModule.pdfium.setValue(matrixPtr, imageData.width, "float");
4243
+ this.pdfiumModule.pdfium.setValue(matrixPtr, rect.size.width, "float");
4207
4244
  this.pdfiumModule.pdfium.setValue(matrixPtr + 4, 0, "float");
4208
4245
  this.pdfiumModule.pdfium.setValue(matrixPtr + 8, 0, "float");
4209
- this.pdfiumModule.pdfium.setValue(matrixPtr + 12, imageData.height, "float");
4246
+ this.pdfiumModule.pdfium.setValue(matrixPtr + 12, rect.size.height, "float");
4210
4247
  this.pdfiumModule.pdfium.setValue(matrixPtr + 16, 0, "float");
4211
4248
  this.pdfiumModule.pdfium.setValue(matrixPtr + 20, 0, "float");
4212
4249
  if (!this.pdfiumModule.FPDFPageObj_SetMatrix(imageObjectPtr, matrixPtr)) {
@@ -4219,8 +4256,8 @@ class PdfiumNative {
4219
4256
  this.memoryManager.free(matrixPtr);
4220
4257
  const pagePos = this.convertDevicePointToPagePoint(doc, page, {
4221
4258
  x: rect.origin.x,
4222
- y: rect.origin.y + imageData.height
4223
- // shift down by the image height
4259
+ y: rect.origin.y + rect.size.height
4260
+ // shift down by the authored display height
4224
4261
  });
4225
4262
  this.pdfiumModule.FPDFPageObj_Transform(imageObjectPtr, 1, 0, 0, 1, pagePos.x, pagePos.y);
4226
4263
  if (!this.pdfiumModule.FPDFAnnot_AppendObject(annotationPtr, imageObjectPtr)) {
@@ -4233,6 +4270,116 @@ class PdfiumNative {
4233
4270
  this.memoryManager.free(bitmapBufferPtr);
4234
4271
  return true;
4235
4272
  }
4273
+ /**
4274
+ * Add PNG image object to annotation using native PNG import.
4275
+ * Passes raw PNG bytes to PDFium which decodes and stores them with
4276
+ * FlateDecode + PNG prediction filters for optimal compression.
4277
+ *
4278
+ * @private
4279
+ */
4280
+ addPngImageObject(doc, docPtr, page, pagePtr, annotationPtr, rect, pngData) {
4281
+ const imageObjectPtr = this.pdfiumModule.FPDFPageObj_NewImageObj(docPtr);
4282
+ if (!imageObjectPtr) {
4283
+ return false;
4284
+ }
4285
+ const pngBytes = new Uint8Array(pngData);
4286
+ const pngPtr = this.memoryManager.malloc(pngBytes.byteLength);
4287
+ if (!pngPtr) {
4288
+ this.pdfiumModule.FPDFPageObj_Destroy(imageObjectPtr);
4289
+ return false;
4290
+ }
4291
+ this.pdfiumModule.pdfium.HEAPU8.set(pngBytes, pngPtr);
4292
+ if (!this.pdfiumModule.EPDFImageObj_SetPng(
4293
+ pagePtr,
4294
+ 0,
4295
+ imageObjectPtr,
4296
+ pngPtr,
4297
+ pngBytes.byteLength
4298
+ )) {
4299
+ this.memoryManager.free(pngPtr);
4300
+ this.pdfiumModule.FPDFPageObj_Destroy(imageObjectPtr);
4301
+ return false;
4302
+ }
4303
+ this.memoryManager.free(pngPtr);
4304
+ const matrixPtr = this.memoryManager.malloc(6 * 4);
4305
+ this.pdfiumModule.pdfium.setValue(matrixPtr, rect.size.width, "float");
4306
+ this.pdfiumModule.pdfium.setValue(matrixPtr + 4, 0, "float");
4307
+ this.pdfiumModule.pdfium.setValue(matrixPtr + 8, 0, "float");
4308
+ this.pdfiumModule.pdfium.setValue(matrixPtr + 12, rect.size.height, "float");
4309
+ this.pdfiumModule.pdfium.setValue(matrixPtr + 16, 0, "float");
4310
+ this.pdfiumModule.pdfium.setValue(matrixPtr + 20, 0, "float");
4311
+ if (!this.pdfiumModule.FPDFPageObj_SetMatrix(imageObjectPtr, matrixPtr)) {
4312
+ this.memoryManager.free(matrixPtr);
4313
+ this.pdfiumModule.FPDFPageObj_Destroy(imageObjectPtr);
4314
+ return false;
4315
+ }
4316
+ this.memoryManager.free(matrixPtr);
4317
+ const pagePos = this.convertDevicePointToPagePoint(doc, page, {
4318
+ x: rect.origin.x,
4319
+ y: rect.origin.y + rect.size.height
4320
+ });
4321
+ this.pdfiumModule.FPDFPageObj_Transform(imageObjectPtr, 1, 0, 0, 1, pagePos.x, pagePos.y);
4322
+ if (!this.pdfiumModule.FPDFAnnot_AppendObject(annotationPtr, imageObjectPtr)) {
4323
+ this.pdfiumModule.FPDFPageObj_Destroy(imageObjectPtr);
4324
+ return false;
4325
+ }
4326
+ return true;
4327
+ }
4328
+ /**
4329
+ * Add JPEG image object to annotation using native JPEG pass-through.
4330
+ * Passes raw JPEG bytes to PDFium which embeds them as a DCTDecode
4331
+ * stream — no decode/re-encode roundtrip.
4332
+ *
4333
+ * @private
4334
+ */
4335
+ addJpegImageObject(doc, docPtr, page, pagePtr, annotationPtr, rect, jpegData) {
4336
+ const imageObjectPtr = this.pdfiumModule.FPDFPageObj_NewImageObj(docPtr);
4337
+ if (!imageObjectPtr) {
4338
+ return false;
4339
+ }
4340
+ const jpegBytes = new Uint8Array(jpegData);
4341
+ const jpegPtr = this.memoryManager.malloc(jpegBytes.byteLength);
4342
+ if (!jpegPtr) {
4343
+ this.pdfiumModule.FPDFPageObj_Destroy(imageObjectPtr);
4344
+ return false;
4345
+ }
4346
+ this.pdfiumModule.pdfium.HEAPU8.set(jpegBytes, jpegPtr);
4347
+ if (!this.pdfiumModule.EPDFImageObj_SetJpeg(
4348
+ pagePtr,
4349
+ 0,
4350
+ imageObjectPtr,
4351
+ jpegPtr,
4352
+ jpegBytes.byteLength
4353
+ )) {
4354
+ this.memoryManager.free(jpegPtr);
4355
+ this.pdfiumModule.FPDFPageObj_Destroy(imageObjectPtr);
4356
+ return false;
4357
+ }
4358
+ this.memoryManager.free(jpegPtr);
4359
+ const matrixPtr = this.memoryManager.malloc(6 * 4);
4360
+ this.pdfiumModule.pdfium.setValue(matrixPtr, rect.size.width, "float");
4361
+ this.pdfiumModule.pdfium.setValue(matrixPtr + 4, 0, "float");
4362
+ this.pdfiumModule.pdfium.setValue(matrixPtr + 8, 0, "float");
4363
+ this.pdfiumModule.pdfium.setValue(matrixPtr + 12, rect.size.height, "float");
4364
+ this.pdfiumModule.pdfium.setValue(matrixPtr + 16, 0, "float");
4365
+ this.pdfiumModule.pdfium.setValue(matrixPtr + 20, 0, "float");
4366
+ if (!this.pdfiumModule.FPDFPageObj_SetMatrix(imageObjectPtr, matrixPtr)) {
4367
+ this.memoryManager.free(matrixPtr);
4368
+ this.pdfiumModule.FPDFPageObj_Destroy(imageObjectPtr);
4369
+ return false;
4370
+ }
4371
+ this.memoryManager.free(matrixPtr);
4372
+ const pagePos = this.convertDevicePointToPagePoint(doc, page, {
4373
+ x: rect.origin.x,
4374
+ y: rect.origin.y + rect.size.height
4375
+ });
4376
+ this.pdfiumModule.FPDFPageObj_Transform(imageObjectPtr, 1, 0, 0, 1, pagePos.x, pagePos.y);
4377
+ if (!this.pdfiumModule.FPDFAnnot_AppendObject(annotationPtr, imageObjectPtr)) {
4378
+ this.pdfiumModule.FPDFPageObj_Destroy(imageObjectPtr);
4379
+ return false;
4380
+ }
4381
+ return true;
4382
+ }
4236
4383
  /**
4237
4384
  * Save document to array buffer
4238
4385
  * @param docPtr - pointer to pdf document
@@ -9685,4 +9832,4 @@ export {
9685
9832
  isValidCustomKey as i,
9686
9833
  readArrayBuffer as r
9687
9834
  };
9688
- //# sourceMappingURL=direct-engine-cyecHjwI.js.map
9835
+ //# sourceMappingURL=direct-engine-B7gUkBcT.js.map