@aglyn/aglyn 1.0.0-beta.197 → 1.0.0-beta.199

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 (80) hide show
  1. package/package.json +11 -11
  2. package/src/lib/app-utils/docs-help.generated.d.ts +1 -1
  3. package/src/lib/app-utils/docs-help.generated.js +1 -0
  4. package/src/lib/app-utils/docs-help.generated.js.map +1 -1
  5. package/src/lib/app-utils/docs-index.generated.js +3 -3
  6. package/src/lib/app-utils/docs-index.generated.js.map +1 -1
  7. package/src/lib/app-utils/media-embedded-fields.d.ts +471 -0
  8. package/src/lib/app-utils/media-embedded-fields.js +619 -0
  9. package/src/lib/app-utils/media-embedded-fields.js.map +1 -0
  10. package/src/lib/app-utils/media-embedded-metadata/exif.d.ts +160 -0
  11. package/src/lib/app-utils/media-embedded-metadata/exif.js +1267 -0
  12. package/src/lib/app-utils/media-embedded-metadata/exif.js.map +1 -0
  13. package/src/lib/app-utils/media-embedded-metadata/gif.d.ts +44 -0
  14. package/src/lib/app-utils/media-embedded-metadata/gif.js +134 -0
  15. package/src/lib/app-utils/media-embedded-metadata/gif.js.map +1 -0
  16. package/src/lib/app-utils/media-embedded-metadata/heif.d.ts +23 -0
  17. package/src/lib/app-utils/media-embedded-metadata/heif.js +354 -0
  18. package/src/lib/app-utils/media-embedded-metadata/heif.js.map +1 -0
  19. package/src/lib/app-utils/media-embedded-metadata/icc.d.ts +22 -0
  20. package/src/lib/app-utils/media-embedded-metadata/icc.js +85 -0
  21. package/src/lib/app-utils/media-embedded-metadata/icc.js.map +1 -0
  22. package/src/lib/app-utils/media-embedded-metadata/image-blocks.d.ts +145 -0
  23. package/src/lib/app-utils/media-embedded-metadata/image-blocks.js +200 -0
  24. package/src/lib/app-utils/media-embedded-metadata/image-blocks.js.map +1 -0
  25. package/src/lib/app-utils/media-embedded-metadata/index.d.ts +93 -0
  26. package/src/lib/app-utils/media-embedded-metadata/index.js +744 -0
  27. package/src/lib/app-utils/media-embedded-metadata/index.js.map +1 -0
  28. package/src/lib/app-utils/media-embedded-metadata/iptc.d.ts +59 -0
  29. package/src/lib/app-utils/media-embedded-metadata/iptc.js +529 -0
  30. package/src/lib/app-utils/media-embedded-metadata/iptc.js.map +1 -0
  31. package/src/lib/app-utils/media-embedded-metadata/jpeg.d.ts +43 -0
  32. package/src/lib/app-utils/media-embedded-metadata/jpeg.js +456 -0
  33. package/src/lib/app-utils/media-embedded-metadata/jpeg.js.map +1 -0
  34. package/src/lib/app-utils/media-embedded-metadata/mp4.d.ts +37 -0
  35. package/src/lib/app-utils/media-embedded-metadata/mp4.js +621 -0
  36. package/src/lib/app-utils/media-embedded-metadata/mp4.js.map +1 -0
  37. package/src/lib/app-utils/media-embedded-metadata/ooxml.d.ts +131 -0
  38. package/src/lib/app-utils/media-embedded-metadata/ooxml.js +1058 -0
  39. package/src/lib/app-utils/media-embedded-metadata/ooxml.js.map +1 -0
  40. package/src/lib/app-utils/media-embedded-metadata/pdf-objects.d.ts +223 -0
  41. package/src/lib/app-utils/media-embedded-metadata/pdf-objects.js +936 -0
  42. package/src/lib/app-utils/media-embedded-metadata/pdf-objects.js.map +1 -0
  43. package/src/lib/app-utils/media-embedded-metadata/pdf.d.ts +82 -0
  44. package/src/lib/app-utils/media-embedded-metadata/pdf.js +1167 -0
  45. package/src/lib/app-utils/media-embedded-metadata/pdf.js.map +1 -0
  46. package/src/lib/app-utils/media-embedded-metadata/png.d.ts +41 -0
  47. package/src/lib/app-utils/media-embedded-metadata/png.js +512 -0
  48. package/src/lib/app-utils/media-embedded-metadata/png.js.map +1 -0
  49. package/src/lib/app-utils/media-embedded-metadata/svg.d.ts +30 -0
  50. package/src/lib/app-utils/media-embedded-metadata/svg.js +154 -0
  51. package/src/lib/app-utils/media-embedded-metadata/svg.js.map +1 -0
  52. package/src/lib/app-utils/media-embedded-metadata/tiff.d.ts +40 -0
  53. package/src/lib/app-utils/media-embedded-metadata/tiff.js +158 -0
  54. package/src/lib/app-utils/media-embedded-metadata/tiff.js.map +1 -0
  55. package/src/lib/app-utils/media-embedded-metadata/types.d.ts +60 -0
  56. package/src/lib/app-utils/media-embedded-metadata/types.js +32 -0
  57. package/src/lib/app-utils/media-embedded-metadata/types.js.map +1 -0
  58. package/src/lib/app-utils/media-embedded-metadata/webm.d.ts +26 -0
  59. package/src/lib/app-utils/media-embedded-metadata/webm.js +417 -0
  60. package/src/lib/app-utils/media-embedded-metadata/webm.js.map +1 -0
  61. package/src/lib/app-utils/media-embedded-metadata/webp.d.ts +37 -0
  62. package/src/lib/app-utils/media-embedded-metadata/webp.js +272 -0
  63. package/src/lib/app-utils/media-embedded-metadata/webp.js.map +1 -0
  64. package/src/lib/app-utils/media-embedded-metadata/xml.d.ts +231 -0
  65. package/src/lib/app-utils/media-embedded-metadata/xml.js +598 -0
  66. package/src/lib/app-utils/media-embedded-metadata/xml.js.map +1 -0
  67. package/src/lib/app-utils/media-embedded-metadata/xmp.d.ts +100 -0
  68. package/src/lib/app-utils/media-embedded-metadata/xmp.js +1475 -0
  69. package/src/lib/app-utils/media-embedded-metadata/xmp.js.map +1 -0
  70. package/src/lib/app-utils/media-embedded-metadata/zip.d.ts +93 -0
  71. package/src/lib/app-utils/media-embedded-metadata/zip.js +531 -0
  72. package/src/lib/app-utils/media-embedded-metadata/zip.js.map +1 -0
  73. package/src/lib/app-utils/name-search.d.ts +12 -0
  74. package/src/lib/app-utils/name-search.js +11 -0
  75. package/src/lib/app-utils/name-search.js.map +1 -1
  76. package/src/lib/foundation/definitions/platform.types.d.ts +11 -0
  77. package/src/lib/foundation/definitions/platform.types.js.map +1 -1
  78. package/src/server.d.ts +1 -0
  79. package/src/server.js +7 -0
  80. package/src/server.js.map +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/aglyn/src/lib/app-utils/media-embedded-metadata/pdf.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * A PDF's document metadata, read and written back without touching a\n * byte of its page content (AGL-3331). Section numbers are ISO 32000-2.\n *\n * ## What is read\n *\n * The document information dictionary the trailer's `/Info` names\n * (§14.3.3), the catalog's `/Metadata` XMP stream (§14.3.2), the page count\n * (`/Root /Pages /Count`), the version, and whether the file is encrypted\n * (§7.6) or signed (§12.8) — the two things that make it read-only.\n *\n * ## How the file is navigated\n *\n * From the last `startxref`, through every cross-reference section on the\n * `/Prev` chain, newest first, the first definition of an object winning\n * (§7.5.6 incremental updates):\n *\n * - classic `xref` tables with their `trailer` (§7.5.4, §7.5.5);\n * - cross-reference streams (§7.5.8), Flate-compressed with a PNG predictor\n * as most writers leave them;\n * - hybrid files, whose table's trailer points at a supplementary stream\n * with `/XRefStm` (§7.5.8.4);\n * - linearized files (Annex F), which need no special case: their final\n * `startxref` names the first-page section, whose `/Prev` is the rest;\n * - objects compressed into object streams (§7.5.7).\n *\n * A file whose cross-reference data does not hold up — a bad offset, a\n * section that does not parse, a `/Prev` loop — is still READ, from a\n * bounded scan for `N G obj` headers and the last trailer, but it is never\n * WRITTEN: an update chained onto a table we had to guess at could make the\n * file worse for every reader that trusted the table.\n *\n * ## How an edit is written\n *\n * As an incremental update (§7.5.6): the new object definitions, a new\n * cross-reference section of the kind the file already ends with, and a\n * trailer whose `/Prev` points at the old one — all APPENDED. The original\n * bytes are a byte-for-byte prefix of the output, which is what guarantees\n * page content, fonts and images are untouched, and what lets any reader\n * that ignores the update still open the file as it was. An encrypted file\n * (its strings are ciphertext) or a signed one (the update would break the\n * signature) is refused with an {@link EmbeddedWriteError}.\n */\n\nimport {\n decodePdfStream,\n decodePdfTextString,\n encodePdfTextString,\n indexOfBytes,\n lastIndexOfBytes,\n latin1Bytes,\n latin1Text,\n PDF_NULL,\n PdfLexer,\n pdfNameFromText,\n pdfNameText,\n PdfParser,\n serializePdfObject,\n type PdfDict,\n type PdfObject,\n type PdfRef,\n type PdfStream,\n type PdfToken,\n} from './pdf-objects'\nimport { EmbeddedWriteError } from './types'\n\nexport interface PdfMetadataRead {\n /**\n * Document-info entries, in the file's order. Text strings are decoded\n * (PDFDocEncoding, UTF-16BE with BOM, UTF-8 with BOM per PDF 2.0);\n * `CreationDate` and `ModDate` become ISO 8601, with a zone only when the\n * file recorded one. A name value (`/Trapped /True`) reads as its text and\n * any other non-string value as its PDF syntax, both `editable: false`.\n * Empty for an encrypted file, whose strings are ciphertext.\n */\n info: Array<{ name: string; value: string; editable: boolean }>\n /**\n * The catalog's `/Metadata` stream as text. Unfiltered or FlateDecode;\n * any other filter, and an encrypted file, read as `null`.\n */\n xmp: string | null\n /** `/Root /Pages /Count`. */\n pageCount: number | null\n /** The header's `%PDF-x.y`, or the catalog's `/Version` when later (§7.2.2 note, Table 29). */\n version: string | null\n /** The trailer has `/Encrypt`. */\n encrypted: boolean\n /**\n * The file carries a signature, or might: a `/ByteRange` anywhere, a\n * signature field with a value, AcroForm `/SigFlags` 1 or 2, or catalog\n * `/Perms`. Conservative on purpose — a false positive only makes the\n * file read-only; a false negative lets an edit break a signature.\n */\n signed: boolean\n}\n\nexport interface PdfMetadataUpdate {\n /**\n * Document-info entries by raw name (`Title`, `Author`, `Subject`,\n * `Keywords`, `Creator`, `Producer`, `CreationDate`, `ModDate`, or any\n * custom name as {@link readPdf} spelled it). `null` removes the entry.\n * `CreationDate`/`ModDate` take ISO 8601.\n */\n info: Record<string, string | null>\n /** A replacement XMP packet for the catalog's `/Metadata` stream. */\n xmp?: string\n}\n\n/** Cross-reference sections followed along `/Prev` before giving up. */\nconst MAX_SECTIONS = 512\n/** Cross-reference entries kept; far more than a 25 MB file can hold. */\nconst MAX_XREF_ENTRIES = 1 << 21\n/** Decoded size of one cross-reference or object stream. */\nconst MAX_STRUCTURE_BYTES = 64 * 1024 * 1024\n/** Decoded size of the XMP stream. */\nconst MAX_XMP_BYTES = 16 * 1024 * 1024\n/** Objects one object stream may declare. */\nconst MAX_OBJSTM_OBJECTS = 1 << 20\n/** `N G obj` headers the repair scan records. */\nconst MAX_SCAN_OBJECTS = 1 << 21\n/** Objects being loaded at once (a `/Length` inside a stream inside …). */\nconst MAX_LOAD_NESTING = 16\n/** Links followed from a reference to a reference. */\nconst MAX_REF_CHAIN = 16\n/** AcroForm field nodes visited looking for a signature. */\nconst MAX_FIELD_NODES = 20_000\n/** Longest non-string Info value shown as PDF syntax. */\nconst MAX_VALUE_TEXT = 4096\n/** Annex C.2: the most indirect objects a conforming reader must handle. */\nconst MAX_OBJECT_NUMBER = 8_388_607\n\nconst DATE_KEYS = new Set(['CreationDate', 'ModDate'])\n\ntype XrefEntry =\n | { type: 0 }\n | { type: 1; offset: number; gen: number }\n | { type: 2; stream: number; index: number }\n\ninterface XrefSection {\n offset: number\n kind: 'table' | 'stream'\n trailer: PdfDict\n entries: Array<[number, XrefEntry]>\n}\n\ninterface ObjectStream {\n data: Uint8Array\n first: number\n /** Object numbers and offsets (from `first`) in header order. */\n numbers: number[]\n offsets: number[]\n}\n\ninterface ObjectHeader {\n num: number\n gen: number\n offset: number\n}\n\nconst ascii = (text: string) => latin1Bytes(text)\nconst STARTXREF = ascii('startxref')\nconst OBJ = ascii('obj')\nconst TRAILER = ascii('trailer')\nconst XREF_TYPE = ascii('/XRef')\nconst OBJSTM_TYPE = ascii('/ObjStm')\nconst CATALOG_TYPE = ascii('/Catalog')\nconst BYTE_RANGE = ascii('/ByteRange')\n\nfunction isDigit(b: number): boolean {\n return b >= 0x30 && b <= 0x39\n}\n\nfunction isSpace(b: number): boolean {\n return b === 0x00 || b === 0x09 || b === 0x0a || b === 0x0c || b === 0x0d || b === 0x20\n}\n\n/** Whether `b` can continue a keyword — so `pattern` found before it is only a prefix. */\nfunction continuesWord(b: number): boolean {\n if (b < 0) return false\n return !isSpace(b) && !'()<>[]{}/%'.includes(String.fromCharCode(b))\n}\n\n/** A non-negative safe integer, or `null`. */\nfunction intValue(obj: PdfObject | undefined): number | null {\n return obj?.kind === 'number' && Number.isSafeInteger(obj.value) && obj.value >= 0\n ? obj.value\n : null\n}\n\nfunction isInt(token: PdfToken): token is { type: 'number'; value: number; text: string } {\n return token.type === 'number' && /^\\d+$/.test(token.text)\n}\n\nfunction asDict(obj: PdfObject | undefined): PdfDict | null {\n if (obj?.kind === 'dict') return obj\n if (obj?.kind === 'stream') return obj.dict\n return null\n}\n\nfunction nameIs(obj: PdfObject | undefined, name: string): boolean {\n return obj?.kind === 'name' && obj.name === name\n}\n\n/**\n * One part of a read, so a failure in it costs only that part. Nothing\n * below is expected to throw — it is bounded and total — but a read of\n * hostile bytes is where \"expected\" deserves a backstop.\n */\nfunction attempt<T>(read: () => T, fallback: T): T {\n try {\n return read()\n } catch {\n return fallback\n }\n}\n\n/** §7.5.2: `%PDF-x.y`, which Acrobat accepts anywhere in the first 1024 bytes. */\nfunction findHeader(bytes: Uint8Array): { offset: number; version: string | null } | null {\n const offset = indexOfBytes(bytes, ascii('%PDF-'), 0, 1024 + 5)\n if (offset < 0) return null\n const head = latin1Text(bytes.subarray(offset + 5, offset + 16))\n const match = /^(\\d{1,2})\\.(\\d{1,2})/.exec(head)\n return { offset, version: match ? `${Number(match[1])}.${Number(match[2])}` : null }\n}\n\n/** The byte offset after the file's LAST `startxref` (§7.5.5), or `null`. */\nfunction findStartxref(bytes: Uint8Array): number | null {\n const at = lastIndexOfBytes(bytes, STARTXREF)\n if (at < 0) return null\n const token = new PdfLexer(bytes, at + STARTXREF.length).next()\n return isInt(token) ? token.value : null\n}\n\n/** A big-endian unsigned field of a cross-reference stream entry. */\nfunction readField(data: Uint8Array, at: number, width: number): number {\n let value = 0\n for (let i = 0; i < width; i++) value = value * 256 + (data[at + i] ?? 0)\n return value\n}\n\n/** The `N G` before an `obj` keyword at `at`, walking back over at most a few bytes. */\nfunction headerBefore(bytes: Uint8Array, at: number): ObjectHeader | null {\n let j = at - 1\n const skipSpace = () => {\n const stop = j - 64\n if (!isSpace(bytes[j] ?? -1)) return false\n while (j > stop && isSpace(bytes[j] ?? -1)) j--\n return true\n }\n const digits = (max: number) => {\n const end = j\n while (end - j < max && isDigit(bytes[j] ?? -1)) j--\n if (end === j) return null\n let value = 0\n for (let k = j + 1; k <= end; k++) value = value * 10 + ((bytes[k] ?? 0x30) - 0x30)\n return value\n }\n if (!skipSpace()) return null\n const gen = digits(5)\n if (gen === null || !skipSpace()) return null\n const num = digits(10)\n if (num === null) return null\n if (j >= 0 && continuesWord(bytes[j] ?? -1)) return null\n return { num, gen, offset: j + 1 }\n}\n\n/**\n * The file, navigated. Objects load lazily and are cached; everything a\n * reader asks of it returns `null` rather than throwing.\n */\nclass PdfFile {\n readonly entries = new Map<number, XrefEntry>()\n /** The sections on the `/Prev` chain, newest first. */\n readonly sections: XrefSection[] = []\n /** Every trailer dictionary seen; `/Encrypt` in any of them counts. */\n readonly trailers: PdfDict[] = []\n /** The newest trailer — the one whose `/Root` and `/Info` are current. */\n trailer: PdfDict | null = null\n /** The offset the final `startxref` gives. */\n startxref = -1\n /**\n * Set when anything had to be found some way other than through a sound\n * cross-reference chain. A repaired file is read, never written.\n */\n repaired = false\n\n private readonly cache = new Map<number, PdfObject | null>()\n private readonly loading = new Set<number>()\n private readonly objectStreams = new Map<number, ObjectStream | null>()\n private scanned: { headers: ObjectHeader[]; latest: Map<number, ObjectHeader> } | null =\n null\n\n constructor(\n readonly bytes: Uint8Array,\n readonly headerOffset: number,\n readonly headerVersion: string | null,\n ) {}\n\n /** The `/Root` reference and the catalog it names. */\n root(): { ref: PdfRef; catalog: PdfDict } | null {\n const ref = this.trailer?.entries.get('Root')\n if (ref?.kind !== 'ref') return null\n const catalog = this.resolve(ref)\n return catalog?.kind === 'dict' ? { ref, catalog } : null\n }\n\n /** The `/Info` dictionary, when the newest trailer names one. */\n info(): PdfDict | null {\n const info = this.resolve(this.trailer?.entries.get('Info'))\n return info?.kind === 'dict' ? info : null\n }\n\n encrypted(): boolean {\n return this.trailers.some((trailer) => trailer.entries.has('Encrypt'))\n }\n\n /** Follows references to a direct object; a dangling one is `null` (§7.3.10). */\n readonly resolve = (obj: PdfObject | undefined): PdfObject | undefined => {\n let value = obj\n for (let i = 0; value?.kind === 'ref' && i < MAX_REF_CHAIN; i++) {\n value = this.getObject(value.num) ?? PDF_NULL\n }\n return value?.kind === 'ref' ? PDF_NULL : value\n }\n\n getObject(num: number): PdfObject | null {\n if (!Number.isSafeInteger(num) || num < 0) return null\n const cached = this.cache.get(num)\n if (cached !== undefined) return cached\n if (this.loading.has(num) || this.loading.size >= MAX_LOAD_NESTING) return null\n this.loading.add(num)\n let obj: PdfObject | null\n try {\n obj = this.loadObject(num)\n } finally {\n this.loading.delete(num)\n }\n this.cache.set(num, obj)\n return obj\n }\n\n private loadObject(num: number): PdfObject | null {\n const entry = this.entries.get(num)\n if (entry?.type === 0) return null\n if (entry?.type === 1) {\n const obj = this.parseAt(entry.offset, num)\n if (obj) return obj\n this.repaired = true\n } else if (entry?.type === 2) {\n const obj = this.loadCompressed(entry.stream, entry.index, num)\n if (obj) return obj\n this.repaired = true\n }\n // Not in the table (a dangling reference is legal), or not where the\n // table says: look for it by scanning.\n const header = this.scan().latest.get(num)\n if (!header) return null\n this.repaired = true\n return this.parseAt(header.offset, num)\n }\n\n private parseAt(offset: number, num: number): PdfObject | null {\n const tryAt = (at: number) => {\n if (!(at >= 0 && at < this.bytes.length)) return null\n const parser = new PdfParser(this.bytes, at, {\n resolveLength: (ref) => intValue(this.resolve(ref) ?? undefined),\n })\n const parsed = parser.parseIndirectObject()\n return parsed && parsed.num === num ? parsed.obj : null\n }\n const obj = tryAt(offset)\n if (obj || this.headerOffset === 0) return obj\n // Offsets counted from the header rather than the file's first byte.\n const shifted = tryAt(offset + this.headerOffset)\n if (shifted) this.repaired = true\n return shifted\n }\n\n private loadCompressed(stream: number, index: number, num: number): PdfObject | null {\n const objstm = this.objectStream(stream)\n if (!objstm) return null\n let at = objstm.numbers[index] === num ? index : objstm.numbers.indexOf(num)\n if (at < 0) return null\n const offset = objstm.offsets[at]\n if (offset === undefined) return null\n at = objstm.first + offset\n if (at >= objstm.data.length) return null\n return new PdfParser(objstm.data, at).parseObject()\n }\n\n /** §7.5.7: an object stream's header of `N` number/offset pairs. */\n private objectStream(num: number): ObjectStream | null {\n if (this.objectStreams.has(num)) return this.objectStreams.get(num) ?? null\n this.objectStreams.set(num, null)\n // A stream is never itself compressed; one claiming to be is a loop.\n if (this.entries.get(num)?.type === 2) return null\n const obj = this.getObject(num)\n if (obj?.kind !== 'stream') return null\n const n = intValue(obj.dict.entries.get('N'))\n const first = intValue(obj.dict.entries.get('First'))\n if (n === null || first === null || n > MAX_OBJSTM_OBJECTS) return null\n const data = decodePdfStream(obj, this.resolve, MAX_STRUCTURE_BYTES)\n if (!data || first > data.length) return null\n const lexer = new PdfLexer(data, 0, first)\n const numbers: number[] = []\n const offsets: number[] = []\n for (let i = 0; i < n; i++) {\n const a = lexer.next()\n const b = lexer.next()\n if (!isInt(a) || !isInt(b)) break\n numbers.push(a.value)\n offsets.push(b.value)\n }\n const objstm = { data, first, numbers, offsets }\n this.objectStreams.set(num, objstm)\n return objstm\n }\n\n /** The next free object number for an appended object. */\n nextObjectNumber(): number {\n let next = Math.max(1, intValue(this.trailer?.entries.get('Size')) ?? 0)\n for (const num of this.entries.keys()) if (num >= next) next = num + 1\n return next\n }\n\n // -------------------------------------------------------------------------\n // The cross-reference chain\n\n /** Reads the `/Prev` chain from the last `startxref`. `false` when it does not hold up. */\n readXref(): boolean {\n const start = findStartxref(this.bytes)\n if (start === null) return false\n this.startxref = start\n const visited = new Set<number>()\n let offset: number | null = start\n while (offset !== null) {\n if (visited.has(offset) || visited.size >= MAX_SECTIONS) {\n // A /Prev loop: what was read stands, but the file is not sound.\n this.repaired = true\n break\n }\n visited.add(offset)\n const section = this.readSection(offset)\n if (!section) return false\n const local = new Map(section.entries)\n if (section.kind === 'table') {\n // §7.5.8.4: a hybrid file's table lists the objects a PDF 1.4\n // reader can find; the stream its /XRefStm names adds the ones in\n // object streams, which the table marks free.\n const stmOffset = intValue(section.trailer.entries.get('XRefStm'))\n if (stmOffset !== null && !visited.has(stmOffset)) {\n visited.add(stmOffset)\n const stm = this.readSection(stmOffset)\n if (stm?.kind !== 'stream') return false\n for (const [num, entry] of stm.entries) {\n if (local.get(num)?.type !== 1) local.set(num, entry)\n }\n }\n }\n for (const [num, entry] of local) {\n if (!this.entries.has(num)) this.entries.set(num, entry)\n }\n if (this.entries.size > MAX_XREF_ENTRIES) return false\n this.sections.push(section)\n this.trailers.push(section.trailer)\n const prev = intValue(section.trailer.entries.get('Prev'))\n // Some writers put /Prev 0 on a file's only section; 0 is the header.\n offset = prev ? prev : null\n }\n this.trailer = this.sections[0]?.trailer ?? null\n return this.trailer !== null\n }\n\n private readSection(offset: number): XrefSection | null {\n if (!(offset >= 0 && offset < this.bytes.length)) return null\n const lexer = new PdfLexer(this.bytes, offset)\n return lexer.peekKeyword('xref')\n ? this.readTable(lexer, offset)\n : this.readXrefStream(offset)\n }\n\n /** §7.5.4: `xref`, subsections of `start count` and 20-byte entries, then `trailer`. */\n private readTable(lexer: PdfLexer, offset: number): XrefSection | null {\n lexer.next()\n const entries: Array<[number, XrefEntry]> = []\n while (!lexer.peekKeyword('trailer')) {\n const startToken = lexer.next()\n const countToken = lexer.next()\n if (!isInt(startToken) || !isInt(countToken)) return null\n let start = startToken.value\n const count = countToken.value\n if (entries.length + count > MAX_XREF_ENTRIES) return null\n for (let i = 0; i < count; i++) {\n const a = lexer.next()\n const b = lexer.next()\n const t = lexer.next()\n if (!isInt(a) || !isInt(b) || t.type !== 'keyword') return null\n if (t.text !== 'n' && t.text !== 'f') return null\n // A common writer bug numbers the first subsection from 1 although\n // it opens with object 0's free-list head; pdf.js and Poppler shift it.\n if (i === 0 && start === 1 && t.text === 'f' && a.value === 0 && b.value === 65535) {\n start = 0\n }\n entries.push([\n start + i,\n t.text === 'n' && a.value > 0\n ? { type: 1, offset: a.value, gen: b.value }\n : { type: 0 },\n ])\n }\n }\n lexer.next()\n const trailer = new PdfParser(this.bytes, lexer.pos).parseObject()\n if (trailer?.kind !== 'dict') return null\n return { offset, kind: 'table', trailer, entries }\n }\n\n /**\n * §7.5.8: an indirect stream object with `/Type /XRef`. Its entries are\n * `/W`-wide big-endian fields, listed for the `/Index` ranges (default\n * `[0 Size]`). Its dictionary entries are direct (§7.5.8.2), so nothing\n * here resolves a reference.\n */\n private readXrefStream(offset: number): XrefSection | null {\n const parsed = new PdfParser(this.bytes, offset).parseIndirectObject()\n if (parsed?.obj.kind !== 'stream') return null\n const stream: PdfStream = parsed.obj\n const dict = stream.dict.entries\n if (!nameIs(dict.get('Type'), 'XRef')) return null\n const direct = (obj: PdfObject | undefined) => obj\n const data = decodePdfStream(stream, direct, MAX_STRUCTURE_BYTES)\n const w = dict.get('W')\n if (!data || w?.kind !== 'array' || w.items.length < 3) return null\n const widths = w.items.slice(0, 3).map((item) => intValue(item))\n const [w0, w1, w2] = widths\n if (w0 == null || w1 == null || w2 == null) return null\n if (w0 > 4 || w1 > 8 || w2 > 8 || w0 + w1 + w2 === 0) return null\n const size = intValue(dict.get('Size')) ?? 0\n const index = dict.get('Index')\n const ranges =\n index?.kind === 'array' ? index.items.map((item) => intValue(item)) : [0, size]\n if (ranges.length % 2 || ranges.some((value) => value === null)) return null\n const width = w0 + w1 + w2\n const entries: Array<[number, XrefEntry]> = []\n let at = 0\n for (let r = 0; r < ranges.length; r += 2) {\n const first = ranges[r] ?? 0\n const count = ranges[r + 1] ?? 0\n for (let i = 0; i < count && at + width <= data.length; i++, at += width) {\n if (entries.length >= MAX_XREF_ENTRIES) return null\n // §7.5.8.3: a missing type field means type 1.\n const type = w0 ? readField(data, at, w0) : 1\n const a = readField(data, at + w0, w1)\n const b = readField(data, at + w0 + w1, w2)\n entries.push([\n first + i,\n type === 1\n ? { type: 1, offset: a, gen: b }\n : type === 2\n ? { type: 2, stream: a, index: b }\n : { type: 0 },\n ])\n }\n }\n return { offset, kind: 'stream', trailer: stream.dict, entries }\n }\n\n // -------------------------------------------------------------------------\n // Repair\n\n /** Every `N G obj` header in the file, bounded; the last one per number wins. */\n private scan(): { headers: ObjectHeader[]; latest: Map<number, ObjectHeader> } {\n if (this.scanned) return this.scanned\n const headers: ObjectHeader[] = []\n const latest = new Map<number, ObjectHeader>()\n const { bytes } = this\n for (\n let at = indexOfBytes(bytes, OBJ);\n at >= 0 && headers.length < MAX_SCAN_OBJECTS;\n at = indexOfBytes(bytes, OBJ, at + OBJ.length)\n ) {\n if (continuesWord(bytes[at + OBJ.length] ?? -1)) continue\n const header = headerBefore(bytes, at)\n if (!header) continue\n headers.push(header)\n latest.set(header.num, header)\n }\n this.scanned = { headers, latest }\n return this.scanned\n }\n\n /** The object whose header is the last one before `at`. */\n private objectAround(at: number): ObjectHeader | null {\n const { headers } = this.scan()\n let lo = 0\n let hi = headers.length - 1\n let found: ObjectHeader | null = null\n while (lo <= hi) {\n const mid = (lo + hi) >> 1\n const header = headers[mid]\n if (!header) break\n if (header.offset < at) {\n found = header\n lo = mid + 1\n } else {\n hi = mid - 1\n }\n }\n return found\n }\n\n /**\n * Every occurrence of `pattern` as a whole token: not continued by a\n * regular character, and — for a keyword, which unlike a name does not\n * open with its own delimiter — not preceded by one either.\n */\n private *occurrences(pattern: Uint8Array): Generator<number> {\n const keyword = pattern[0] !== 0x2f\n let count = 0\n for (\n let at = indexOfBytes(this.bytes, pattern);\n at >= 0 && count < MAX_SCAN_OBJECTS;\n at = indexOfBytes(this.bytes, pattern, at + pattern.length)\n ) {\n count++\n if (continuesWord(this.bytes[at + pattern.length] ?? -1)) continue\n if (keyword && continuesWord(this.bytes[at - 1] ?? -1)) continue\n yield at\n }\n }\n\n /**\n * Rebuilds the object table from a scan when the cross-reference data\n * does not hold up, as Poppler and pdf.js do: the last definition of each\n * object in file order, including those in object streams, and the last\n * trailer (classic or cross-reference stream) whose `/Root` is a\n * dictionary — or, failing that, the last `/Type /Catalog` object.\n */\n rebuild(): void {\n this.repaired = true\n this.entries.clear()\n this.cache.clear()\n this.objectStreams.clear()\n this.sections.length = 0\n this.trailer = null\n const { headers } = this.scan()\n for (const h of headers) this.entries.set(h.num, { type: 1, offset: h.offset, gen: h.gen })\n\n // Object streams add their objects at the stream's own position, so\n // the last definition in file order still wins.\n const compressed: Array<{ at: number; num: number; entry: XrefEntry }> = []\n for (const at of this.occurrences(OBJSTM_TYPE)) {\n const header = this.objectAround(at)\n if (!header) continue\n const objstm = this.objectStream(header.num)\n objstm?.numbers.forEach((num, index) =>\n compressed.push({ at: header.offset, num, entry: { type: 2, stream: header.num, index } }),\n )\n }\n if (compressed.length) {\n compressed.sort((a, b) => a.at - b.at)\n this.entries.clear()\n this.cache.clear()\n let next = 0\n for (const h of headers) {\n for (; next < compressed.length && (compressed[next]?.at ?? Infinity) < h.offset; next++) {\n const def = compressed[next]\n if (def) this.entries.set(def.num, def.entry)\n }\n this.entries.set(h.num, { type: 1, offset: h.offset, gen: h.gen })\n }\n for (; next < compressed.length; next++) {\n const def = compressed[next]\n if (def) this.entries.set(def.num, def.entry)\n }\n }\n\n const candidates: Array<{ at: number; dict: PdfDict }> = []\n for (const at of this.occurrences(TRAILER)) {\n const dict = new PdfParser(this.bytes, at + TRAILER.length).parseObject()\n if (dict?.kind === 'dict') candidates.push({ at, dict })\n }\n for (const at of this.occurrences(XREF_TYPE)) {\n const header = this.objectAround(at)\n const obj = header && this.getObject(header.num)\n if (obj?.kind === 'stream' && nameIs(obj.dict.entries.get('Type'), 'XRef')) {\n candidates.push({ at, dict: obj.dict })\n }\n }\n candidates.sort((a, b) => a.at - b.at)\n for (const candidate of candidates) this.trailers.push(candidate.dict)\n for (let i = candidates.length - 1; i >= 0 && !this.trailer; i--) {\n const dict = candidates[i]?.dict\n const root = dict?.entries.get('Root')\n if (dict && root?.kind === 'ref' && this.resolve(root)?.kind === 'dict') {\n this.trailer = dict\n }\n }\n if (this.trailer) return\n\n let catalog: PdfRef | null = null\n for (const at of this.occurrences(CATALOG_TYPE)) {\n const header = this.objectAround(at)\n const obj = header && this.getObject(header.num)\n if (header && obj?.kind === 'dict' && nameIs(obj.entries.get('Type'), 'Catalog')) {\n catalog = { kind: 'ref', num: header.num, gen: header.gen }\n }\n }\n let checked = 0\n for (const [num, entry] of this.entries) {\n if (entry.type !== 2 || ++checked > 100_000) continue\n const obj = this.getObject(num)\n if (obj?.kind === 'dict' && nameIs(obj.entries.get('Type'), 'Catalog')) {\n catalog = { kind: 'ref', num, gen: 0 }\n }\n }\n if (catalog) {\n const last = candidates.at(-1)?.dict\n const entries = new Map(last?.entries ?? [])\n entries.set('Root', catalog)\n this.trailer = { kind: 'dict', entries }\n }\n }\n}\n\n/** Opens the file: its cross-reference chain, or a rebuild from a scan. */\nfunction openPdf(bytes: Uint8Array): PdfFile | null {\n const header = findHeader(bytes)\n if (!header) return null\n const file = new PdfFile(bytes, header.offset, header.version)\n if (!file.readXref() || !file.root()) file.rebuild()\n return file\n}\n\n// ---------------------------------------------------------------------------\n// Dates (§7.9.4)\n\n/**\n * `D:YYYYMMDDHHmmSSOHH'mm'`, every field after the year optional, the\n * apostrophes forgiven (writers disagree on the trailing one). `Z` may be\n * followed by a redundant `00'00'`.\n */\nconst PDF_DATE =\n /^(?:D:)?(\\d{4})(\\d{2})?(\\d{2})?(\\d{2})?(\\d{2})?(\\d{2})?(?:([Zz])(?:00'?(?:00'?)?)?|([+-])(\\d{2})'?(?:(\\d{2})'?)?)?$/\n\n/**\n * A PDF date as ISO 8601, or `null` when it is not one. Missing month and\n * day default to 01 (§7.9.4); a time is shown only when the date has one,\n * and a zone only when both were recorded — never invented.\n */\nexport function pdfDateToIso(text: string): string | null {\n const trimmed = text.trim()\n const match = PDF_DATE.exec(trimmed)\n if (!match) return null\n const [, year, month = '01', day = '01', hour, minute = '00', second = '00', utc, sign, zh, zm = '00'] =\n match\n const inRange = (value: string | undefined, min: number, max: number) =>\n value === undefined || (Number(value) >= min && Number(value) <= max)\n if (\n !inRange(month, 1, 12) ||\n !inRange(day, 1, 31) ||\n !inRange(hour, 0, 23) ||\n !inRange(minute, 0, 59) ||\n !inRange(second, 0, 59) ||\n !inRange(zh, 0, 23) ||\n !inRange(zm, 0, 59)\n ) {\n return null\n }\n let iso = `${year}-${month}-${day}`\n if (hour === undefined) return iso\n iso += `T${hour}:${minute}:${second}`\n if (sign && zh !== undefined) return `${iso}${sign}${zh}:${zm}`\n return utc ? `${iso}Z` : iso\n}\n\nconst ISO_DATE =\n /^(\\d{4})-(\\d{2})-(\\d{2})(?:T(\\d{2}):(\\d{2})(?::(\\d{2})(?:\\.\\d+)?)?(Z|[+-]\\d{2}:\\d{2})?)?$/\n\n/** ISO 8601 as a PDF date (§7.9.4), or `null` when it is not ISO. */\nexport function isoToPdfDate(value: string): string | null {\n const match = ISO_DATE.exec(value.trim())\n if (!match) return null\n const [, year, month, day, hour, minute, second = '00', zone] = match\n let date = `D:${year}${month}${day}`\n if (hour === undefined) return date\n date += `${hour}${minute}${second}`\n if (zone === 'Z') return `${date}Z`\n if (zone) return `${date}${zone.slice(0, 3)}'${zone.slice(4)}'`\n return date\n}\n\n// ---------------------------------------------------------------------------\n// Reading\n\nfunction readInfo(file: PdfFile, info: PdfDict | null): PdfMetadataRead['info'] {\n const out: PdfMetadataRead['info'] = []\n if (!info) return out\n for (const [key, raw] of info.entries) {\n const value = file.resolve(raw)\n const name = pdfNameText(key)\n if (!value || value.kind === 'null' || value.kind === 'stream') continue\n if (value.kind === 'string') {\n const text = decodePdfTextString(value.bytes)\n const date = DATE_KEYS.has(key) ? pdfDateToIso(text) : null\n out.push({ name, value: date ?? text, editable: true })\n } else if (value.kind === 'name') {\n out.push({ name, value: pdfNameText(value.name), editable: false })\n } else {\n const text = serializePdfObject(value)\n out.push({\n name,\n value: text.length > MAX_VALUE_TEXT ? `${text.slice(0, MAX_VALUE_TEXT)}…` : text,\n editable: false,\n })\n }\n }\n return out\n}\n\n/** XMP packets are UTF-8, -16 or -32 (XMP part 1 §7.1); PDF writers use UTF-8. */\nfunction xmpText(data: Uint8Array): string {\n if (data[0] === 0xfe && data[1] === 0xff) return new TextDecoder('utf-16be').decode(data)\n if (data[0] === 0xff && data[1] === 0xfe) return new TextDecoder('utf-16le').decode(data)\n return new TextDecoder('utf-8').decode(data)\n}\n\nfunction readXmp(file: PdfFile, catalog: PdfDict | null): string | null {\n const metadata = file.resolve(catalog?.entries.get('Metadata'))\n if (metadata?.kind !== 'stream') return null\n const data = decodePdfStream(metadata, file.resolve, MAX_XMP_BYTES)\n return data ? xmpText(data) : null\n}\n\nfunction readPageCount(file: PdfFile, catalog: PdfDict | null): number | null {\n const pages = asDict(file.resolve(catalog?.entries.get('Pages')))\n return intValue(file.resolve(pages?.entries.get('Count')))\n}\n\nfunction readVersion(file: PdfFile, catalog: PdfDict | null): string | null {\n const header = file.headerVersion\n const version = file.resolve(catalog?.entries.get('Version'))\n const match = version?.kind === 'name' ? /^(\\d{1,2})\\.(\\d{1,2})$/.exec(version.name) : null\n if (!match) return header\n const catalogVersion = `${Number(match[1])}.${Number(match[2])}`\n if (!header) return catalogVersion\n const [hMajor = 0, hMinor = 0] = header.split('.').map(Number)\n const later = Number(match[1]) * 100 + Number(match[2]) > hMajor * 100 + hMinor\n return later ? catalogVersion : header\n}\n\n/**\n * Whether the file is, or may be, signed. A signature dictionary cannot\n * live in an object stream — its `/ByteRange` must exclude `/Contents` in\n * the file's own bytes — so a raw scan for `/ByteRange` finds every real\n * signature and some false alarms, which is the side to err on. The\n * catalog checks catch signed-looking structure the scan cannot.\n */\nfunction readSigned(file: PdfFile, catalog: PdfDict | null): boolean {\n if (indexOfBytes(file.bytes, BYTE_RANGE) >= 0) return true\n if (!catalog) return false\n // §12.8.4: /Perms holds DocMDP and usage-rights (UR3) signatures.\n if (catalog.entries.has('Perms')) return true\n const acroForm = asDict(file.resolve(catalog.entries.get('AcroForm')))\n if (!acroForm) return false\n // §12.7.3 Table 225: bit 1 SignaturesExist, bit 2 AppendOnly.\n const flags = intValue(file.resolve(acroForm.entries.get('SigFlags'))) ?? 0\n if (flags & 3) return true\n const fields = file.resolve(acroForm.entries.get('Fields'))\n if (fields?.kind !== 'array') return false\n const stack: Array<{ node: PdfObject; sig: boolean }> = fields.items.map((node) => ({\n node,\n sig: false,\n }))\n const seen = new Set<number>()\n for (let visited = 0; stack.length; visited++) {\n // Unsure after this many nodes: say signed.\n if (visited > MAX_FIELD_NODES) return true\n const next = stack.pop()\n if (!next) break\n if (next.node.kind === 'ref') {\n if (seen.has(next.node.num)) continue\n seen.add(next.node.num)\n }\n const field = asDict(file.resolve(next.node))\n if (!field) continue\n // /FT is inheritable (§12.7.4.1), so a kid inherits its parent's type.\n const ft = file.resolve(field.entries.get('FT'))\n const sig = ft ? nameIs(ft, 'Sig') : next.sig\n // A value that is there but does not resolve still counts: unsure.\n const value = field.entries.get('V')\n if (sig && value && value.kind !== 'null') return true\n const kids = file.resolve(field.entries.get('Kids'))\n if (kids?.kind === 'array') {\n for (const kid of kids.items) stack.push({ node: kid, sig })\n }\n }\n return false\n}\n\n/**\n * The metadata a PDF carries, or `null` when the bytes are not a PDF or\n * nothing in them could be found — neither a catalog nor an Info\n * dictionary. Never throws.\n */\nexport function readPdf(bytes: Uint8Array): PdfMetadataRead | null {\n const file = attempt(() => openPdf(bytes), null)\n if (!file) return null\n const catalog = attempt(() => file.root()?.catalog ?? null, null)\n const info = attempt(() => file.info(), null)\n if (!catalog && !info) return null\n const encrypted = attempt(() => file.encrypted(), true)\n return {\n info: encrypted ? [] : attempt(() => readInfo(file, info), []),\n xmp: encrypted ? null : attempt(() => readXmp(file, catalog), null),\n pageCount: attempt(() => readPageCount(file, catalog), null),\n version: attempt(() => readVersion(file, catalog), file.headerVersion),\n encrypted,\n signed: attempt(() => readSigned(file, catalog), true),\n }\n}\n\n// ---------------------------------------------------------------------------\n// Writing\n\nconst DAMAGED =\n \"This PDF's internal index is damaged, so an edit cannot be written into it safely.\"\n\n/** An Info key as name bytes, matching an existing entry's spelling when there is one. */\nfunction infoKey(entries: Map<string, PdfObject>, key: string): string {\n for (const existing of entries.keys()) {\n if (pdfNameText(existing) === key) return existing\n }\n const name = pdfNameFromText(key)\n if (!key || key.includes('\\u0000') || name.length > 127) {\n // Annex C.2: 127 bytes is the longest name a reader must accept.\n throw new EmbeddedWriteError(`\"${key.slice(0, 40)}\" cannot be used as a PDF field name.`)\n }\n return name\n}\n\nfunction infoValue(key: string, value: string): PdfObject {\n if (DATE_KEYS.has(key)) {\n const date = isoToPdfDate(value)\n if (date) return { kind: 'string', bytes: latin1Bytes(date), hex: false }\n }\n // §14.3.3 Table 349: /Trapped is a name.\n if (key === 'Trapped' && /^(?:True|False|Unknown)$/.test(value)) {\n return { kind: 'name', name: value }\n }\n return encodePdfTextString(value)\n}\n\ninterface NewObject {\n ref: PdfRef\n /** What the object must read back as. */\n expect: PdfObject\n body: Uint8Array\n}\n\nfunction concat(chunks: Uint8Array[]): Uint8Array {\n let length = 0\n for (const chunk of chunks) length += chunk.length\n const out = new Uint8Array(length)\n let at = 0\n for (const chunk of chunks) {\n out.set(chunk, at)\n at += chunk.length\n }\n return out\n}\n\nfunction dictObject(ref: PdfRef, dict: PdfDict): NewObject {\n return {\n ref,\n expect: dict,\n body: latin1Bytes(`${ref.num} ${ref.gen} obj\\n${serializePdfObject(dict)}\\nendobj\\n`),\n }\n}\n\n/** §14.3.2: an uncompressed metadata stream, so any tool can find the packet. */\nfunction metadataObject(ref: PdfRef, data: Uint8Array): NewObject {\n const dict: PdfDict = {\n kind: 'dict',\n entries: new Map<string, PdfObject>([\n ['Type', { kind: 'name', name: 'Metadata' }],\n ['Subtype', { kind: 'name', name: 'XML' }],\n ['Length', { kind: 'number', value: data.length, text: String(data.length) }],\n ]),\n }\n return {\n ref,\n expect: { kind: 'stream', dict, data },\n body: concat([\n latin1Bytes(`${ref.num} ${ref.gen} obj\\n${serializePdfObject(dict)}\\nstream\\n`),\n data,\n latin1Bytes('\\nendstream\\nendobj\\n'),\n ]),\n }\n}\n\n/** Consecutive object numbers grouped into `[start, count]` subsections. */\nfunction subsections<T extends { num: number }>(items: T[]): Array<{ start: number; items: T[] }> {\n const runs: Array<{ start: number; items: T[] }> = []\n for (const item of [...items].sort((a, b) => a.num - b.num)) {\n const run = runs.at(-1)\n if (run && run.start + run.items.length === item.num) run.items.push(item)\n else runs.push({ start: item.num, items: [item] })\n }\n return runs\n}\n\nfunction sameObject(actual: PdfObject | null, expected: PdfObject): boolean {\n if (!actual) return false\n if (expected.kind === 'stream') {\n if (actual.kind !== 'stream') return false\n const { data } = expected\n return (\n actual.data.length === data.length &&\n actual.data.every((b, i) => b === data[i]) &&\n serializePdfObject(actual.dict) === serializePdfObject(expected.dict)\n )\n }\n return serializePdfObject(actual) === serializePdfObject(expected)\n}\n\n/**\n * Writes an edit as an incremental update (§7.5.6) appended to `bytes`.\n * Returns the new file; `bytes` is a prefix of it. Throws\n * {@link EmbeddedWriteError} for a file that is not a PDF, is encrypted or\n * signed, or whose cross-reference data had to be repaired to be read —\n * and, as a last line, when the output does not read back as written.\n */\nexport function writePdf(bytes: Uint8Array, update: PdfMetadataUpdate): Uint8Array {\n const file = attempt(() => openPdf(bytes), null)\n if (!file) throw new EmbeddedWriteError('This file could not be read as a PDF, so it was left as it was.')\n if (file.encrypted()) {\n throw new EmbeddedWriteError('This PDF is encrypted, so its details cannot be changed.')\n }\n const root = attempt(() => file.root(), null)\n if (attempt(() => readSigned(file, root?.catalog ?? null), true)) {\n throw new EmbeddedWriteError(\n 'This PDF is digitally signed; changing it would invalidate the signature.',\n )\n }\n const patch = Object.entries(update.info ?? {})\n if (!patch.length && update.xmp === undefined) return bytes.slice()\n const trailer = file.trailer\n if (!root || !trailer) throw new EmbeddedWriteError(DAMAGED)\n\n let next = file.nextObjectNumber()\n const objects: NewObject[] = []\n\n // The Info dictionary: every entry it has, the patch applied in place.\n let infoRef: PdfObject | undefined = trailer.entries.get('Info')\n if (patch.length) {\n const current = asDict(file.resolve(infoRef))\n const entries = new Map(current?.entries ?? [])\n for (const [key, value] of patch) {\n if (value === undefined) continue\n const name = infoKey(entries, key)\n if (value === null) entries.delete(name)\n else entries.set(name, infoValue(name, value))\n }\n const ref: PdfRef = infoRef?.kind === 'ref' ? infoRef : { kind: 'ref', num: next++, gen: 0 }\n infoRef = ref\n objects.push(dictObject(ref, { kind: 'dict', entries }))\n }\n\n // The XMP stream: redefined in place, or added and linked from a\n // redefinition of the catalog that keeps every other entry it had.\n if (update.xmp !== undefined) {\n const data = new TextEncoder().encode(update.xmp)\n const existing = root.catalog.entries.get('Metadata')\n const ref: PdfRef =\n existing?.kind === 'ref' ? existing : { kind: 'ref', num: next++, gen: 0 }\n objects.push(metadataObject(ref, data))\n if (existing?.kind !== 'ref') {\n const entries = new Map(root.catalog.entries)\n entries.set('Metadata', ref)\n objects.push(dictObject(root.ref, { kind: 'dict', entries }))\n }\n }\n\n // Everything above resolved through the table; only now is it known\n // whether any of it had to be found another way.\n if (file.repaired || file.headerOffset !== 0 || file.startxref <= 0) {\n throw new EmbeddedWriteError(DAMAGED)\n }\n const nums = new Set(objects.map((o) => o.ref.num))\n if (\n nums.size !== objects.length ||\n objects.some((o) => o.ref.num < 1 || o.ref.gen > 65535) ||\n next > MAX_OBJECT_NUMBER\n ) {\n throw new EmbeddedWriteError(DAMAGED)\n }\n\n // §7.5.6: the update starts on a line of its own.\n const last = bytes[bytes.length - 1]\n const chunks: Uint8Array[] = [bytes]\n if (last !== 0x0a && last !== 0x0d) chunks.push(latin1Bytes('\\n'))\n let offset = bytes.length + (chunks.length - 1)\n const placed: Array<{ num: number; gen: number; offset: number }> = []\n for (const object of objects) {\n placed.push({ num: object.ref.num, gen: object.ref.gen, offset })\n chunks.push(object.body)\n offset += object.body.length\n }\n const xrefOffset = offset\n if (xrefOffset > 0xffffffff) {\n throw new EmbeddedWriteError('This PDF is too large to take an edit.')\n }\n\n const trailerEntries = new Map<string, PdfObject>()\n const setSize = (size: number) =>\n trailerEntries.set('Size', { kind: 'number', value: size, text: String(size) })\n const size = Math.max(next, ...placed.map((p) => p.num + 1))\n setSize(size)\n trailerEntries.set('Root', root.ref)\n if (infoRef) trailerEntries.set('Info', infoRef)\n trailerEntries.set('Prev', {\n kind: 'number',\n value: file.startxref,\n text: String(file.startxref),\n })\n const id = file.sections.map((s) => s.trailer.entries.get('ID')).find(Boolean)\n if (id) trailerEntries.set('ID', id)\n\n if (file.sections[0]?.kind === 'stream') {\n // §7.5.8: a cross-reference stream, uncompressed, listing itself.\n const xrefNum = next\n if (xrefNum > MAX_OBJECT_NUMBER) throw new EmbeddedWriteError(DAMAGED)\n placed.push({ num: xrefNum, gen: 0, offset: xrefOffset })\n const runs = subsections(placed)\n const data = new Uint8Array(placed.length * 7)\n let at = 0\n for (const run of runs) {\n for (const entry of run.items) {\n data[at] = 1\n data[at + 1] = (entry.offset >>> 24) & 0xff\n data[at + 2] = (entry.offset >>> 16) & 0xff\n data[at + 3] = (entry.offset >>> 8) & 0xff\n data[at + 4] = entry.offset & 0xff\n data[at + 5] = (entry.gen >>> 8) & 0xff\n data[at + 6] = entry.gen & 0xff\n at += 7\n }\n }\n const int = (value: number): PdfObject => ({ kind: 'number', value, text: String(value) })\n const dict = new Map<string, PdfObject>([['Type', { kind: 'name', name: 'XRef' }]])\n setSize(Math.max(size, xrefNum + 1))\n for (const [key, value] of trailerEntries) dict.set(key, value)\n dict.set('W', { kind: 'array', items: [int(1), int(4), int(2)] })\n dict.set('Index', {\n kind: 'array',\n items: runs.flatMap((run) => [int(run.start), int(run.items.length)]),\n })\n dict.set('Length', int(data.length))\n chunks.push(\n latin1Bytes(\n `${xrefNum} 0 obj\\n${serializePdfObject({ kind: 'dict', entries: dict })}\\nstream\\n`,\n ),\n data,\n latin1Bytes(`\\nendstream\\nendobj\\nstartxref\\n${xrefOffset}\\n%%EOF\\n`),\n )\n } else {\n // §7.5.4: each entry exactly 20 bytes, `nnnnnnnnnn ggggg n` and a\n // two-byte end of line.\n let table = 'xref\\n'\n for (const run of subsections(placed)) {\n table += `${run.start} ${run.items.length}\\n`\n for (const entry of run.items) {\n table += `${String(entry.offset).padStart(10, '0')} ${String(entry.gen).padStart(5, '0')} n\\r\\n`\n }\n }\n table += `trailer\\n${serializePdfObject({ kind: 'dict', entries: trailerEntries })}\\n`\n table += `startxref\\n${xrefOffset}\\n%%EOF\\n`\n chunks.push(latin1Bytes(table))\n }\n const output = concat(chunks)\n\n // Read the result back the way the next reader will. Anything short of\n // a sound chain holding exactly what was written means the update is\n // not what it claims to be, and the original stays as it was.\n const check = attempt(() => openPdf(output), null)\n const verified =\n check !== null &&\n attempt(\n () =>\n check.root()?.ref.num === root.ref.num &&\n objects.every((o) => sameObject(check.getObject(o.ref.num), o.expect)) &&\n !check.repaired &&\n check.sections.length === file.sections.length + 1,\n false,\n )\n if (!verified) {\n throw new EmbeddedWriteError(\n 'The edited PDF did not read back as written, so the file was left as it was.',\n )\n }\n return output\n}\n"],"names":["decodePdfStream","decodePdfTextString","encodePdfTextString","indexOfBytes","lastIndexOfBytes","latin1Bytes","latin1Text","PDF_NULL","PdfLexer","pdfNameFromText","pdfNameText","PdfParser","serializePdfObject","EmbeddedWriteError","MAX_SECTIONS","MAX_XREF_ENTRIES","MAX_STRUCTURE_BYTES","MAX_XMP_BYTES","MAX_OBJSTM_OBJECTS","MAX_SCAN_OBJECTS","MAX_LOAD_NESTING","MAX_REF_CHAIN","MAX_FIELD_NODES","MAX_VALUE_TEXT","MAX_OBJECT_NUMBER","DATE_KEYS","Set","ascii","text","STARTXREF","OBJ","TRAILER","XREF_TYPE","OBJSTM_TYPE","CATALOG_TYPE","BYTE_RANGE","isDigit","b","isSpace","continuesWord","includes","String","fromCharCode","intValue","obj","kind","Number","isSafeInteger","value","isInt","token","type","test","asDict","dict","nameIs","name","attempt","read","fallback","findHeader","bytes","offset","head","subarray","match","exec","version","findStartxref","at","length","next","readField","data","width","i","headerBefore","j","skipSpace","stop","digits","max","end","k","gen","num","PdfFile","root","ref","trailer","entries","get","catalog","resolve","info","encrypted","trailers","some","has","getObject","cached","cache","undefined","loading","size","add","loadObject","delete","set","entry","parseAt","repaired","loadCompressed","stream","index","header","scan","latest","tryAt","parser","resolveLength","parsed","parseIndirectObject","headerOffset","shifted","objstm","objectStream","numbers","indexOf","offsets","first","parseObject","objectStreams","n","lexer","a","push","nextObjectNumber","Math","keys","readXref","start","startxref","visited","section","readSection","local","Map","stmOffset","stm","sections","prev","peekKeyword","readTable","readXrefStream","startToken","countToken","count","t","pos","direct","w","items","widths","slice","map","item","w0","w1","w2","ranges","r","scanned","headers","objectAround","lo","hi","found","mid","occurrences","pattern","keyword","rebuild","clear","h","compressed","forEach","sort","Infinity","def","candidates","candidate","checked","last","headerVersion","openPdf","file","PDF_DATE","pdfDateToIso","trimmed","trim","year","month","day","hour","minute","second","utc","sign","zh","zm","inRange","min","iso","ISO_DATE","isoToPdfDate","zone","date","readInfo","out","key","raw","editable","xmpText","TextDecoder","decode","readXmp","metadata","readPageCount","pages","readVersion","catalogVersion","hMajor","hMinor","split","later","readSigned","acroForm","flags","fields","stack","node","sig","seen","pop","field","ft","kids","kid","readPdf","xmp","pageCount","signed","DAMAGED","infoKey","existing","infoValue","hex","concat","chunks","chunk","Uint8Array","dictObject","expect","body","metadataObject","subsections","runs","run","sameObject","actual","expected","every","writePdf","update","patch","Object","objects","infoRef","current","TextEncoder","encode","nums","o","placed","object","xrefOffset","trailerEntries","setSize","p","id","s","find","Boolean","xrefNum","int","flatMap","table","padStart","output","check","verified"],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ import { type ImageBlockUpdate, type ImageBlocks } from './image-blocks';
