modern-pdf-lib 0.25.0 → 0.28.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 (110) hide show
  1. package/README.md +16 -3
  2. package/dist/{batchOptimize-Ba_pWw71.cjs → batchOptimize-CXC9gNqD.cjs} +55 -55
  3. package/dist/{batchOptimize-DtRwBOqR.mjs → batchOptimize-CjLGD5ie.mjs} +25 -25
  4. package/dist/{bridge-DYCQzxF7.cjs → bridge-ByvzPu5h.cjs} +29 -31
  5. package/dist/{bridge-CcivG_Sm.mjs → bridge-ZD6O6QQa.mjs} +4 -5
  6. package/dist/browser.cjs +263 -151
  7. package/dist/browser.d.cts +166 -166
  8. package/dist/browser.d.cts.map +1 -1
  9. package/dist/browser.d.mts +166 -166
  10. package/dist/browser.d.mts.map +1 -1
  11. package/dist/browser.mjs +15 -19
  12. package/dist/cli/index.cjs +7 -7
  13. package/dist/cli/index.mjs +8 -8
  14. package/dist/{compressionAnalysis-odbHC7Uk.mjs → compressionAnalysis-BgKy45pA.mjs} +60 -74
  15. package/dist/{compressionAnalysis-DGs-MqTe.d.mts → compressionAnalysis-CDOp_vPr.d.mts} +136 -136
  16. package/dist/compressionAnalysis-CDOp_vPr.d.mts.map +1 -0
  17. package/dist/{compressionAnalysis-B84FPXaQ.cjs → compressionAnalysis-Djv-Zvcd.cjs} +90 -104
  18. package/dist/{compressionAnalysis-VtYV9Zmq.d.cts → compressionAnalysis-UfmonqbM.d.cts} +136 -136
  19. package/dist/compressionAnalysis-UfmonqbM.d.cts.map +1 -0
  20. package/dist/create.cjs +21 -23
  21. package/dist/create.d.cts +2 -2
  22. package/dist/create.d.mts +2 -2
  23. package/dist/create.mjs +3 -5
  24. package/dist/{deduplicateImages-MfUDPxQz.mjs → deduplicateImages-BTCyAPfJ.mjs} +4 -5
  25. package/dist/{deduplicateImages-cKsnD6Ep.cjs → deduplicateImages-CaGgaqyS.cjs} +14 -15
  26. package/dist/{fieldAppearance-C8PoLFSc.d.mts → fieldAppearance-Df1262CT.d.cts} +44 -44
  27. package/dist/fieldAppearance-Df1262CT.d.cts.map +1 -0
  28. package/dist/{fieldAppearance-CdiGFG5e.d.cts → fieldAppearance-_CZdoUCD.d.mts} +44 -44
  29. package/dist/fieldAppearance-_CZdoUCD.d.mts.map +1 -0
  30. package/dist/fontEmbed-DGiZS0h2.d.cts +677 -0
  31. package/dist/fontEmbed-DGiZS0h2.d.cts.map +1 -0
  32. package/dist/fontEmbed-DtA_riGC.d.mts +677 -0
  33. package/dist/fontEmbed-DtA_riGC.d.mts.map +1 -0
  34. package/dist/forms.cjs +3 -4
  35. package/dist/forms.d.cts +2 -2
  36. package/dist/forms.d.mts +2 -2
  37. package/dist/forms.mjs +2 -3
  38. package/dist/{grayscaleDetect-C6kFF3dk.mjs → grayscaleDetect-6GJrgBRT.mjs} +3 -3
  39. package/dist/{grayscaleDetect-C2m-eEXR.cjs → grayscaleDetect-DAUqxjgR.cjs} +13 -14
  40. package/dist/{imageExtract-zEb1gnkb.cjs → imageExtract-DT50Hp_g.cjs} +13 -14
  41. package/dist/{imageExtract-Dnk_Ssv7.mjs → imageExtract-Dapir-ux.mjs} +3 -4
  42. package/dist/index-C1lZe66f.d.mts +8682 -0
  43. package/dist/index-C1lZe66f.d.mts.map +1 -0
  44. package/dist/index-D1SvXWSI.d.cts +8682 -0
  45. package/dist/index-D1SvXWSI.d.cts.map +1 -0
  46. package/dist/index.cjs +263 -150
  47. package/dist/index.d.cts +7 -7
  48. package/dist/index.d.mts +7 -7
  49. package/dist/index.mjs +14 -17
  50. package/dist/{layout-DH61a1iR.cjs → layout-C4vbTlBW.cjs} +184 -134
  51. package/dist/{layout-D6EUKSP8.mjs → layout-lO4x64kY.mjs} +50 -12
  52. package/dist/{loader-C7B5dVCI.mjs → loader-B1Ix7ozU.mjs} +259 -13
  53. package/dist/{loader-I4zdkoWc.cjs → loader-DR7H0XOf.cjs} +343 -67
  54. package/dist/parse.cjs +7 -8
  55. package/dist/parse.d.cts +3 -3
  56. package/dist/parse.d.mts +3 -3
  57. package/dist/parse.mjs +6 -7
  58. package/dist/pdfDocument-CH2E4UCc.d.mts +5160 -0
  59. package/dist/pdfDocument-CH2E4UCc.d.mts.map +1 -0
  60. package/dist/{pdfDocument-CEbbUP9i.cjs → pdfDocument-C_7mrBCL.cjs} +20493 -9511
  61. package/dist/pdfDocument-CzOipXnw.d.cts +5160 -0
  62. package/dist/pdfDocument-CzOipXnw.d.cts.map +1 -0
  63. package/dist/{pdfDocument-B0_XwS4X.mjs → pdfDocument-DRbT6HZw.mjs} +11017 -863
  64. package/dist/{pdfForm-9gd40uz9.cjs → pdfForm-BVS_do95.cjs} +113 -102
  65. package/dist/pdfForm-Ca86NDWn.d.cts +897 -0
  66. package/dist/pdfForm-Ca86NDWn.d.cts.map +1 -0
  67. package/dist/pdfForm-Ca86NDWn.d.mts +897 -0
  68. package/dist/pdfForm-Ca86NDWn.d.mts.map +1 -0
  69. package/dist/{pdfForm-Cn-cVicP.mjs → pdfForm-CfLnlsj-.mjs} +23 -18
  70. package/dist/{pdfObjects-1veop1_d.cjs → pdfObjects-BcPlSI0a.cjs} +62 -53
  71. package/dist/{pdfObjects-uEsWlfzU.mjs → pdfObjects-CB7TEdbW.mjs} +12 -2
  72. package/dist/rolldown-runtime-ak5kbic3.cjs +18 -0
  73. package/dist/{src-B1iDGLCL.cjs → src-C-IDXuvi.cjs} +9886 -1421
  74. package/dist/{src-Db6Qknoz.mjs → src-DJaD-bJ2.mjs} +8392 -515
  75. package/dist/{streamDecode-Bj568Nc9.mjs → streamDecode-BamENT3k.mjs} +129 -150
  76. package/dist/{streamDecode-CvgErkFu.cjs → streamDecode-DcaZz309.cjs} +139 -160
  77. package/package.json +26 -22
  78. package/dist/compressionAnalysis-DGs-MqTe.d.mts.map +0 -1
  79. package/dist/compressionAnalysis-VtYV9Zmq.d.cts.map +0 -1
  80. package/dist/fflateAdapter-LTAeAhaD.cjs +0 -207
  81. package/dist/fflateAdapter-PSiW_ML7.mjs +0 -196
  82. package/dist/fieldAppearance-C8PoLFSc.d.mts.map +0 -1
  83. package/dist/fieldAppearance-CdiGFG5e.d.cts.map +0 -1
  84. package/dist/fontEmbed-BN842wlb.d.cts +0 -659
  85. package/dist/fontEmbed-BN842wlb.d.cts.map +0 -1
  86. package/dist/fontEmbed-Dgq5K89o.d.mts +0 -659
  87. package/dist/fontEmbed-Dgq5K89o.d.mts.map +0 -1
  88. package/dist/fontSubset-5SLWMmEw.cjs +0 -518
  89. package/dist/fontSubset-D-vQQems.mjs +0 -495
  90. package/dist/index-DCSbmXWh.d.mts +0 -5939
  91. package/dist/index-DCSbmXWh.d.mts.map +0 -1
  92. package/dist/index-J1W3FdL8.d.cts +0 -5939
  93. package/dist/index-J1W3FdL8.d.cts.map +0 -1
  94. package/dist/libdeflateWasm-8b91Vmia.mjs +0 -220
  95. package/dist/libdeflateWasm-BdiDEJOj.cjs +0 -237
  96. package/dist/pdfCatalog-3yMIhJtt.mjs +0 -138
  97. package/dist/pdfCatalog-CYy4NXEY.cjs +0 -173
  98. package/dist/pdfDocument-BgvEP5Po.d.mts +0 -4673
  99. package/dist/pdfDocument-BgvEP5Po.d.mts.map +0 -1
  100. package/dist/pdfDocument-CbU-2TjT.d.cts +0 -4673
  101. package/dist/pdfDocument-CbU-2TjT.d.cts.map +0 -1
  102. package/dist/pdfForm-BiyNtYem.d.mts +0 -905
  103. package/dist/pdfForm-BiyNtYem.d.mts.map +0 -1
  104. package/dist/pdfForm-SOXJ72LW.d.cts +0 -905
  105. package/dist/pdfForm-SOXJ72LW.d.cts.map +0 -1
  106. package/dist/pdfPage-B_d9HmkG.mjs +0 -8015
  107. package/dist/pdfPage-Cd8jOJp6.cjs +0 -8728
  108. package/dist/pngEmbed-BWAbEUKF.mjs +0 -552
  109. package/dist/pngEmbed-D4X4ZN-3.cjs +0 -563
  110. package/dist/rolldown-runtime-CKhH4XqG.cjs +0 -24
