pdf-codec 1.3.0 → 1.4.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 (198) hide show
  1. package/README.md +38 -0
  2. package/dist/afm-widths-BoeTOK2r.cjs +826 -0
  3. package/dist/afm-widths-Dxucrg7D.js +779 -0
  4. package/dist/afm-widths-DyDq56Ph.d.cts +19 -0
  5. package/dist/afm-widths-DyDq56Ph.d.ts +19 -0
  6. package/dist/afm-widths.cjs +4 -0
  7. package/dist/afm-widths.d.cts +2 -0
  8. package/dist/afm-widths.d.ts +2 -0
  9. package/dist/afm-widths.js +2 -0
  10. package/dist/assets/stix-two-math-font.cjs +5 -0
  11. package/dist/assets/stix-two-math-font.d.cts +4 -0
  12. package/dist/assets/stix-two-math-font.d.ts +4 -0
  13. package/dist/assets/stix-two-math-font.js +4 -0
  14. package/dist/bytes/crc32.cjs +21 -0
  15. package/dist/bytes/crc32.d.cts +4 -0
  16. package/dist/bytes/crc32.d.ts +4 -0
  17. package/dist/bytes/crc32.js +20 -0
  18. package/dist/bytes/flate.cjs +53 -0
  19. package/dist/bytes/flate.d.cts +12 -0
  20. package/dist/bytes/flate.d.ts +12 -0
  21. package/dist/bytes/flate.js +49 -0
  22. package/dist/bytes/reader.cjs +60 -0
  23. package/dist/bytes/reader.d.cts +20 -0
  24. package/dist/bytes/reader.d.ts +20 -0
  25. package/dist/bytes/reader.js +58 -0
  26. package/dist/bytes/writer.cjs +37 -0
  27. package/dist/bytes/writer.d.cts +13 -0
  28. package/dist/bytes/writer.d.ts +13 -0
  29. package/dist/bytes/writer.js +35 -0
  30. package/dist/cmap.cjs +110 -0
  31. package/dist/cmap.d.cts +8 -0
  32. package/dist/cmap.d.ts +8 -0
  33. package/dist/cmap.js +109 -0
  34. package/dist/codec.cjs +34 -0
  35. package/dist/codec.d.cts +167 -0
  36. package/dist/codec.d.ts +167 -0
  37. package/dist/codec.js +32 -0
  38. package/dist/content-read.cjs +126 -0
  39. package/dist/content-read.d.cts +21 -0
  40. package/dist/content-read.d.ts +21 -0
  41. package/dist/content-read.js +125 -0
  42. package/dist/content-write.cjs +138 -0
  43. package/dist/content-write.d.cts +24 -0
  44. package/dist/content-write.d.ts +24 -0
  45. package/dist/content-write.js +137 -0
  46. package/dist/diagnostics.cjs +21 -0
  47. package/dist/diagnostics.d.cts +19 -0
  48. package/dist/diagnostics.d.ts +19 -0
  49. package/dist/diagnostics.js +18 -0
  50. package/dist/document.cjs +162 -0
  51. package/dist/document.d.cts +12 -0
  52. package/dist/document.d.ts +12 -0
  53. package/dist/document.js +161 -0
  54. package/dist/encoding.cjs +5 -0
  55. package/dist/encoding.d.cts +6 -0
  56. package/dist/encoding.d.ts +6 -0
  57. package/dist/encoding.js +2 -0
  58. package/dist/filters.cjs +223 -0
  59. package/dist/filters.d.cts +14 -0
  60. package/dist/filters.d.ts +14 -0
  61. package/dist/filters.js +218 -0
  62. package/dist/font-read.cjs +199 -0
  63. package/dist/font-read.d.cts +23 -0
  64. package/dist/font-read.d.ts +23 -0
  65. package/dist/font-read.js +198 -0
  66. package/dist/font-style.cjs +35 -0
  67. package/dist/font-style.d.cts +14 -0
  68. package/dist/font-style.d.ts +14 -0
  69. package/dist/font-style.js +34 -0
  70. package/dist/fonts.cjs +124 -0
  71. package/dist/fonts.d.cts +15 -0
  72. package/dist/fonts.d.ts +15 -0
  73. package/dist/fonts.js +122 -0
  74. package/dist/formula.cjs +0 -0
  75. package/dist/formula.d.cts +10 -0
  76. package/dist/formula.d.ts +10 -0
  77. package/dist/formula.js +0 -0
  78. package/dist/image/jpeg-info.cjs +71 -0
  79. package/dist/image/jpeg-info.d.cts +12 -0
  80. package/dist/image/jpeg-info.d.ts +12 -0
  81. package/dist/image/jpeg-info.js +70 -0
  82. package/dist/image/png-decode.cjs +181 -0
  83. package/dist/image/png-decode.d.cts +14 -0
  84. package/dist/image/png-decode.d.ts +14 -0
  85. package/dist/image/png-decode.js +180 -0
  86. package/dist/image/png-encode.cjs +64 -0
  87. package/dist/image/png-encode.d.cts +8 -0
  88. package/dist/image/png-encode.d.ts +8 -0
  89. package/dist/image/png-encode.js +63 -0
  90. package/dist/image/png-filter.cjs +95 -0
  91. package/dist/image/png-filter.d.cts +6 -0
  92. package/dist/image/png-filter.d.ts +6 -0
  93. package/dist/image/png-filter.js +93 -0
  94. package/dist/images-read.cjs +250 -0
  95. package/dist/images-read.d.cts +13 -0
  96. package/dist/images-read.d.ts +13 -0
  97. package/dist/images-read.js +249 -0
  98. package/dist/index.cjs +45 -5912
  99. package/dist/index.d.cts +21 -483
  100. package/dist/index.d.ts +21 -483
  101. package/dist/index.js +18 -5885
  102. package/dist/interpret.cjs +587 -0
  103. package/dist/interpret.d.cts +84 -0
  104. package/dist/interpret.d.ts +84 -0
  105. package/dist/interpret.js +586 -0
  106. package/dist/lexer.cjs +180 -0
  107. package/dist/lexer.d.cts +29 -0
  108. package/dist/lexer.d.ts +29 -0
  109. package/dist/lexer.js +179 -0
  110. package/dist/math-cmap.cjs +81 -0
  111. package/dist/math-cmap.d.cts +6 -0
  112. package/dist/math-cmap.d.ts +6 -0
  113. package/dist/math-cmap.js +80 -0
  114. package/dist/math-content-write.cjs +83 -0
  115. package/dist/math-content-write.d.cts +11 -0
  116. package/dist/math-content-write.d.ts +11 -0
  117. package/dist/math-content-write.js +81 -0
  118. package/dist/math-font-write.cjs +100 -0
  119. package/dist/math-font-write.d.cts +19 -0
  120. package/dist/math-font-write.d.ts +19 -0
  121. package/dist/math-font-write.js +99 -0
  122. package/dist/math-font.cjs +103 -0
  123. package/dist/math-font.d.cts +25 -0
  124. package/dist/math-font.d.ts +25 -0
  125. package/dist/math-font.js +102 -0
  126. package/dist/math-hmtx.cjs +17 -0
  127. package/dist/math-hmtx.d.cts +8 -0
  128. package/dist/math-hmtx.d.ts +8 -0
  129. package/dist/math-hmtx.js +16 -0
  130. package/dist/math-table.cjs +117 -0
  131. package/dist/math-table.d.cts +45 -0
  132. package/dist/math-table.d.ts +45 -0
  133. package/dist/math-table.js +116 -0
  134. package/dist/math-types-Ba8qAf1p.d.cts +82 -0
  135. package/dist/math-types-Ba8qAf1p.d.ts +82 -0
  136. package/dist/math-types.cjs +0 -0
  137. package/dist/math-types.d.cts +2 -0
  138. package/dist/math-types.d.ts +2 -0
  139. package/dist/math-types.js +0 -0
  140. package/dist/matrix-B3c2_a2f.d.cts +18 -0
  141. package/dist/matrix-B3c2_a2f.d.ts +18 -0
  142. package/dist/matrix.cjs +93 -0
  143. package/dist/matrix.d.cts +2 -0
  144. package/dist/matrix.d.ts +2 -0
  145. package/dist/matrix.js +83 -0
  146. package/dist/measure.cjs +54 -0
  147. package/dist/measure.d.cts +20 -0
  148. package/dist/measure.d.ts +20 -0
  149. package/dist/measure.js +53 -0
  150. package/dist/objects.cjs +100 -0
  151. package/dist/objects.d.cts +58 -0
  152. package/dist/objects.d.ts +58 -0
  153. package/dist/objects.js +84 -0
  154. package/dist/parse.cjs +230 -0
  155. package/dist/parse.d.cts +13 -0
  156. package/dist/parse.d.ts +13 -0
  157. package/dist/parse.js +228 -0
  158. package/dist/predictors.cjs +64 -0
  159. package/dist/predictors.d.cts +13 -0
  160. package/dist/predictors.d.ts +13 -0
  161. package/dist/predictors.js +62 -0
  162. package/dist/read.cjs +418 -0
  163. package/dist/read.d.cts +21 -0
  164. package/dist/read.d.ts +21 -0
  165. package/dist/read.js +413 -0
  166. package/dist/serialize.cjs +69 -0
  167. package/dist/serialize.d.cts +8 -0
  168. package/dist/serialize.d.ts +8 -0
  169. package/dist/serialize.js +66 -0
  170. package/dist/sfnt.cjs +52 -0
  171. package/dist/sfnt.d.cts +17 -0
  172. package/dist/sfnt.d.ts +17 -0
  173. package/dist/sfnt.js +46 -0
  174. package/dist/text-layout.cjs +224 -0
  175. package/dist/text-layout.d.cts +37 -0
  176. package/dist/text-layout.d.ts +37 -0
  177. package/dist/text-layout.js +222 -0
  178. package/dist/util/abort.cjs +7 -0
  179. package/dist/util/abort.d.cts +4 -0
  180. package/dist/util/abort.d.ts +4 -0
  181. package/dist/util/abort.js +6 -0
  182. package/dist/util/base64.cjs +48 -0
  183. package/dist/util/base64.d.cts +5 -0
  184. package/dist/util/base64.d.ts +5 -0
  185. package/dist/util/base64.js +46 -0
  186. package/dist/winansi.cjs +5 -0
  187. package/dist/winansi.d.cts +20 -0
  188. package/dist/winansi.d.ts +20 -0
  189. package/dist/winansi.js +2 -0
  190. package/dist/write.cjs +421 -0
  191. package/dist/write.d.cts +16 -0
  192. package/dist/write.d.ts +16 -0
  193. package/dist/write.js +419 -0
  194. package/dist/xref.cjs +325 -0
  195. package/dist/xref.d.cts +21 -0
  196. package/dist/xref.d.ts +21 -0
  197. package/dist/xref.js +324 -0
  198. package/package.json +9 -1