18
+ /**
19
+ * Reads the metadata blocks of a PNG. Returns `null` when the signature is
20
+ * not PNG's; a damaged file yields what came before the damage.
21
+ */
22
+ export declare function readPngBlocks(bytes: Uint8Array): ImageBlocks | null;
23
+ /**
24
+ * Writes an update into a PNG and returns the new file.
25
+ *
26
+ * - `exif` replaces the `eXIf` chunk (moving it before IDAT if an old file
27
+ * had it after), or inserts one immediately before the first IDAT.
28
+ * - `xmp` replaces the XMP text chunk in place as an uncompressed `iTXt`,
29
+ * or inserts one before the first IDAT.
30
+ * - `pngText` sets or removes text chunks by keyword. A set replaces the
31
+ * first chunk with that keyword and removes the rest; a new keyword is
32
+ * inserted before the first IDAT.
33
+ * - Replacing or removing EXIF or XMP also removes the legacy raw-profile
34
+ * copy of it.
35
+ *
36
+ * Every chunk it does not rewrite, and every byte after IEND, is copied
37
+ * verbatim. Throws `EmbeddedWriteError` for a file that is not a PNG or that
38
+ * ends before IEND, for an IRB (PNG has no place for one), for a keyword the
39
+ * PNG spec does not allow, and for text containing NUL.
40
+ */
41
+ export declare function writePngBlocks(bytes: Uint8Array, update: ImageBlockUpdate): Uint8Array;