@@ -1,552 +0,0 @@
1
- import { os as __exportAll } from "./index-DCSbmXWh.d.mts";
2
- import { deflateSync, unzlibSync } from "fflate";
3
-
4
- //#region src/assets/image/pngEmbed.ts
5
- /**
6
- * @module assets/image/pngEmbed
7
- *
8
- * PNG decoding and embedding for PDF image XObjects.
9
- *
10
- * Parses a PNG file to extract dimensions, color type, bit depth, and
11
- * pixel data. Produces the data needed for a PDF image XObject
12
- * dictionary with the appropriate `/ColorSpace`, `/BitsPerComponent`,
13
- * `/Filter`, and `/SMask` entries.
14
- *
15
- * Handles all standard PNG color types:
16
- * - Type 0: Grayscale
17
- * - Type 2: RGB (Truecolor)
18
- * - Type 3: Indexed (Palette)
19
- * - Type 4: Grayscale + Alpha
20
- * - Type 6: RGBA (Truecolor + Alpha)
21
- *
22
- * For images with alpha channels (types 4 and 6), the alpha channel
23
- * is separated into a /SMask soft-mask image.
24
- *
25
- * WASM-accelerated decoding is supported with a JS fallback.
26
- *
27
- * No Buffer — uses Uint8Array exclusively.
28
- * No fs — no file system access.
29
- * No require() — ESM import only.
30
- */
31
- var pngEmbed_exports = /* @__PURE__ */ __exportAll({
32
- embedPng: () => embedPng,
33
- initPngWasm: () => initPngWasm
34
- });
35
- /** PNG file signature (8 bytes). */
36
- const PNG_SIGNATURE = new Uint8Array([
37
- 137,
38
- 80,
39
- 78,
40
- 71,
41
- 13,
42
- 10,
43
- 26,
44
- 10
45
- ]);
46
- /** Color type constants from the PNG spec. */
47
- var PngColorType = /* @__PURE__ */ function(PngColorType) {
48
- PngColorType[PngColorType["Grayscale"] = 0] = "Grayscale";
49
- PngColorType[PngColorType["RGB"] = 2] = "RGB";
50
- PngColorType[PngColorType["Indexed"] = 3] = "Indexed";
51
- PngColorType[PngColorType["GrayscaleAlpha"] = 4] = "GrayscaleAlpha";
52
- PngColorType[PngColorType["RGBA"] = 6] = "RGBA";
53
- return PngColorType;
54
- }(PngColorType || {});
55
- /**
56
- * Validate the PNG signature.
57
- *
58
- * @param data - The raw PNG bytes.
59
- * @throws If the signature does not match.
60
- */
61
- function validatePngSignature(data) {
62
- if (data.length < 8) throw new Error("PNG data too small — expected at least 8 bytes for the signature");
63
- for (let i = 0; i < 8; i++) if (data[i] !== PNG_SIGNATURE[i]) throw new Error("Invalid PNG signature");
64
- }
65
- /**
66
- * Iterate over all chunks in a PNG file.
67
- *
68
- * @param data - The raw PNG bytes.
69
- * @returns An array of parsed chunks.
70
- */
71
- function parseChunks(data) {
72
- const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
73
- const chunks = [];
74
- let offset = 8;
75
- while (offset < data.length) {
76
- if (offset + 8 > data.length) break;
77
- const length = view.getUint32(offset, false);
78
- const type = String.fromCharCode(data[offset + 4], data[offset + 5], data[offset + 6], data[offset + 7]);
79
- const chunkData = data.slice(offset + 8, offset + 8 + length);
80
- chunks.push({
81
- type,
82
- data: chunkData
83
- });
84
- offset += 12 + length;
85
- if (type === "IEND") break;
86
- }
87
- return chunks;
88
- }
89
- /**
90
- * Parse the IHDR chunk.
91
- */
92
- function parseIhdr(chunk) {
93
- if (chunk.type !== "IHDR" || chunk.data.length < 13) throw new Error("Invalid PNG: missing or malformed IHDR chunk");
94
- const view = new DataView(chunk.data.buffer, chunk.data.byteOffset, chunk.data.byteLength);
95
- return {
96
- width: view.getUint32(0, false),
97
- height: view.getUint32(4, false),
98
- bitDepth: chunk.data[8],
99
- colorType: chunk.data[9],
100
- compressionMethod: chunk.data[10],
101
- filterMethod: chunk.data[11],
102
- interlaceMethod: chunk.data[12]
103
- };
104
- }
105
- /**
106
- * Concatenate all IDAT chunk data into a single Uint8Array.
107
- */
108
- function concatenateIdatChunks(chunks) {
109
- const idatChunks = chunks.filter((c) => c.type === "IDAT");
110
- if (idatChunks.length === 0) throw new Error("Invalid PNG: no IDAT chunks found");
111
- const totalLength = idatChunks.reduce((sum, c) => sum + c.data.length, 0);
112
- const result = new Uint8Array(totalLength);
113
- let pos = 0;
114
- for (const chunk of idatChunks) {
115
- result.set(chunk.data, pos);
116
- pos += chunk.data.length;
117
- }
118
- return result;
119
- }
120
- /**
121
- * Find the PLTE (palette) chunk data if present.
122
- */
123
- function findPalette(chunks) {
124
- return chunks.find((c) => c.type === "PLTE")?.data;
125
- }
126
- /**
127
- * Find the tRNS (transparency) chunk data if present.
128
- */
129
- function findTransparency(chunks) {
130
- return chunks.find((c) => c.type === "tRNS")?.data;
131
- }
132
- let pngWasmInstance;
133
- /**
134
- * Initialize the PNG decoding WASM module.
135
- *
136
- * @param wasmSource - The WASM binary, URL, or Response.
137
- */
138
- async function initPngWasm(wasmSource) {
139
- if (pngWasmInstance) return;
140
- const imports = { env: {} };
141
- let result;
142
- try {
143
- if (wasmSource instanceof Uint8Array) result = await WebAssembly.instantiate(wasmSource.buffer, imports);
144
- else if (typeof Response !== "undefined" && wasmSource instanceof Response) result = await WebAssembly.instantiateStreaming(wasmSource, imports);
145
- else if (typeof wasmSource === "string" || wasmSource instanceof URL) {
146
- const resp = await fetch(String(wasmSource));
147
- result = await WebAssembly.instantiateStreaming(resp, imports);
148
- } else {
149
- const { loadWasmModule } = await import("./loader-C7B5dVCI.mjs").then((n) => n.l);
150
- const bytes = await loadWasmModule("png");
151
- result = await WebAssembly.instantiate(bytes.buffer, imports);
152
- }
153
- pngWasmInstance = result.instance.exports;
154
- } catch {
155
- pngWasmInstance = void 0;
156
- }
157
- }
158
- /**
159
- * Decompress the zlib data from IDAT chunks.
160
- *
161
- * Uses the DecompressionStream API (available in modern browsers,
162
- * Node 18+, Deno) or falls back to a manual inflate.
163
- *
164
- * @internal
165
- */
166
- function decompressZlib(compressed) {
167
- return unzlibSync(compressed);
168
- }
169
- /**
170
- * Apply PNG filter reconstruction to a decompressed scanline buffer.
171
- *
172
- * Each scanline is prefixed with a 1-byte filter type:
173
- * 0=None, 1=Sub, 2=Up, 3=Average, 4=Paeth
174
- *
175
- * @internal
176
- */
177
- function reconstructFilters(decompressed, width, height, bytesPerPixel) {
178
- const stride = width * bytesPerPixel;
179
- const result = new Uint8Array(height * stride);
180
- let srcOffset = 0;
181
- let dstOffset = 0;
182
- for (let y = 0; y < height; y++) {
183
- const filterType = decompressed[srcOffset];
184
- srcOffset++;
185
- const scanline = decompressed.subarray(srcOffset, srcOffset + stride);
186
- srcOffset += stride;
187
- const prevLine = y > 0 ? result.subarray((y - 1) * stride, y * stride) : new Uint8Array(stride);
188
- for (let x = 0; x < stride; x++) {
189
- const raw = scanline[x];
190
- const a = x >= bytesPerPixel ? result[dstOffset + x - bytesPerPixel] : 0;
191
- const b = prevLine[x];
192
- const c = x >= bytesPerPixel && y > 0 ? result[(y - 1) * stride + x - bytesPerPixel] : 0;
193
- let reconstructed;
194
- switch (filterType) {
195
- case 0:
196
- reconstructed = raw;
197
- break;
198
- case 1:
199
- reconstructed = raw + a & 255;
200
- break;
201
- case 2:
202
- reconstructed = raw + b & 255;
203
- break;
204
- case 3:
205
- reconstructed = raw + Math.floor((a + b) / 2) & 255;
206
- break;
207
- case 4:
208
- reconstructed = raw + paethPredictor(a, b, c) & 255;
209
- break;
210
- default: throw new Error(`Unknown PNG filter type: ${filterType}`);
211
- }
212
- result[dstOffset + x] = reconstructed;
213
- }
214
- dstOffset += stride;
215
- }
216
- return result;
217
- }
218
- /**
219
- * Paeth predictor function.
220
- * @internal
221
- */
222
- function paethPredictor(a, b, c) {
223
- const p = a + b - c;
224
- const pa = Math.abs(p - a);
225
- const pb = Math.abs(p - b);
226
- const pc = Math.abs(p - c);
227
- if (pa <= pb && pa <= pc) return a;
228
- if (pb <= pc) return b;
229
- return c;
230
- }
231
- /**
232
- * Compute the bytes per pixel for a given color type and bit depth.
233
- * @internal
234
- */
235
- function bytesPerPixel(colorType, bitDepth) {
236
- const channels = colorType === PngColorType.Grayscale ? 1 : colorType === PngColorType.RGB ? 3 : colorType === PngColorType.Indexed ? 1 : colorType === PngColorType.GrayscaleAlpha ? 2 : colorType === PngColorType.RGBA ? 4 : 1;
237
- return Math.max(1, Math.ceil(channels * bitDepth / 8));
238
- }
239
- /**
240
- * Separate RGBA pixels into RGB data + alpha mask.
241
- * @internal
242
- */
243
- function separateRgba(pixels, width, height) {
244
- const pixelCount = width * height;
245
- const rgb = new Uint8Array(pixelCount * 3);
246
- const alpha = new Uint8Array(pixelCount);
247
- for (let i = 0; i < pixelCount; i++) {
248
- const srcIdx = i * 4;
249
- const dstIdx = i * 3;
250
- rgb[dstIdx] = pixels[srcIdx];
251
- rgb[dstIdx + 1] = pixels[srcIdx + 1];
252
- rgb[dstIdx + 2] = pixels[srcIdx + 2];
253
- alpha[i] = pixels[srcIdx + 3];
254
- }
255
- return {
256
- rgb,
257
- alpha
258
- };
259
- }
260
- /**
261
- * Separate Grayscale+Alpha pixels into gray data + alpha mask.
262
- * @internal
263
- */
264
- function separateGrayscaleAlpha(pixels, width, height) {
265
- const pixelCount = width * height;
266
- const gray = new Uint8Array(pixelCount);
267
- const alpha = new Uint8Array(pixelCount);
268
- for (let i = 0; i < pixelCount; i++) {
269
- gray[i] = pixels[i * 2];
270
- alpha[i] = pixels[i * 2 + 1];
271
- }
272
- return {
273
- gray,
274
- alpha
275
- };
276
- }
277
- /**
278
- * Compress data using deflate for FlateDecode.
279
- * @internal
280
- */
281
- function compressForPdf(data) {
282
- return deflateSync(data, { level: 6 });
283
- }
284
- /**
285
- * Embed a PNG image for use as a PDF image XObject.
286
- *
287
- * Parses the PNG file, decodes pixel data, separates alpha channels,
288
- * and produces all the data needed for the PDF image XObject
289
- * dictionary.
290
- *
291
- * @param pngData - The raw PNG file as a Uint8Array.
292
- * @returns The embedding result with all data needed for a PDF image XObject.
293
- *
294
- * @example
295
- * ```ts
296
- * const pngBytes = await readFile('photo.png');
297
- * const result = embedPng(pngBytes);
298
- *
299
- * // Create image XObject with:
300
- * // /Width result.width
301
- * // /Height result.height
302
- * // /ColorSpace result.colorSpace
303
- * // /BitsPerComponent result.bitsPerComponent
304
- * // /Filter /FlateDecode
305
- * // stream: result.imageData
306
- * //
307
- * // If result.smaskData is defined, create a second XObject for the SMask.
308
- * ```
309
- */
310
- function embedPng(pngData) {
311
- validatePngSignature(pngData);
312
- const chunks = parseChunks(pngData);
313
- if (chunks.length === 0) throw new Error("Invalid PNG: no chunks found");
314
- const ihdr = parseIhdr(chunks[0]);
315
- const idatData = concatenateIdatChunks(chunks);
316
- const palette = findPalette(chunks);
317
- const transparency = findTransparency(chunks);
318
- const hasAlpha = ihdr.colorType === PngColorType.GrayscaleAlpha || ihdr.colorType === PngColorType.RGBA;
319
- const isInterlaced = ihdr.interlaceMethod !== 0;
320
- if (ihdr.colorType === PngColorType.Indexed && !isInterlaced && ihdr.bitDepth === 8) return embedIndexedPng(ihdr, idatData, palette, transparency);
321
- if (!hasAlpha && !isInterlaced && ihdr.bitDepth === 8) return embedDirectPng(ihdr, idatData, transparency);
322
- return embedComplexPng(ihdr, idatData, palette, transparency);
323
- }
324
- /**
325
- * Embed an indexed (palette-based) PNG.
326
- * @internal
327
- */
328
- function embedIndexedPng(ihdr, idatData, palette, transparency) {
329
- if (!palette) throw new Error("Invalid PNG: indexed color type requires PLTE chunk");
330
- if (!transparency || transparency.length === 0) return {
331
- width: ihdr.width,
332
- height: ihdr.height,
333
- bitsPerComponent: 8,
334
- colorSpace: "Indexed",
335
- palette,
336
- imageData: idatData,
337
- filter: "FlateDecode",
338
- hasTransparency: false,
339
- decodeParms: {
340
- predictor: 15,
341
- columns: ihdr.width,
342
- colors: 1,
343
- bitsPerComponent: 8
344
- }
345
- };
346
- const decompressed = decompressZlib(idatData);
347
- const bpp = bytesPerPixel(ihdr.colorType, ihdr.bitDepth);
348
- const pixels = reconstructFilters(decompressed, ihdr.width, ihdr.height, bpp);
349
- const imageData = compressForPdf(pixels);
350
- const pixelCount = ihdr.width * ihdr.height;
351
- const alpha = new Uint8Array(pixelCount);
352
- for (let i = 0; i < pixelCount; i++) {
353
- const paletteIndex = pixels[i];
354
- alpha[i] = paletteIndex < transparency.length ? transparency[paletteIndex] : 255;
355
- }
356
- const smaskData = compressForPdf(alpha);
357
- return {
358
- width: ihdr.width,
359
- height: ihdr.height,
360
- bitsPerComponent: 8,
361
- colorSpace: "Indexed",
362
- palette,
363
- imageData,
364
- filter: "FlateDecode",
365
- smaskData,
366
- smaskBitsPerComponent: 8,
367
- hasTransparency: true
368
- };
369
- }
370
- /**
371
- * Embed a direct (Grayscale or RGB) PNG without alpha.
372
- * @internal
373
- */
374
- function embedDirectPng(ihdr, idatData, transparency) {
375
- const colorSpace = ihdr.colorType === PngColorType.Grayscale ? "DeviceGray" : "DeviceRGB";
376
- const colors = ihdr.colorType === PngColorType.Grayscale ? 1 : 3;
377
- if (!transparency || transparency.length === 0) return {
378
- width: ihdr.width,
379
- height: ihdr.height,
380
- bitsPerComponent: ihdr.bitDepth,
381
- colorSpace,
382
- imageData: idatData,
383
- filter: "FlateDecode",
384
- hasTransparency: false,
385
- decodeParms: {
386
- predictor: 15,
387
- columns: ihdr.width,
388
- colors,
389
- bitsPerComponent: ihdr.bitDepth
390
- }
391
- };
392
- const decompressed = decompressZlib(idatData);
393
- const bpp = bytesPerPixel(ihdr.colorType, ihdr.bitDepth);
394
- const pixels = reconstructFilters(decompressed, ihdr.width, ihdr.height, bpp);
395
- const imageData = compressForPdf(pixels);
396
- let smaskData;
397
- const pixelCount = ihdr.width * ihdr.height;
398
- const alpha = new Uint8Array(pixelCount);
399
- alpha.fill(255);
400
- if (ihdr.colorType === PngColorType.Grayscale && transparency.length >= 2) {
401
- const trnsGray = transparency[0] << 8 | transparency[1];
402
- for (let i = 0; i < pixelCount; i++) if (pixels[i] === trnsGray) alpha[i] = 0;
403
- smaskData = compressForPdf(alpha);
404
- } else if (ihdr.colorType === PngColorType.RGB && transparency.length >= 6) {
405
- const trnsR = transparency[0] << 8 | transparency[1];
406
- const trnsG = transparency[2] << 8 | transparency[3];
407
- const trnsB = transparency[4] << 8 | transparency[5];
408
- for (let i = 0; i < pixelCount; i++) {
409
- const idx = i * 3;
410
- if (pixels[idx] === trnsR && pixels[idx + 1] === trnsG && pixels[idx + 2] === trnsB) alpha[i] = 0;
411
- }
412
- smaskData = compressForPdf(alpha);
413
- }
414
- return {
415
- width: ihdr.width,
416
- height: ihdr.height,
417
- bitsPerComponent: ihdr.bitDepth,
418
- colorSpace,
419
- imageData,
420
- filter: "FlateDecode",
421
- smaskData,
422
- smaskBitsPerComponent: smaskData ? 8 : void 0,
423
- hasTransparency: true
424
- };
425
- }
426
- /**
427
- * Full decompression path for PNGs that need alpha separation,
428
- * de-interlacing, or bit-depth normalization.
429
- * @internal
430
- */
431
- function embedComplexPng(ihdr, idatData, palette, transparency) {
432
- const decompressed = decompressZlib(idatData);
433
- const bpp = bytesPerPixel(ihdr.colorType, ihdr.bitDepth);
434
- let pixels;
435
- if (ihdr.interlaceMethod !== 0) {
436
- const startingRow = [
437
- 0,
438
- 0,
439
- 4,
440
- 0,
441
- 2,
442
- 0,
443
- 1
444
- ];
445
- const startingCol = [
446
- 0,
447
- 4,
448
- 0,
449
- 2,
450
- 0,
451
- 1,
452
- 0
453
- ];
454
- const rowStride = [
455
- 8,
456
- 8,
457
- 8,
458
- 4,
459
- 4,
460
- 2,
461
- 2
462
- ];
463
- const colStride = [
464
- 8,
465
- 8,
466
- 4,
467
- 4,
468
- 2,
469
- 2,
470
- 1
471
- ];
472
- const stride = ihdr.width * bpp;
473
- const finalPixels = new Uint8Array(ihdr.height * stride);
474
- let srcOffset = 0;
475
- for (let pass = 0; pass < 7; pass++) {
476
- const startRow = startingRow[pass];
477
- const startCol = startingCol[pass];
478
- const rStride = rowStride[pass];
479
- const cStride = colStride[pass];
480
- const passWidth = ihdr.width <= startCol ? 0 : Math.ceil((ihdr.width - startCol) / cStride);
481
- const passHeight = ihdr.height <= startRow ? 0 : Math.ceil((ihdr.height - startRow) / rStride);
482
- if (passWidth === 0 || passHeight === 0) continue;
483
- const passDataLength = passHeight * (1 + passWidth * bpp);
484
- const passData = decompressed.subarray(srcOffset, srcOffset + passDataLength);
485
- srcOffset += passDataLength;
486
- const passPixels = reconstructFilters(passData, passWidth, passHeight, bpp);
487
- for (let py = 0; py < passHeight; py++) {
488
- const finalY = startRow + py * rStride;
489
- for (let px = 0; px < passWidth; px++) {
490
- const finalX = startCol + px * cStride;
491
- const srcIdx = (py * passWidth + px) * bpp;
492
- const dstIdx = finalY * stride + finalX * bpp;
493
- for (let b = 0; b < bpp; b++) finalPixels[dstIdx + b] = passPixels[srcIdx + b];
494
- }
495
- }
496
- }
497
- pixels = finalPixels;
498
- } else pixels = reconstructFilters(decompressed, ihdr.width, ihdr.height, bpp);
499
- let imageData;
500
- let smaskData;
501
- let colorSpace;
502
- let bitsPerComponent = ihdr.bitDepth;
503
- switch (ihdr.colorType) {
504
- case PngColorType.RGBA: {
505
- const { rgb, alpha } = separateRgba(pixels, ihdr.width, ihdr.height);
506
- imageData = compressForPdf(rgb);
507
- smaskData = compressForPdf(alpha);
508
- colorSpace = "DeviceRGB";
509
- bitsPerComponent = 8;
510
- break;
511
- }
512
- case PngColorType.GrayscaleAlpha: {
513
- const { gray, alpha } = separateGrayscaleAlpha(pixels, ihdr.width, ihdr.height);
514
- imageData = compressForPdf(gray);
515
- smaskData = compressForPdf(alpha);
516
- colorSpace = "DeviceGray";
517
- bitsPerComponent = 8;
518
- break;
519
- }
520
- case PngColorType.Grayscale:
521
- imageData = compressForPdf(pixels);
522
- colorSpace = "DeviceGray";
523
- break;
524
- case PngColorType.RGB:
525
- imageData = compressForPdf(pixels);
526
- colorSpace = "DeviceRGB";
527
- break;
528
- case PngColorType.Indexed:
529
- if (!palette) throw new Error("Invalid PNG: indexed color type requires PLTE chunk");
530
- imageData = compressForPdf(pixels);
531
- colorSpace = "Indexed";
532
- bitsPerComponent = ihdr.bitDepth;
533
- break;
534
- default: throw new Error(`Unsupported PNG color type: ${ihdr.colorType}`);
535
- }
536
- return {
537
- width: ihdr.width,
538
- height: ihdr.height,
539
- bitsPerComponent,
540
- colorSpace,
541
- palette: ihdr.colorType === PngColorType.Indexed ? palette : void 0,
542
- imageData,
543
- filter: "FlateDecode",
544
- smaskData,
545
- smaskBitsPerComponent: smaskData ? 8 : void 0,
546
- hasTransparency: smaskData !== void 0 || transparency !== void 0 && transparency.length > 0
547
- };
548
- }
549
-
550
- //#endregion
551
- export { pngEmbed_exports as n, embedPng as t };
552
- //# sourceMappingURL=pngEmbed-BWAbEUKF.mjs.map