package/dist/codec.cjs ADDED
@@ -0,0 +1,34 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_write = require("./write.cjs");
3
+ const require_read = require("./read.cjs");
4
+ let zod = require("zod");
5
+ let document_schema_js = require("document-schema.js");
6
+ //#region src/codec.ts
7
+ const PDF_HEADER = [
8
+ 37,
9
+ 80,
10
+ 68,
11
+ 70,
12
+ 45
13
+ ];
14
+ const PDF_HEADER_SEARCH_WINDOW = 1024;
15
+ function containsBytesWithin(bytes, signature, window) {
16
+ const limit = Math.min(bytes.length - signature.length, window);
17
+ for (let start = 0; start <= limit; start++) {
18
+ let matched = true;
19
+ for (let i = 0; i < signature.length; i++) if (bytes[start + i] !== signature[i]) {
20
+ matched = false;
21
+ break;
22
+ }
23
+ if (matched) return true;
24
+ }
25
+ return false;
26
+ }
27
+ const PdfBytesSchema = zod.z.instanceof(Uint8Array).refine((bytes) => containsBytesWithin(bytes, PDF_HEADER, PDF_HEADER_SEARCH_WINDOW), { message: "not a valid PDF file: missing the %PDF- header" });
28
+ const pdfCodec = zod.z.codec(PdfBytesSchema, document_schema_js.LayoutDocumentSchema, {
29
+ decode: (bytes) => require_read.readPdf(bytes),
30
+ encode: (doc) => require_write.writePdf(doc)
31
+ });
32
+ //#endregion
33
+ exports.PdfBytesSchema = PdfBytesSchema;
34
+ exports.pdfCodec = pdfCodec;
@@ -0,0 +1,167 @@
1
+ import { z } from "zod";
2
+ //#region src/codec.d.ts
3
+ declare const PdfBytesSchema: z.ZodCustom<Uint8Array<ArrayBuffer>, Uint8Array<ArrayBuffer>>;
4
+ declare const pdfCodec: z.ZodCodec<z.ZodCustom<Uint8Array<ArrayBuffer>, Uint8Array<ArrayBuffer>>, z.ZodObject<{
5
+ formatVersion: z.ZodLiteral<1>;
6
+ metadata: z.ZodObject<{
7
+ title: z.ZodOptional<z.ZodString>;
8
+ author: z.ZodOptional<z.ZodString>;
9
+ subject: z.ZodOptional<z.ZodString>;
10
+ keywords: z.ZodOptional<z.ZodArray<z.ZodString>>;
11
+ creator: z.ZodOptional<z.ZodString>;
12
+ producer: z.ZodOptional<z.ZodString>;
13
+ createdIso: z.ZodOptional<z.ZodString>;
14
+ modifiedIso: z.ZodOptional<z.ZodString>;
15
+ }, z.core.$strip>;
16
+ pages: z.ZodArray<z.ZodObject<{
17
+ widthPt: z.ZodNumber;
18
+ heightPt: z.ZodNumber;
19
+ items: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
20
+ kind: z.ZodLiteral<"text">;
21
+ text: z.ZodString;
22
+ xPt: z.ZodNumber;
23
+ yPt: z.ZodNumber;
24
+ font: z.ZodObject<{
25
+ family: z.ZodString;
26
+ weight: z.ZodEnum<{
27
+ normal: "normal";
28
+ bold: "bold";
29
+ }>;
30
+ style: z.ZodEnum<{
31
+ normal: "normal";
32
+ italic: "italic";
33
+ }>;
34
+ }, z.core.$strip>;
35
+ sizePt: z.ZodNumber;
36
+ color: z.ZodObject<{
37
+ r: z.ZodNumber;
38
+ g: z.ZodNumber;
39
+ b: z.ZodNumber;
40
+ }, z.core.$strip>;
41
+ widthPt: z.ZodOptional<z.ZodNumber>;
42
+ rotationDeg: z.ZodOptional<z.ZodNumber>;
43
+ underline: z.ZodOptional<z.ZodBoolean>;
44
+ sourcePath: z.ZodOptional<z.ZodString>;
45
+ }, z.core.$strip>, z.ZodObject<{
46
+ kind: z.ZodLiteral<"image">;
47
+ imageId: z.ZodString;
48
+ xPt: z.ZodNumber;
49
+ yPt: z.ZodNumber;
50
+ widthPt: z.ZodNumber;
51
+ heightPt: z.ZodNumber;
52
+ rotationDeg: z.ZodOptional<z.ZodNumber>;
53
+ sourcePath: z.ZodOptional<z.ZodString>;
54
+ }, z.core.$strip>, z.ZodObject<{
55
+ kind: z.ZodLiteral<"rect">;
56
+ xPt: z.ZodNumber;
57
+ yPt: z.ZodNumber;
58
+ widthPt: z.ZodNumber;
59
+ heightPt: z.ZodNumber;
60
+ fill: z.ZodOptional<z.ZodObject<{
61
+ r: z.ZodNumber;
62
+ g: z.ZodNumber;
63
+ b: z.ZodNumber;
64
+ }, z.core.$strip>>;
65
+ stroke: z.ZodOptional<z.ZodObject<{
66
+ color: z.ZodObject<{
67
+ r: z.ZodNumber;
68
+ g: z.ZodNumber;
69
+ b: z.ZodNumber;
70
+ }, z.core.$strip>;
71
+ widthPt: z.ZodNumber;
72
+ }, z.core.$strip>>;
73
+ sourcePath: z.ZodOptional<z.ZodString>;
74
+ }, z.core.$strip>, z.ZodObject<{
75
+ kind: z.ZodLiteral<"line">;
76
+ x1Pt: z.ZodNumber;
77
+ y1Pt: z.ZodNumber;
78
+ x2Pt: z.ZodNumber;
79
+ y2Pt: z.ZodNumber;
80
+ color: z.ZodObject<{
81
+ r: z.ZodNumber;
82
+ g: z.ZodNumber;
83
+ b: z.ZodNumber;
84
+ }, z.core.$strip>;
85
+ widthPt: z.ZodNumber;
86
+ sourcePath: z.ZodOptional<z.ZodString>;
87
+ }, z.core.$strip>, z.ZodObject<{
88
+ kind: z.ZodLiteral<"ellipse">;
89
+ xPt: z.ZodNumber;
90
+ yPt: z.ZodNumber;
91
+ widthPt: z.ZodNumber;
92
+ heightPt: z.ZodNumber;
93
+ fill: z.ZodOptional<z.ZodObject<{
94
+ r: z.ZodNumber;
95
+ g: z.ZodNumber;
96
+ b: z.ZodNumber;
97
+ }, z.core.$strip>>;
98
+ stroke: z.ZodOptional<z.ZodObject<{
99
+ color: z.ZodObject<{
100
+ r: z.ZodNumber;
101
+ g: z.ZodNumber;
102
+ b: z.ZodNumber;
103
+ }, z.core.$strip>;
104
+ widthPt: z.ZodNumber;
105
+ }, z.core.$strip>>;
106
+ sourcePath: z.ZodOptional<z.ZodString>;
107
+ }, z.core.$strip>, z.ZodObject<{
108
+ kind: z.ZodLiteral<"path">;
109
+ subpaths: z.ZodArray<z.ZodObject<{
110
+ startXPt: z.ZodNumber;
111
+ startYPt: z.ZodNumber;
112
+ segments: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
113
+ kind: z.ZodLiteral<"line">;
114
+ xPt: z.ZodNumber;
115
+ yPt: z.ZodNumber;
116
+ }, z.core.$strip>, z.ZodObject<{
117
+ kind: z.ZodLiteral<"cubic">;
118
+ c1xPt: z.ZodNumber;
119
+ c1yPt: z.ZodNumber;
120
+ c2xPt: z.ZodNumber;
121
+ c2yPt: z.ZodNumber;
122
+ xPt: z.ZodNumber;
123
+ yPt: z.ZodNumber;
124
+ }, z.core.$strip>], "kind">>;
125
+ closed: z.ZodBoolean;
126
+ }, z.core.$strip>>;
127
+ fill: z.ZodOptional<z.ZodObject<{
128
+ r: z.ZodNumber;
129
+ g: z.ZodNumber;
130
+ b: z.ZodNumber;
131
+ }, z.core.$strip>>;
132
+ fillRule: z.ZodOptional<z.ZodEnum<{
133
+ nonzero: "nonzero";
134
+ evenodd: "evenodd";
135
+ }>>;
136
+ stroke: z.ZodOptional<z.ZodObject<{
137
+ color: z.ZodObject<{
138
+ r: z.ZodNumber;
139
+ g: z.ZodNumber;
140
+ b: z.ZodNumber;
141
+ }, z.core.$strip>;
142
+ widthPt: z.ZodNumber;
143
+ }, z.core.$strip>>;
144
+ sourcePath: z.ZodOptional<z.ZodString>;
145
+ }, z.core.$strip>, z.ZodObject<{
146
+ kind: z.ZodLiteral<"link">;
147
+ uri: z.ZodString;
148
+ xPt: z.ZodNumber;
149
+ yPt: z.ZodNumber;
150
+ widthPt: z.ZodNumber;
151
+ heightPt: z.ZodNumber;
152
+ sourcePath: z.ZodOptional<z.ZodString>;
153
+ }, z.core.$strip>], "kind">>;
154
+ notes: z.ZodOptional<z.ZodString>;
155
+ }, z.core.$strip>>;
156
+ images: z.ZodRecord<z.ZodString, z.ZodObject<{
157
+ format: z.ZodEnum<{
158
+ png: "png";
159
+ jpeg: "jpeg";
160
+ }>;
161
+ base64: z.ZodString;
162
+ widthPx: z.ZodNumber;
163
+ heightPx: z.ZodNumber;
164
+ }, z.core.$strip>>;
165
+ }, z.core.$strip>>;
166
+ //#endregion
167
+ export { PdfBytesSchema, pdfCodec };
@@ -0,0 +1,167 @@
1
+ import { z } from "zod";
2
+ //#region src/codec.d.ts
3
+ declare const PdfBytesSchema: z.ZodCustom<Uint8Array<ArrayBuffer>, Uint8Array<ArrayBuffer>>;
4
+ declare const pdfCodec: z.ZodCodec<z.ZodCustom<Uint8Array<ArrayBuffer>, Uint8Array<ArrayBuffer>>, z.ZodObject<{
5
+ formatVersion: z.ZodLiteral<1>;
6
+ metadata: z.ZodObject<{
7
+ title: z.ZodOptional<z.ZodString>;
8
+ author: z.ZodOptional<z.ZodString>;
9
+ subject: z.ZodOptional<z.ZodString>;
10
+ keywords: z.ZodOptional<z.ZodArray<z.ZodString>>;
11
+ creator: z.ZodOptional<z.ZodString>;
12
+ producer: z.ZodOptional<z.ZodString>;
13
+ createdIso: z.ZodOptional<z.ZodString>;
14
+ modifiedIso: z.ZodOptional<z.ZodString>;
15
+ }, z.core.$strip>;
16
+ pages: z.ZodArray<z.ZodObject<{
17
+ widthPt: z.ZodNumber;
18
+ heightPt: z.ZodNumber;
19
+ items: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
20
+ kind: z.ZodLiteral<"text">;
21
+ text: z.ZodString;
22
+ xPt: z.ZodNumber;
23
+ yPt: z.ZodNumber;
24
+ font: z.ZodObject<{
25
+ family: z.ZodString;
26
+ weight: z.ZodEnum<{
27
+ normal: "normal";
28
+ bold: "bold";
29
+ }>;
30
+ style: z.ZodEnum<{
31
+ normal: "normal";
32
+ italic: "italic";
33
+ }>;
34
+ }, z.core.$strip>;
35
+ sizePt: z.ZodNumber;
36
+ color: z.ZodObject<{
37
+ r: z.ZodNumber;
38
+ g: z.ZodNumber;
39
+ b: z.ZodNumber;
40
+ }, z.core.$strip>;
41
+ widthPt: z.ZodOptional<z.ZodNumber>;
42
+ rotationDeg: z.ZodOptional<z.ZodNumber>;
43
+ underline: z.ZodOptional<z.ZodBoolean>;
44
+ sourcePath: z.ZodOptional<z.ZodString>;
45
+ }, z.core.$strip>, z.ZodObject<{
46
+ kind: z.ZodLiteral<"image">;
47
+ imageId: z.ZodString;
48
+ xPt: z.ZodNumber;
49
+ yPt: z.ZodNumber;
50
+ widthPt: z.ZodNumber;
51
+ heightPt: z.ZodNumber;
52
+ rotationDeg: z.ZodOptional<z.ZodNumber>;
53
+ sourcePath: z.ZodOptional<z.ZodString>;
54
+ }, z.core.$strip>, z.ZodObject<{
55
+ kind: z.ZodLiteral<"rect">;
56
+ xPt: z.ZodNumber;
57
+ yPt: z.ZodNumber;
58
+ widthPt: z.ZodNumber;
59
+ heightPt: z.ZodNumber;
60
+ fill: z.ZodOptional<z.ZodObject<{
61
+ r: z.ZodNumber;
62
+ g: z.ZodNumber;
63
+ b: z.ZodNumber;
64
+ }, z.core.$strip>>;
65
+ stroke: z.ZodOptional<z.ZodObject<{
66
+ color: z.ZodObject<{
67
+ r: z.ZodNumber;
68
+ g: z.ZodNumber;
69
+ b: z.ZodNumber;
70
+ }, z.core.$strip>;
71
+ widthPt: z.ZodNumber;
72
+ }, z.core.$strip>>;
73
+ sourcePath: z.ZodOptional<z.ZodString>;
74
+ }, z.core.$strip>, z.ZodObject<{
75
+ kind: z.ZodLiteral<"line">;
76
+ x1Pt: z.ZodNumber;
77
+ y1Pt: z.ZodNumber;
78
+ x2Pt: z.ZodNumber;
79
+ y2Pt: z.ZodNumber;
80
+ color: z.ZodObject<{
81
+ r: z.ZodNumber;
82
+ g: z.ZodNumber;
83
+ b: z.ZodNumber;
84
+ }, z.core.$strip>;
85
+ widthPt: z.ZodNumber;
86
+ sourcePath: z.ZodOptional<z.ZodString>;
87
+ }, z.core.$strip>, z.ZodObject<{
88
+ kind: z.ZodLiteral<"ellipse">;
89
+ xPt: z.ZodNumber;
90
+ yPt: z.ZodNumber;
91
+ widthPt: z.ZodNumber;
92
+ heightPt: z.ZodNumber;
93
+ fill: z.ZodOptional<z.ZodObject<{
94
+ r: z.ZodNumber;
95
+ g: z.ZodNumber;
96
+ b: z.ZodNumber;
97
+ }, z.core.$strip>>;
98
+ stroke: z.ZodOptional<z.ZodObject<{
99
+ color: z.ZodObject<{
100
+ r: z.ZodNumber;
101
+ g: z.ZodNumber;
102
+ b: z.ZodNumber;
103
+ }, z.core.$strip>;
104
+ widthPt: z.ZodNumber;
105
+ }, z.core.$strip>>;
106
+ sourcePath: z.ZodOptional<z.ZodString>;
107
+ }, z.core.$strip>, z.ZodObject<{
108
+ kind: z.ZodLiteral<"path">;
109
+ subpaths: z.ZodArray<z.ZodObject<{
110
+ startXPt: z.ZodNumber;
111
+ startYPt: z.ZodNumber;
112
+ segments: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
113
+ kind: z.ZodLiteral<"line">;
114
+ xPt: z.ZodNumber;
115
+ yPt: z.ZodNumber;
116
+ }, z.core.$strip>, z.ZodObject<{
117
+ kind: z.ZodLiteral<"cubic">;
118
+ c1xPt: z.ZodNumber;
119
+ c1yPt: z.ZodNumber;
120
+ c2xPt: z.ZodNumber;
121
+ c2yPt: z.ZodNumber;
122
+ xPt: z.ZodNumber;
123
+ yPt: z.ZodNumber;
124
+ }, z.core.$strip>], "kind">>;
125
+ closed: z.ZodBoolean;
126
+ }, z.core.$strip>>;
127
+ fill: z.ZodOptional<z.ZodObject<{
128
+ r: z.ZodNumber;
129
+ g: z.ZodNumber;
130
+ b: z.ZodNumber;
131
+ }, z.core.$strip>>;
132
+ fillRule: z.ZodOptional<z.ZodEnum<{
133
+ nonzero: "nonzero";
134
+ evenodd: "evenodd";
135
+ }>>;
136
+ stroke: z.ZodOptional<z.ZodObject<{
137
+ color: z.ZodObject<{
138
+ r: z.ZodNumber;
139
+ g: z.ZodNumber;
140
+ b: z.ZodNumber;
141
+ }, z.core.$strip>;
142
+ widthPt: z.ZodNumber;
143
+ }, z.core.$strip>>;
144
+ sourcePath: z.ZodOptional<z.ZodString>;
145
+ }, z.core.$strip>, z.ZodObject<{
146
+ kind: z.ZodLiteral<"link">;
147
+ uri: z.ZodString;
148
+ xPt: z.ZodNumber;
149
+ yPt: z.ZodNumber;
150
+ widthPt: z.ZodNumber;
151
+ heightPt: z.ZodNumber;
152
+ sourcePath: z.ZodOptional<z.ZodString>;
153
+ }, z.core.$strip>], "kind">>;
154
+ notes: z.ZodOptional<z.ZodString>;
155
+ }, z.core.$strip>>;
156
+ images: z.ZodRecord<z.ZodString, z.ZodObject<{
157
+ format: z.ZodEnum<{
158
+ png: "png";
159
+ jpeg: "jpeg";
160
+ }>;
161
+ base64: z.ZodString;
162
+ widthPx: z.ZodNumber;
163
+ heightPx: z.ZodNumber;
164
+ }, z.core.$strip>>;
165
+ }, z.core.$strip>>;
166
+ //#endregion
167
+ export { PdfBytesSchema, pdfCodec };
package/dist/codec.js ADDED
@@ -0,0 +1,32 @@
1
+ import { writePdf } from "./write.js";
2
+ import { readPdf } from "./read.js";
3
+ import { z } from "zod";
4
+ import { LayoutDocumentSchema } from "document-schema.js";
5
+ //#region src/codec.ts
6
+ const PDF_HEADER = [
7
+ 37,
8
+ 80,
9
+ 68,
10
+ 70,
11
+ 45
12
+ ];
13
+ const PDF_HEADER_SEARCH_WINDOW = 1024;
14
+ function containsBytesWithin(bytes, signature, window) {
15
+ const limit = Math.min(bytes.length - signature.length, window);
16
+ for (let start = 0; start <= limit; start++) {
17
+ let matched = true;
18
+ for (let i = 0; i < signature.length; i++) if (bytes[start + i] !== signature[i]) {
19
+ matched = false;
20
+ break;
21
+ }
22
+ if (matched) return true;
23
+ }
24
+ return false;
25
+ }
26
+ const PdfBytesSchema = z.instanceof(Uint8Array).refine((bytes) => containsBytesWithin(bytes, PDF_HEADER, PDF_HEADER_SEARCH_WINDOW), { message: "not a valid PDF file: missing the %PDF- header" });
27
+ const pdfCodec = z.codec(PdfBytesSchema, LayoutDocumentSchema, {
28
+ decode: (bytes) => readPdf(bytes),
29
+ encode: (doc) => writePdf(doc)
30
+ });
31
+ //#endregion
32
+ export { PdfBytesSchema, pdfCodec };
@@ -0,0 +1,126 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_bytes_reader = require("./bytes/reader.cjs");
3
+ const require_lexer = require("./lexer.cjs");
4
+ const require_objects = require("./objects.cjs");
5
+ const require_parse = require("./parse.cjs");
6
+ //#region src/content-read.ts
7
+ function readContentStream(bytes, sink) {
8
+ const reader = new require_bytes_reader.ByteReader(bytes);
9
+ const tokens = [];
10
+ let operands = [];
11
+ for (;;) {
12
+ const mark = reader.mark();
13
+ const peeked = require_lexer.nextToken(reader);
14
+ if (peeked === void 0) break;
15
+ if (peeked.kind === "keyword" && peeked.value === "BI") {
16
+ const image = readInlineImage(reader, sink);
17
+ if (image !== void 0) tokens.push({
18
+ kind: "inlineImage",
19
+ image
20
+ });
21
+ operands = [];
22
+ continue;
23
+ }
24
+ if (peeked.kind === "keyword" && peeked.value !== "true" && peeked.value !== "false" && peeked.value !== "null") {
25
+ tokens.push({
26
+ kind: "operation",
27
+ operation: {
28
+ operands,
29
+ operator: peeked.value
30
+ }
31
+ });
32
+ operands = [];
33
+ continue;
34
+ }
35
+ reader.reset(mark);
36
+ const value = require_parse.parseValue(reader, sink);
37
+ if (value === void 0) break;
38
+ operands.push(value);
39
+ }
40
+ return tokens;
41
+ }
42
+ const EI_BYTES = new TextEncoder().encode("EI");
43
+ function looksLikeEiAt(reader, offset) {
44
+ if (offset < 0 || offset > reader.length) return false;
45
+ const mark = reader.mark();
46
+ reader.seek(offset);
47
+ reader.skipWhitespace();
48
+ const matches = reader.matchKeyword("EI");
49
+ reader.reset(mark);
50
+ return matches;
51
+ }
52
+ function findEiBoundary(reader, fromOffset) {
53
+ const haystack = reader.slice(fromOffset, reader.length);
54
+ outer: for (let i = 0; i <= haystack.length - EI_BYTES.length; i++) {
55
+ if (i > 0 && !require_bytes_reader.isAsciiWhitespace(haystack[i - 1])) continue;
56
+ for (let j = 0; j < EI_BYTES.length; j++) if (haystack[i + j] !== EI_BYTES[j]) continue outer;
57
+ const after = haystack[i + EI_BYTES.length];
58
+ if (after !== void 0 && !require_bytes_reader.isAsciiWhitespace(after)) continue;
59
+ return fromOffset + i;
60
+ }
61
+ }
62
+ function readInlineImage(reader, sink) {
63
+ const entries = /* @__PURE__ */ new Map();
64
+ for (;;) {
65
+ const token = require_lexer.nextToken(reader);
66
+ if (token === void 0) {
67
+ sink({
68
+ code: "pdf/inline-image-truncated",
69
+ severity: "warning",
70
+ message: "inline image dictionary was truncated before \"ID\""
71
+ });
72
+ return;
73
+ }
74
+ if (token.kind === "keyword" && token.value === "ID") break;
75
+ if (token.kind !== "name") {
76
+ sink({
77
+ code: "pdf/dict-key-not-name",
78
+ severity: "warning",
79
+ message: "inline image dictionary key was not a /Name"
80
+ });
81
+ continue;
82
+ }
83
+ const value = require_parse.parseValue(reader, sink);
84
+ if (value === void 0) {
85
+ sink({
86
+ code: "pdf/inline-image-truncated",
87
+ severity: "warning",
88
+ message: "inline image dictionary was truncated before \"ID\""
89
+ });
90
+ return;
91
+ }
92
+ entries.set(token.value, value);
93
+ }
94
+ reader.next();
95
+ const dataStart = reader.offset;
96
+ const dict = require_objects.pdfDict(entries);
97
+ const explicitLength = require_objects.asNumber(require_objects.dictGet(dict, "L") ?? require_objects.dictGet(dict, "Length"));
98
+ let dataEnd;
99
+ if (explicitLength !== void 0 && looksLikeEiAt(reader, dataStart + explicitLength)) dataEnd = dataStart + explicitLength;
100
+ else {
101
+ const found = findEiBoundary(reader, dataStart);
102
+ if (found === void 0) {
103
+ sink({
104
+ code: "pdf/inline-image-truncated",
105
+ severity: "warning",
106
+ message: "no \"EI\" boundary found for an inline image; treating the remainder of the content stream as its data"
107
+ });
108
+ dataEnd = reader.length;
109
+ } else dataEnd = found > dataStart && require_bytes_reader.isAsciiWhitespace(reader.slice(found - 1, found)[0]) ? found - 1 : found;
110
+ }
111
+ const data = reader.slice(dataStart, dataEnd);
112
+ reader.seek(dataEnd);
113
+ reader.skipWhitespace();
114
+ const eiTok = require_lexer.nextToken(reader);
115
+ if (eiTok?.kind !== "keyword" || eiTok.value !== "EI") sink({
116
+ code: "pdf/inline-image-truncated",
117
+ severity: "warning",
118
+ message: "inline image data was not followed by \"EI\""
119
+ });
120
+ return {
121
+ dict,
122
+ data
123
+ };
124
+ }
125
+ //#endregion
126
+ exports.readContentStream = readContentStream;
@@ -0,0 +1,21 @@
1
+ import { PdfDiagnosticSink } from "./diagnostics.cjs";
2
+ import { PdfDict, PdfObject } from "./objects.cjs";
3
+ //#region src/content-read.d.ts
4
+ interface ContentOperation {
5
+ readonly operands: readonly PdfObject[];
6
+ readonly operator: string;
7
+ }
8
+ interface InlineImage {
9
+ readonly dict: PdfDict;
10
+ readonly data: Uint8Array<ArrayBuffer>;
11
+ }
12
+ type ContentToken = {
13
+ readonly kind: 'operation';
14
+ readonly operation: ContentOperation;
15
+ } | {
16
+ readonly kind: 'inlineImage';
17
+ readonly image: InlineImage;
18
+ };
19
+ declare function readContentStream(bytes: Uint8Array<ArrayBuffer>, sink: PdfDiagnosticSink): ContentToken[];
20
+ //#endregion
21
+ export { ContentOperation, ContentToken, InlineImage, readContentStream };
@@ -0,0 +1,21 @@
1
+ import { PdfDiagnosticSink } from "./diagnostics.js";
2
+ import { PdfDict, PdfObject } from "./objects.js";
3
+ //#region src/content-read.d.ts
4
+ interface ContentOperation {
5
+ readonly operands: readonly PdfObject[];
6
+ readonly operator: string;
7
+ }
8
+ interface InlineImage {
9
+ readonly dict: PdfDict;
10
+ readonly data: Uint8Array<ArrayBuffer>;
11
+ }
12
+ type ContentToken = {
13
+ readonly kind: 'operation';
14
+ readonly operation: ContentOperation;
15
+ } | {
16
+ readonly kind: 'inlineImage';
17
+ readonly image: InlineImage;
18
+ };
19
+ declare function readContentStream(bytes: Uint8Array<ArrayBuffer>, sink: PdfDiagnosticSink): ContentToken[];
20
+ //#endregion
21
+ export { ContentOperation, ContentToken, InlineImage, readContentStream };
@@ -0,0 +1,125 @@
1
+ import { ByteReader, isAsciiWhitespace } from "./bytes/reader.js";
2
+ import { nextToken } from "./lexer.js";
3
+ import { asNumber, dictGet, pdfDict } from "./objects.js";
4
+ import { parseValue } from "./parse.js";
5
+ //#region src/content-read.ts
6
+ function readContentStream(bytes, sink) {
7
+ const reader = new ByteReader(bytes);
8
+ const tokens = [];
9
+ let operands = [];
10
+ for (;;) {
11
+ const mark = reader.mark();
12
+ const peeked = nextToken(reader);
13
+ if (peeked === void 0) break;
14
+ if (peeked.kind === "keyword" && peeked.value === "BI") {
15
+ const image = readInlineImage(reader, sink);
16
+ if (image !== void 0) tokens.push({
17
+ kind: "inlineImage",
18
+ image
19
+ });
20
+ operands = [];
21
+ continue;
22
+ }
23
+ if (peeked.kind === "keyword" && peeked.value !== "true" && peeked.value !== "false" && peeked.value !== "null") {
24
+ tokens.push({
25
+ kind: "operation",
26
+ operation: {
27
+ operands,
28
+ operator: peeked.value
29
+ }
30
+ });
31
+ operands = [];
32
+ continue;
33
+ }
34
+ reader.reset(mark);
35
+ const value = parseValue(reader, sink);
36
+ if (value === void 0) break;
37
+ operands.push(value);
38
+ }
39
+ return tokens;
40
+ }
41
+ const EI_BYTES = new TextEncoder().encode("EI");
42
+ function looksLikeEiAt(reader, offset) {
43
+ if (offset < 0 || offset > reader.length) return false;
44
+ const mark = reader.mark();
45
+ reader.seek(offset);
46
+ reader.skipWhitespace();
47
+ const matches = reader.matchKeyword("EI");
48
+ reader.reset(mark);
49
+ return matches;
50
+ }
51
+ function findEiBoundary(reader, fromOffset) {
52
+ const haystack = reader.slice(fromOffset, reader.length);
53
+ outer: for (let i = 0; i <= haystack.length - EI_BYTES.length; i++) {
54
+ if (i > 0 && !isAsciiWhitespace(haystack[i - 1])) continue;
55
+ for (let j = 0; j < EI_BYTES.length; j++) if (haystack[i + j] !== EI_BYTES[j]) continue outer;
56
+ const after = haystack[i + EI_BYTES.length];
57
+ if (after !== void 0 && !isAsciiWhitespace(after)) continue;
58
+ return fromOffset + i;
59
+ }
60
+ }
61
+ function readInlineImage(reader, sink) {
62
+ const entries = /* @__PURE__ */ new Map();
63
+ for (;;) {
64
+ const token = nextToken(reader);
65
+ if (token === void 0) {
66
+ sink({
67
+ code: "pdf/inline-image-truncated",
68
+ severity: "warning",
69
+ message: "inline image dictionary was truncated before \"ID\""
70
+ });
71
+ return;
72
+ }
73
+ if (token.kind === "keyword" && token.value === "ID") break;
74
+ if (token.kind !== "name") {
75
+ sink({
76
+ code: "pdf/dict-key-not-name",
77
+ severity: "warning",
78
+ message: "inline image dictionary key was not a /Name"
79
+ });
80
+ continue;
81
+ }
82
+ const value = parseValue(reader, sink);
83
+ if (value === void 0) {
84
+ sink({
85
+ code: "pdf/inline-image-truncated",
86
+ severity: "warning",
87
+ message: "inline image dictionary was truncated before \"ID\""
88
+ });
89
+ return;
90
+ }
91
+ entries.set(token.value, value);
92
+ }
93
+ reader.next();
94
+ const dataStart = reader.offset;
95
+ const dict = pdfDict(entries);
96
+ const explicitLength = asNumber(dictGet(dict, "L") ?? dictGet(dict, "Length"));
97
+ let dataEnd;
98
+ if (explicitLength !== void 0 && looksLikeEiAt(reader, dataStart + explicitLength)) dataEnd = dataStart + explicitLength;
99
+ else {
100
+ const found = findEiBoundary(reader, dataStart);
101
+ if (found === void 0) {
102
+ sink({
103
+ code: "pdf/inline-image-truncated",
104
+ severity: "warning",
105
+ message: "no \"EI\" boundary found for an inline image; treating the remainder of the content stream as its data"
106
+ });
107
+ dataEnd = reader.length;
108
+ } else dataEnd = found > dataStart && isAsciiWhitespace(reader.slice(found - 1, found)[0]) ? found - 1 : found;
109
+ }
110
+ const data = reader.slice(dataStart, dataEnd);
111
+ reader.seek(dataEnd);
112
+ reader.skipWhitespace();
113
+ const eiTok = nextToken(reader);
114
+ if (eiTok?.kind !== "keyword" || eiTok.value !== "EI") sink({
115
+ code: "pdf/inline-image-truncated",
116
+ severity: "warning",
117
+ message: "inline image data was not followed by \"EI\""
118
+ });
119
+ return {
120
+ dict,
121
+ data
122
+ };
123
+ }
124
+ //#endregion
125
+ export { readContentStream };