pdf-lite 1.4.0 → 1.6.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.
- package/EXAMPLES.md +51 -70
- package/README.md +1 -1
- package/dist/acroform/appearance/index.d.ts +4 -4
- package/dist/acroform/appearance/index.js +4 -4
- package/dist/acroform/appearance/{PdfAppearanceStream.d.ts → pdf-appearance-stream.d.ts} +9 -3
- package/dist/acroform/appearance/{PdfAppearanceStream.js → pdf-appearance-stream.js} +14 -5
- package/dist/acroform/appearance/{PdfButtonAppearanceStream.d.ts → pdf-button-appearance-stream.d.ts} +3 -2
- package/dist/acroform/appearance/pdf-button-appearance-stream.js +58 -0
- package/dist/acroform/appearance/pdf-choice-appearance-stream.d.ts +22 -0
- package/dist/acroform/appearance/pdf-choice-appearance-stream.js +75 -0
- package/dist/acroform/appearance/pdf-graphics.d.ts +51 -0
- package/dist/acroform/appearance/pdf-graphics.js +239 -0
- package/dist/acroform/appearance/{PdfTextAppearanceStream.d.ts → pdf-text-appearance-stream.d.ts} +7 -2
- package/dist/acroform/appearance/pdf-text-appearance-stream.js +104 -0
- package/dist/acroform/fields/index.d.ts +7 -7
- package/dist/acroform/fields/index.js +7 -7
- package/dist/acroform/fields/pdf-button-form-field.d.ts +14 -0
- package/dist/acroform/fields/pdf-button-form-field.js +70 -0
- package/dist/acroform/fields/pdf-choice-form-field.d.ts +19 -0
- package/dist/acroform/fields/pdf-choice-form-field.js +112 -0
- package/dist/acroform/fields/{PdfFormFieldFlags.d.ts → pdf-form-field-flags.d.ts} +5 -6
- package/dist/acroform/fields/{PdfFormFieldFlags.js → pdf-form-field-flags.js} +12 -18
- package/dist/acroform/fields/{PdfFormField.d.ts → pdf-form-field.d.ts} +37 -38
- package/dist/acroform/fields/pdf-form-field.js +519 -0
- package/dist/acroform/fields/{PdfSignatureFormField.d.ts → pdf-signature-form-field.d.ts} +1 -1
- package/dist/acroform/fields/{PdfSignatureFormField.js → pdf-signature-form-field.js} +1 -1
- package/dist/acroform/fields/{PdfTextFormField.d.ts → pdf-text-form-field.d.ts} +1 -1
- package/dist/acroform/fields/{PdfTextFormField.js → pdf-text-form-field.js} +11 -13
- package/dist/acroform/fields/types.d.ts +6 -1
- package/dist/acroform/index.d.ts +1 -3
- package/dist/acroform/index.js +1 -3
- package/dist/acroform/pdf-acro-form.d.ts +45 -0
- package/dist/acroform/pdf-acro-form.js +203 -0
- package/dist/acroform/xfa/index.d.ts +3 -3
- package/dist/acroform/xfa/index.js +2 -2
- package/dist/acroform/xfa/{PdfXfaData.d.ts → pdf-xfa-data.d.ts} +4 -3
- package/dist/acroform/xfa/{PdfXfaData.js → pdf-xfa-data.js} +16 -12
- package/dist/acroform/xfa/pdf-xfa-form.d.ts +16 -0
- package/dist/acroform/xfa/pdf-xfa-form.js +34 -0
- package/dist/annotations/index.d.ts +3 -4
- package/dist/annotations/index.js +3 -4
- package/dist/annotations/{PdfAnnotationFlags.d.ts → pdf-annotation-flags.d.ts} +3 -4
- package/dist/annotations/{PdfAnnotationFlags.js → pdf-annotation-flags.js} +5 -6
- package/dist/annotations/{PdfAnnotation.d.ts → pdf-annotation.d.ts} +31 -5
- package/dist/annotations/{PdfAnnotation.js → pdf-annotation.js} +31 -19
- package/dist/annotations/pdf-default-resources.d.ts +11 -0
- package/dist/annotations/pdf-default-resources.js +3 -0
- package/dist/annotations/{PdfWidgetAnnotation.d.ts → pdf-widget-annotation.d.ts} +1 -1
- package/dist/annotations/{PdfWidgetAnnotation.js → pdf-widget-annotation.js} +1 -1
- package/dist/core/decoder.js +1 -1
- package/dist/core/objects/pdf-array.d.ts +8 -1
- package/dist/core/objects/pdf-array.js +31 -0
- package/dist/core/objects/pdf-dictionary.d.ts +2 -0
- package/dist/core/objects/pdf-dictionary.js +14 -7
- package/dist/core/objects/pdf-hexadecimal.d.ts +1 -0
- package/dist/core/objects/pdf-hexadecimal.js +3 -3
- package/dist/core/objects/pdf-indirect-object.d.ts +18 -9
- package/dist/core/objects/pdf-indirect-object.js +75 -16
- package/dist/core/objects/pdf-number.d.ts +1 -0
- package/dist/core/objects/pdf-number.js +5 -4
- package/dist/core/objects/pdf-object-reference.d.ts +8 -1
- package/dist/core/objects/pdf-object-reference.js +14 -0
- package/dist/core/objects/pdf-object.d.ts +14 -0
- package/dist/core/objects/pdf-object.js +36 -0
- package/dist/core/objects/pdf-start-xref.d.ts +1 -0
- package/dist/core/objects/pdf-start-xref.js +4 -0
- package/dist/core/objects/pdf-stream.d.ts +44 -7
- package/dist/core/objects/pdf-stream.js +284 -26
- package/dist/core/objects/pdf-string.d.ts +1 -0
- package/dist/core/objects/pdf-string.js +3 -6
- package/dist/core/objects/pdf-trailer.d.ts +1 -0
- package/dist/core/objects/pdf-trailer.js +6 -3
- package/dist/core/objects/pdf-xref-table.js +1 -1
- package/dist/core/parser/incremental-parser.d.ts +0 -13
- package/dist/core/parser/incremental-parser.js +1 -18
- package/dist/core/ref.d.ts +3 -1
- package/dist/core/ref.js +8 -5
- package/dist/core/streams/object-stream.d.ts +1 -1
- package/dist/core/streams/object-stream.js +1 -1
- package/dist/core/tokens/token.d.ts +2 -1
- package/dist/core/tokens/token.js +3 -0
- package/dist/errors.d.ts +22 -0
- package/dist/errors.js +24 -0
- package/dist/fonts/index.d.ts +0 -1
- package/dist/fonts/index.js +0 -1
- package/dist/fonts/pdf-font.d.ts +94 -32
- package/dist/fonts/pdf-font.js +301 -83
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/pdf/index.d.ts +2 -1
- package/dist/pdf/index.js +2 -1
- package/dist/pdf/pdf-document.d.ts +61 -36
- package/dist/pdf/pdf-document.js +315 -117
- package/dist/pdf/pdf-page.d.ts +50 -0
- package/dist/pdf/pdf-page.js +144 -0
- package/dist/pdf/pdf-pages.d.ts +28 -0
- package/dist/pdf/pdf-pages.js +94 -0
- package/dist/pdf/pdf-reader.d.ts +5 -1
- package/dist/pdf/pdf-reader.js +36 -2
- package/dist/pdf/pdf-revision.d.ts +3 -3
- package/dist/pdf/pdf-revision.js +7 -7
- package/dist/pdf/pdf-xref-lookup.js +34 -14
- package/dist/signing/document-security-store.d.ts +14 -17
- package/dist/signing/document-security-store.js +19 -34
- package/dist/signing/signer.d.ts +23 -8
- package/dist/signing/signer.js +51 -17
- package/dist/utils/encodePdfText.d.ts +17 -0
- package/dist/utils/encodePdfText.js +61 -0
- package/dist/utils/index.d.ts +1 -2
- package/dist/utils/index.js +1 -2
- package/dist/utils/needsCentralWhitespace.d.ts +10 -0
- package/dist/utils/needsCentralWhitespace.js +34 -0
- package/package.json +3 -3
- package/dist/acroform/PdfAcroForm.d.ts +0 -63
- package/dist/acroform/PdfAcroForm.js +0 -279
- package/dist/acroform/PdfFontEncodingCache.d.ts +0 -16
- package/dist/acroform/PdfFontEncodingCache.js +0 -75
- package/dist/acroform/acroform.d.ts +0 -9
- package/dist/acroform/acroform.js +0 -7
- package/dist/acroform/appearance/PdfButtonAppearanceStream.js +0 -54
- package/dist/acroform/appearance/PdfChoiceAppearanceStream.d.ts +0 -15
- package/dist/acroform/appearance/PdfChoiceAppearanceStream.js +0 -48
- package/dist/acroform/appearance/PdfTextAppearanceStream.js +0 -75
- package/dist/acroform/fields/PdfButtonFormField.d.ts +0 -9
- package/dist/acroform/fields/PdfButtonFormField.js +0 -35
- package/dist/acroform/fields/PdfChoiceFormField.d.ts +0 -9
- package/dist/acroform/fields/PdfChoiceFormField.js +0 -46
- package/dist/acroform/fields/PdfFormField.js +0 -499
- package/dist/acroform/manager.d.ts +0 -33
- package/dist/acroform/manager.js +0 -51
- package/dist/acroform/xfa/PdfXfaForm.d.ts +0 -12
- package/dist/acroform/xfa/PdfXfaForm.js +0 -64
- package/dist/annotations/PdfAnnotationWriter.d.ts +0 -20
- package/dist/annotations/PdfAnnotationWriter.js +0 -76
- package/dist/fonts/font-manager.d.ts +0 -127
- package/dist/fonts/font-manager.js +0 -378
- package/dist/pdf/errors.d.ts +0 -6
- package/dist/pdf/errors.js +0 -6
- package/dist/utils/predictors.d.ts +0 -113
- package/dist/utils/predictors.js +0 -279
- /package/dist/acroform/fields/{PdfDefaultAppearance.d.ts → pdf-default-appearance.d.ts} +0 -0
- /package/dist/acroform/fields/{PdfDefaultAppearance.js → pdf-default-appearance.js} +0 -0
- /package/dist/utils/{IterableReadableStream.d.ts → iterable-readable-stream.d.ts} +0 -0
- /package/dist/utils/{IterableReadableStream.js → iterable-readable-stream.js} +0 -0
|
@@ -9,10 +9,20 @@ export class PdfObject {
|
|
|
9
9
|
modified = true;
|
|
10
10
|
/** Indicates whether the object is immutable (cannot be modified) */
|
|
11
11
|
immutable = false;
|
|
12
|
+
/** Cached byte representation of the object, if available */
|
|
13
|
+
cachedTokens;
|
|
12
14
|
/** The type of this PDF object */
|
|
13
15
|
get objectType() {
|
|
14
16
|
return this.constructor.name;
|
|
15
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* Returns true if this object's serialized form ends with a self-delimiting
|
|
20
|
+
* character (e.g., `)`, `>`, `]`, `>>`). Such objects do not require trailing
|
|
21
|
+
* whitespace before the next token.
|
|
22
|
+
*/
|
|
23
|
+
get isTrailingDelimited() {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
16
26
|
/** Indicates whether the object has been modified. Override this method if the modified state is determined differently */
|
|
17
27
|
isModified() {
|
|
18
28
|
return this.modified;
|
|
@@ -27,10 +37,22 @@ export class PdfObject {
|
|
|
27
37
|
}
|
|
28
38
|
/** Sets the immutable state of the object */
|
|
29
39
|
setImmutable(immutable = true) {
|
|
40
|
+
if (immutable === this.immutable) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
30
43
|
this.immutable = immutable;
|
|
44
|
+
if (immutable) {
|
|
45
|
+
this.cachedTokens = this.toTokens();
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
this.cachedTokens = undefined;
|
|
49
|
+
}
|
|
31
50
|
}
|
|
32
51
|
/** Converts the object to an array of PdfTokens, including any pre or post tokens */
|
|
33
52
|
toTokens() {
|
|
53
|
+
if (this.cachedTokens) {
|
|
54
|
+
return this.cachedTokens;
|
|
55
|
+
}
|
|
34
56
|
return [
|
|
35
57
|
...(this.preTokens ?? []),
|
|
36
58
|
...this.tokenize(),
|
|
@@ -90,4 +112,18 @@ export class PdfObject {
|
|
|
90
112
|
}
|
|
91
113
|
return true;
|
|
92
114
|
}
|
|
115
|
+
/**
|
|
116
|
+
* Serializes the document to a Base64-encoded string.
|
|
117
|
+
*
|
|
118
|
+
* @returns A promise that resolves to the PDF document as a Base64 string
|
|
119
|
+
*/
|
|
120
|
+
toBase64() {
|
|
121
|
+
const bytes = this.toBytes();
|
|
122
|
+
let binary = '';
|
|
123
|
+
const len = bytes.byteLength;
|
|
124
|
+
for (let i = 0; i < len; i++) {
|
|
125
|
+
binary += String.fromCharCode(bytes[i]);
|
|
126
|
+
}
|
|
127
|
+
return btoa(binary);
|
|
128
|
+
}
|
|
93
129
|
}
|
|
@@ -27,6 +27,10 @@ export class PdfStartXRef extends PdfObject {
|
|
|
27
27
|
const cloned = new PdfStartXRef(this.offset.clone());
|
|
28
28
|
return cloned;
|
|
29
29
|
}
|
|
30
|
+
setModified(modified) {
|
|
31
|
+
super.setModified(modified);
|
|
32
|
+
this.offset.setModified(modified);
|
|
33
|
+
}
|
|
30
34
|
isModified() {
|
|
31
35
|
return super.isModified() || this.offset.isModified();
|
|
32
36
|
}
|
|
@@ -1,12 +1,48 @@
|
|
|
1
1
|
import { PdfToken } from '../tokens/token.js';
|
|
2
2
|
import { PdfDictionary } from './pdf-dictionary.js';
|
|
3
3
|
import { PdfObject } from './pdf-object.js';
|
|
4
|
-
import { ByteArray } from '../../types.js';
|
|
4
|
+
import { ByteArray, DecodeParms } from '../../types.js';
|
|
5
5
|
import { PdfNumber } from './pdf-number.js';
|
|
6
6
|
import { PdfIndirectObject } from './pdf-indirect-object.js';
|
|
7
7
|
import { PdfXRefTableEntry } from './pdf-xref-table.js';
|
|
8
8
|
import { PdfFilter, PdfStreamFilterType } from '../../filters/types.js';
|
|
9
|
+
export declare class PdfStreamPredictor extends PdfDictionary<{
|
|
10
|
+
Predictor?: PdfNumber;
|
|
11
|
+
Columns?: PdfNumber;
|
|
12
|
+
Colors?: PdfNumber;
|
|
13
|
+
BitsPerComponent?: PdfNumber;
|
|
14
|
+
}> {
|
|
15
|
+
static NONE: PdfStreamPredictor;
|
|
16
|
+
static TIFF: PdfStreamPredictor;
|
|
17
|
+
static PNG_NONE: PdfStreamPredictor;
|
|
18
|
+
static PNG_SUB: PdfStreamPredictor;
|
|
19
|
+
static PNG_UP: PdfStreamPredictor;
|
|
20
|
+
static PNG_AVERAGE: PdfStreamPredictor;
|
|
21
|
+
static PNG_PAETH: PdfStreamPredictor;
|
|
22
|
+
static PNG_OPTIMUM: PdfStreamPredictor;
|
|
23
|
+
static XREF_STREAM: PdfStreamPredictor;
|
|
24
|
+
get predictor(): number;
|
|
25
|
+
set predictor(value: number);
|
|
26
|
+
get columns(): number;
|
|
27
|
+
set columns(value: number);
|
|
28
|
+
get colors(): number;
|
|
29
|
+
set colors(value: number);
|
|
30
|
+
get bitsPerComponent(): number;
|
|
31
|
+
set bitsPerComponent(value: number);
|
|
32
|
+
toDecodeParms(): DecodeParms;
|
|
33
|
+
cloneImpl(): this;
|
|
34
|
+
static fromDecodeParms(params: DecodeParms): PdfStreamPredictor;
|
|
35
|
+
static fromDictionary(dict?: PdfDictionary): PdfStreamPredictor | undefined;
|
|
36
|
+
encode(data: ByteArray, filterType?: number): ByteArray;
|
|
37
|
+
decode(data: ByteArray): ByteArray;
|
|
38
|
+
private static tiffDecode;
|
|
39
|
+
private static tiffEncode;
|
|
40
|
+
private static pngDecode;
|
|
41
|
+
private static pngEncode;
|
|
42
|
+
private static paethPredictor;
|
|
43
|
+
}
|
|
9
44
|
export declare class PdfStream<T extends PdfDictionary = PdfDictionary> extends PdfObject {
|
|
45
|
+
static PdfStreamPredictor: typeof PdfStreamPredictor;
|
|
10
46
|
header: T;
|
|
11
47
|
original: ByteArray;
|
|
12
48
|
preStreamDataTokens?: PdfToken[];
|
|
@@ -20,14 +56,15 @@ export declare class PdfStream<T extends PdfDictionary = PdfDictionary> extends
|
|
|
20
56
|
set raw(data: ByteArray);
|
|
21
57
|
get originalAsString(): string;
|
|
22
58
|
get rawAsString(): string;
|
|
59
|
+
set rawAsString(str: string);
|
|
60
|
+
get data(): ByteArray;
|
|
61
|
+
set data(data: ByteArray);
|
|
62
|
+
get dataAsString(): string;
|
|
63
|
+
set dataAsString(str: string);
|
|
23
64
|
getFilters(): PdfStreamFilterType[];
|
|
24
65
|
addFilter(filterName: PdfStreamFilterType): this;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
Columns?: number;
|
|
28
|
-
Colors?: number;
|
|
29
|
-
BitsPerComponent?: number;
|
|
30
|
-
}): this;
|
|
66
|
+
get predictor(): PdfStreamPredictor | undefined;
|
|
67
|
+
set predictor(predictor: PdfStreamPredictor);
|
|
31
68
|
removeFilter(filterName: PdfStreamFilterType): this;
|
|
32
69
|
removePredictor(): this;
|
|
33
70
|
removeAllFilters(): this;
|
|
@@ -12,12 +12,244 @@ import { lzw } from '../../filters/lzw.js';
|
|
|
12
12
|
import { runLength } from '../../filters/runlength.js';
|
|
13
13
|
import { passthroughFilter } from '../../filters/pass-through.js';
|
|
14
14
|
import { PdfNumber } from './pdf-number.js';
|
|
15
|
-
import { Predictor } from '../../utils/predictors.js';
|
|
16
15
|
import { bytesToPdfObjects } from '../generators.js';
|
|
17
16
|
import { PdfIndirectObject } from './pdf-indirect-object.js';
|
|
18
17
|
import { PdfXRefTableEntry } from './pdf-xref-table.js';
|
|
19
18
|
import { stringToBytes } from '../../utils/stringToBytes.js';
|
|
19
|
+
import { bytesToString } from '../../utils/bytesToString.js';
|
|
20
|
+
export class PdfStreamPredictor extends PdfDictionary {
|
|
21
|
+
static NONE = new PdfStreamPredictor({ Predictor: new PdfNumber(1) });
|
|
22
|
+
static TIFF = new PdfStreamPredictor({ Predictor: new PdfNumber(2) });
|
|
23
|
+
static PNG_NONE = new PdfStreamPredictor({ Predictor: new PdfNumber(10) });
|
|
24
|
+
static PNG_SUB = new PdfStreamPredictor({ Predictor: new PdfNumber(11) });
|
|
25
|
+
static PNG_UP = new PdfStreamPredictor({ Predictor: new PdfNumber(12) });
|
|
26
|
+
static PNG_AVERAGE = new PdfStreamPredictor({
|
|
27
|
+
Predictor: new PdfNumber(13),
|
|
28
|
+
});
|
|
29
|
+
static PNG_PAETH = new PdfStreamPredictor({ Predictor: new PdfNumber(14) });
|
|
30
|
+
static PNG_OPTIMUM = new PdfStreamPredictor({
|
|
31
|
+
Predictor: new PdfNumber(15),
|
|
32
|
+
});
|
|
33
|
+
static XREF_STREAM = new PdfStreamPredictor({
|
|
34
|
+
Predictor: new PdfNumber(12),
|
|
35
|
+
Columns: new PdfNumber(7),
|
|
36
|
+
});
|
|
37
|
+
get predictor() {
|
|
38
|
+
return this.get('Predictor')?.as(PdfNumber)?.value ?? 1;
|
|
39
|
+
}
|
|
40
|
+
set predictor(value) {
|
|
41
|
+
this.set('Predictor', new PdfNumber(value));
|
|
42
|
+
}
|
|
43
|
+
get columns() {
|
|
44
|
+
return this.get('Columns')?.as(PdfNumber)?.value ?? 1;
|
|
45
|
+
}
|
|
46
|
+
set columns(value) {
|
|
47
|
+
this.set('Columns', new PdfNumber(value));
|
|
48
|
+
}
|
|
49
|
+
get colors() {
|
|
50
|
+
return this.get('Colors')?.as(PdfNumber)?.value ?? 1;
|
|
51
|
+
}
|
|
52
|
+
set colors(value) {
|
|
53
|
+
this.set('Colors', new PdfNumber(value));
|
|
54
|
+
}
|
|
55
|
+
get bitsPerComponent() {
|
|
56
|
+
return this.get('BitsPerComponent')?.as(PdfNumber)?.value ?? 8;
|
|
57
|
+
}
|
|
58
|
+
set bitsPerComponent(value) {
|
|
59
|
+
this.set('BitsPerComponent', new PdfNumber(value));
|
|
60
|
+
}
|
|
61
|
+
toDecodeParms() {
|
|
62
|
+
const params = {};
|
|
63
|
+
const predictor = this.get('Predictor')?.as(PdfNumber);
|
|
64
|
+
if (predictor)
|
|
65
|
+
params.Predictor = predictor.value;
|
|
66
|
+
const columns = this.get('Columns')?.as(PdfNumber);
|
|
67
|
+
if (columns)
|
|
68
|
+
params.Columns = columns.value;
|
|
69
|
+
const colors = this.get('Colors')?.as(PdfNumber);
|
|
70
|
+
if (colors)
|
|
71
|
+
params.Colors = colors.value;
|
|
72
|
+
const bpc = this.get('BitsPerComponent')?.as(PdfNumber);
|
|
73
|
+
if (bpc)
|
|
74
|
+
params.BitsPerComponent = bpc.value;
|
|
75
|
+
return params;
|
|
76
|
+
}
|
|
77
|
+
cloneImpl() {
|
|
78
|
+
return PdfStreamPredictor.fromDecodeParms(this.toDecodeParms());
|
|
79
|
+
}
|
|
80
|
+
static fromDecodeParms(params) {
|
|
81
|
+
const predictor = new PdfStreamPredictor();
|
|
82
|
+
if (params.Predictor !== undefined) {
|
|
83
|
+
predictor.predictor = params.Predictor;
|
|
84
|
+
}
|
|
85
|
+
if (params.Columns !== undefined) {
|
|
86
|
+
predictor.columns = params.Columns;
|
|
87
|
+
}
|
|
88
|
+
if (params.Colors !== undefined) {
|
|
89
|
+
predictor.colors = params.Colors;
|
|
90
|
+
}
|
|
91
|
+
if (params.BitsPerComponent !== undefined) {
|
|
92
|
+
predictor.bitsPerComponent = params.BitsPerComponent;
|
|
93
|
+
}
|
|
94
|
+
return predictor;
|
|
95
|
+
}
|
|
96
|
+
static fromDictionary(dict) {
|
|
97
|
+
if (!dict)
|
|
98
|
+
return undefined;
|
|
99
|
+
const predictor = dict.get('Predictor')?.as(PdfNumber)?.value;
|
|
100
|
+
if (predictor === undefined || predictor <= 1 || predictor > 15) {
|
|
101
|
+
return undefined;
|
|
102
|
+
}
|
|
103
|
+
return PdfStreamPredictor.fromDecodeParms({
|
|
104
|
+
Predictor: predictor,
|
|
105
|
+
Columns: dict.get('Columns')?.as(PdfNumber)?.value,
|
|
106
|
+
Colors: dict.get('Colors')?.as(PdfNumber)?.value,
|
|
107
|
+
BitsPerComponent: dict.get('BitsPerComponent')?.as(PdfNumber)
|
|
108
|
+
?.value,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
encode(data, filterType = 0) {
|
|
112
|
+
const bpp = Math.ceil((this.colors * this.bitsPerComponent) / 8);
|
|
113
|
+
if (this.predictor === 2) {
|
|
114
|
+
return PdfStreamPredictor.tiffEncode(data, this.columns, bpp);
|
|
115
|
+
}
|
|
116
|
+
else if (this.predictor >= 10 && this.predictor <= 15) {
|
|
117
|
+
return PdfStreamPredictor.pngEncode(data, this.columns, bpp, filterType);
|
|
118
|
+
}
|
|
119
|
+
return data;
|
|
120
|
+
}
|
|
121
|
+
decode(data) {
|
|
122
|
+
const bpp = Math.ceil((this.colors * this.bitsPerComponent) / 8);
|
|
123
|
+
if (this.predictor === 2) {
|
|
124
|
+
return PdfStreamPredictor.tiffDecode(data, this.columns, bpp);
|
|
125
|
+
}
|
|
126
|
+
else if (this.predictor >= 10 && this.predictor <= 15) {
|
|
127
|
+
return PdfStreamPredictor.pngDecode(data, this.columns, bpp);
|
|
128
|
+
}
|
|
129
|
+
return data;
|
|
130
|
+
}
|
|
131
|
+
static tiffDecode(data, columns, bpp) {
|
|
132
|
+
const rowLength = columns * bpp;
|
|
133
|
+
const output = new Uint8Array(data.length);
|
|
134
|
+
for (let i = 0; i < data.length; i += rowLength) {
|
|
135
|
+
for (let j = 0; j < rowLength; j++) {
|
|
136
|
+
output[i + j] =
|
|
137
|
+
j < bpp
|
|
138
|
+
? data[i + j]
|
|
139
|
+
: (data[i + j] + output[i + j - bpp]) & 0xff;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return output;
|
|
143
|
+
}
|
|
144
|
+
static tiffEncode(data, columns, bpp) {
|
|
145
|
+
const rowLength = columns * bpp;
|
|
146
|
+
const output = new Uint8Array(data.length);
|
|
147
|
+
for (let i = 0; i < data.length; i += rowLength) {
|
|
148
|
+
for (let j = 0; j < rowLength; j++) {
|
|
149
|
+
output[i + j] =
|
|
150
|
+
j < bpp
|
|
151
|
+
? data[i + j]
|
|
152
|
+
: (data[i + j] - data[i + j - bpp] + 256) & 0xff;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return output;
|
|
156
|
+
}
|
|
157
|
+
static pngDecode(data, columns, bpp) {
|
|
158
|
+
const rowLength = columns * bpp;
|
|
159
|
+
const output = [];
|
|
160
|
+
for (let i = 0; i < data.length;) {
|
|
161
|
+
const filter = data[i];
|
|
162
|
+
const row = data.slice(i + 1, i + 1 + rowLength);
|
|
163
|
+
const prior = output.slice(output.length - rowLength, output.length);
|
|
164
|
+
const decodedRow = new Uint8Array(rowLength);
|
|
165
|
+
for (let j = 0; j < rowLength; j++) {
|
|
166
|
+
const left = j >= bpp ? decodedRow[j - bpp] : 0;
|
|
167
|
+
const up = prior[j] ?? 0;
|
|
168
|
+
const upperLeft = j >= bpp ? (prior[j - bpp] ?? 0) : 0;
|
|
169
|
+
switch (filter) {
|
|
170
|
+
case 0:
|
|
171
|
+
decodedRow[j] = row[j];
|
|
172
|
+
break;
|
|
173
|
+
case 1:
|
|
174
|
+
decodedRow[j] = (row[j] + left) & 0xff;
|
|
175
|
+
break;
|
|
176
|
+
case 2:
|
|
177
|
+
decodedRow[j] = (row[j] + up) & 0xff;
|
|
178
|
+
break;
|
|
179
|
+
case 3:
|
|
180
|
+
decodedRow[j] =
|
|
181
|
+
(row[j] + Math.floor((left + up) / 2)) & 0xff;
|
|
182
|
+
break;
|
|
183
|
+
case 4:
|
|
184
|
+
decodedRow[j] =
|
|
185
|
+
(row[j] +
|
|
186
|
+
this.paethPredictor(left, up, upperLeft)) &
|
|
187
|
+
0xff;
|
|
188
|
+
break;
|
|
189
|
+
default:
|
|
190
|
+
throw new Error(`Unsupported PNG filter: ${filter}`);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
output.push(...decodedRow);
|
|
194
|
+
i += 1 + rowLength;
|
|
195
|
+
}
|
|
196
|
+
return new Uint8Array(output);
|
|
197
|
+
}
|
|
198
|
+
static pngEncode(data, columns, bpp, filterType) {
|
|
199
|
+
const rowLength = columns * bpp;
|
|
200
|
+
const output = [];
|
|
201
|
+
let prior = new Uint8Array(rowLength);
|
|
202
|
+
for (let i = 0; i < data.length; i += rowLength) {
|
|
203
|
+
const row = data.slice(i, i + rowLength);
|
|
204
|
+
const encodedRow = new Uint8Array(rowLength);
|
|
205
|
+
for (let j = 0; j < rowLength; j++) {
|
|
206
|
+
const left = j >= bpp ? row[j - bpp] : 0;
|
|
207
|
+
const up = prior[j] ?? 0;
|
|
208
|
+
const upperLeft = j >= bpp ? (prior[j - bpp] ?? 0) : 0;
|
|
209
|
+
switch (filterType) {
|
|
210
|
+
case 0:
|
|
211
|
+
encodedRow[j] = row[j];
|
|
212
|
+
break;
|
|
213
|
+
case 1:
|
|
214
|
+
encodedRow[j] = (row[j] - left + 256) & 0xff;
|
|
215
|
+
break;
|
|
216
|
+
case 2:
|
|
217
|
+
encodedRow[j] = (row[j] - up + 256) & 0xff;
|
|
218
|
+
break;
|
|
219
|
+
case 3:
|
|
220
|
+
encodedRow[j] =
|
|
221
|
+
(row[j] - Math.floor((left + up) / 2) + 256) & 0xff;
|
|
222
|
+
break;
|
|
223
|
+
case 4:
|
|
224
|
+
encodedRow[j] =
|
|
225
|
+
(row[j] -
|
|
226
|
+
this.paethPredictor(left, up, upperLeft) +
|
|
227
|
+
256) &
|
|
228
|
+
0xff;
|
|
229
|
+
break;
|
|
230
|
+
default:
|
|
231
|
+
throw new Error(`Unsupported PNG filter: ${filterType}`);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
output.push(filterType, ...encodedRow);
|
|
235
|
+
prior = row;
|
|
236
|
+
}
|
|
237
|
+
return new Uint8Array(output);
|
|
238
|
+
}
|
|
239
|
+
static paethPredictor(a, b, c) {
|
|
240
|
+
const p = a + b - c;
|
|
241
|
+
const pa = Math.abs(p - a);
|
|
242
|
+
const pb = Math.abs(p - b);
|
|
243
|
+
const pc = Math.abs(p - c);
|
|
244
|
+
if (pa <= pb && pa <= pc)
|
|
245
|
+
return a;
|
|
246
|
+
if (pb <= pc)
|
|
247
|
+
return b;
|
|
248
|
+
return c;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
20
251
|
export class PdfStream extends PdfObject {
|
|
252
|
+
static PdfStreamPredictor = PdfStreamPredictor;
|
|
21
253
|
header;
|
|
22
254
|
original;
|
|
23
255
|
preStreamDataTokens;
|
|
@@ -44,18 +276,40 @@ export class PdfStream extends PdfObject {
|
|
|
44
276
|
return this.original.slice(0, length);
|
|
45
277
|
}
|
|
46
278
|
set raw(data) {
|
|
47
|
-
if (this.isImmutable()) {
|
|
48
|
-
throw new Error('Cannot modify an immutable PdfStream');
|
|
49
|
-
}
|
|
50
279
|
this.setModified();
|
|
51
280
|
this.original = data;
|
|
52
281
|
this.header.set('Length', new PdfNumber(data.length));
|
|
53
282
|
}
|
|
54
283
|
get originalAsString() {
|
|
55
|
-
return
|
|
284
|
+
return bytesToString(this.original);
|
|
56
285
|
}
|
|
57
286
|
get rawAsString() {
|
|
58
|
-
return
|
|
287
|
+
return bytesToString(this.raw);
|
|
288
|
+
}
|
|
289
|
+
set rawAsString(str) {
|
|
290
|
+
this.raw = stringToBytes(str);
|
|
291
|
+
}
|
|
292
|
+
get data() {
|
|
293
|
+
return this.decode();
|
|
294
|
+
}
|
|
295
|
+
set data(data) {
|
|
296
|
+
const filters = this.getFilters();
|
|
297
|
+
const existingPredictor = this.predictor;
|
|
298
|
+
this.removeAllFilters();
|
|
299
|
+
this.header.delete('DecodeParms');
|
|
300
|
+
this.raw = data;
|
|
301
|
+
if (existingPredictor) {
|
|
302
|
+
this.predictor = existingPredictor;
|
|
303
|
+
}
|
|
304
|
+
for (const filter of filters) {
|
|
305
|
+
this.addFilter(filter);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
get dataAsString() {
|
|
309
|
+
return bytesToString(this.data);
|
|
310
|
+
}
|
|
311
|
+
set dataAsString(str) {
|
|
312
|
+
this.data = stringToBytes(str);
|
|
59
313
|
}
|
|
60
314
|
getFilters() {
|
|
61
315
|
const filters = this.header.get('Filter');
|
|
@@ -90,23 +344,24 @@ export class PdfStream extends PdfObject {
|
|
|
90
344
|
this.raw = filter.encode(this.raw);
|
|
91
345
|
return this;
|
|
92
346
|
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
if (!
|
|
96
|
-
|
|
97
|
-
|
|
347
|
+
get predictor() {
|
|
348
|
+
const raw = this.header.get('DecodeParms');
|
|
349
|
+
if (!raw)
|
|
350
|
+
return undefined;
|
|
351
|
+
if (raw instanceof PdfStreamPredictor) {
|
|
352
|
+
if (raw.get('Predictor') === undefined)
|
|
353
|
+
return undefined;
|
|
354
|
+
return raw;
|
|
98
355
|
}
|
|
99
|
-
|
|
100
|
-
|
|
356
|
+
if (raw instanceof PdfDictionary) {
|
|
357
|
+
return PdfStreamPredictor.fromDictionary(raw);
|
|
101
358
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
this.raw = Predictor.encode(this.raw, predictorParams);
|
|
109
|
-
return this;
|
|
359
|
+
return undefined;
|
|
360
|
+
}
|
|
361
|
+
set predictor(predictor) {
|
|
362
|
+
const cloned = predictor.cloneImpl();
|
|
363
|
+
this.header.set('DecodeParms', cloned);
|
|
364
|
+
this.raw = cloned.encode(this.raw);
|
|
110
365
|
}
|
|
111
366
|
removeFilter(filterName) {
|
|
112
367
|
let filters = this.header.get('Filter');
|
|
@@ -155,9 +410,9 @@ export class PdfStream extends PdfObject {
|
|
|
155
410
|
const filter = PdfStream.getFilter(filterName);
|
|
156
411
|
data = filter.decode(data);
|
|
157
412
|
}
|
|
158
|
-
const
|
|
159
|
-
if (
|
|
160
|
-
data =
|
|
413
|
+
const streamPredictor = PdfStreamPredictor.fromDictionary(this.header.get('DecodeParms')?.as(PdfDictionary));
|
|
414
|
+
if (streamPredictor) {
|
|
415
|
+
data = streamPredictor.decode(data);
|
|
161
416
|
}
|
|
162
417
|
return data;
|
|
163
418
|
}
|
|
@@ -303,11 +558,14 @@ export class PdfObjStream extends PdfStream {
|
|
|
303
558
|
// After that come the actual objects
|
|
304
559
|
const objectNumber = numbers[i * 2].value;
|
|
305
560
|
const generationNumber = 0;
|
|
306
|
-
|
|
561
|
+
const decompressedObject = new PdfIndirectObject({
|
|
307
562
|
objectNumber,
|
|
308
563
|
generationNumber,
|
|
309
564
|
content: obj,
|
|
310
|
-
|
|
565
|
+
compressed: true,
|
|
566
|
+
}).clone();
|
|
567
|
+
decompressedObject.setModified(false);
|
|
568
|
+
yield decompressedObject;
|
|
311
569
|
i++;
|
|
312
570
|
// Stop after we've read N objects
|
|
313
571
|
if (totalObjects > 0 && i >= totalObjects) {
|
|
@@ -37,9 +37,6 @@ export class PdfString extends PdfObject {
|
|
|
37
37
|
return this._raw;
|
|
38
38
|
}
|
|
39
39
|
set raw(raw) {
|
|
40
|
-
if (this.isImmutable()) {
|
|
41
|
-
throw new Error('Cannot modify an immutable PdfString');
|
|
42
|
-
}
|
|
43
40
|
this.setModified();
|
|
44
41
|
this._raw = raw;
|
|
45
42
|
// Clear original bytes when modified
|
|
@@ -53,9 +50,6 @@ export class PdfString extends PdfObject {
|
|
|
53
50
|
return (this.raw.length >= 2 && this.raw[0] === 0xfe && this.raw[1] === 0xff);
|
|
54
51
|
}
|
|
55
52
|
set value(str) {
|
|
56
|
-
if (this.isImmutable()) {
|
|
57
|
-
throw new Error('Cannot modify an immutable PdfString');
|
|
58
|
-
}
|
|
59
53
|
this.setModified();
|
|
60
54
|
if (needsUnicodeEncoding(str)) {
|
|
61
55
|
this._raw = encodeAsUTF16BE(str);
|
|
@@ -74,6 +68,9 @@ export class PdfString extends PdfObject {
|
|
|
74
68
|
// Default: use PDFDocEncoding
|
|
75
69
|
return decodeFromPDFDocEncoding(this.raw);
|
|
76
70
|
}
|
|
71
|
+
get isTrailingDelimited() {
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
77
74
|
tokenize() {
|
|
78
75
|
return [new PdfStringToken(this.raw, this._originalBytes)];
|
|
79
76
|
}
|
|
@@ -26,9 +26,12 @@ export class PdfTrailer extends PdfObject {
|
|
|
26
26
|
const cloned = new PdfTrailer(this.dict.clone());
|
|
27
27
|
return cloned;
|
|
28
28
|
}
|
|
29
|
+
setModified(modified) {
|
|
30
|
+
super.setModified(modified);
|
|
31
|
+
this.dict.setModified(modified);
|
|
32
|
+
this.offset.setModified(modified);
|
|
33
|
+
}
|
|
29
34
|
isModified() {
|
|
30
|
-
return (super.isModified() ||
|
|
31
|
-
this.dict.isModified() ||
|
|
32
|
-
this.offset.isModified);
|
|
35
|
+
return (super.isModified() || this.dict.isModified() || this.offset.modified);
|
|
33
36
|
}
|
|
34
37
|
}
|
|
@@ -87,7 +87,7 @@ export class PdfXRefTable extends PdfObject {
|
|
|
87
87
|
return (super.isModified() ||
|
|
88
88
|
this.sections.some((section) => section.isModified()) ||
|
|
89
89
|
this.entries.some((entry) => entry.isModified()) ||
|
|
90
|
-
this.offset.
|
|
90
|
+
this.offset.modified);
|
|
91
91
|
}
|
|
92
92
|
addEntryForObject(obj) {
|
|
93
93
|
const foundEntry = this.entries.find((entry) => entry.objectNumber.value === obj.objectNumber);
|
|
@@ -1,17 +1,4 @@
|
|
|
1
1
|
import { Parser } from './parser.js';
|
|
2
|
-
/**
|
|
3
|
-
* Error thrown when the parser needs more input to continue parsing.
|
|
4
|
-
*/
|
|
5
|
-
export declare class NoMoreTokensError extends Error {
|
|
6
|
-
}
|
|
7
|
-
/**
|
|
8
|
-
* Error thrown when the end of file has been reached and no more input is available.
|
|
9
|
-
*/
|
|
10
|
-
export declare class EofReachedError extends Error {
|
|
11
|
-
}
|
|
12
|
-
export declare class UnexpectedTokenError extends Error {
|
|
13
|
-
constructor(expected: string, actual: string | null);
|
|
14
|
-
}
|
|
15
2
|
/**
|
|
16
3
|
* Abstract base class for incremental parsers that can process input as it becomes available.
|
|
17
4
|
* Supports buffering, lookahead, and backtracking for complex parsing scenarios.
|
|
@@ -1,22 +1,5 @@
|
|
|
1
1
|
import { Parser } from './parser.js';
|
|
2
|
-
|
|
3
|
-
* Error thrown when the parser needs more input to continue parsing.
|
|
4
|
-
*/
|
|
5
|
-
export class NoMoreTokensError extends Error {
|
|
6
|
-
}
|
|
7
|
-
/**
|
|
8
|
-
* Error thrown when the end of file has been reached and no more input is available.
|
|
9
|
-
*/
|
|
10
|
-
export class EofReachedError extends Error {
|
|
11
|
-
}
|
|
12
|
-
/*
|
|
13
|
-
* Error thrown when an unexpected token is encountered during parsing.
|
|
14
|
-
*/
|
|
15
|
-
export class UnexpectedTokenError extends Error {
|
|
16
|
-
constructor(expected, actual) {
|
|
17
|
-
super(`Unexpected token: expected ${expected}, but got ${actual === null ? 'EOF' : actual}`);
|
|
18
|
-
}
|
|
19
|
-
}
|
|
2
|
+
import { NoMoreTokensError, EofReachedError } from '../../errors.js';
|
|
20
3
|
/**
|
|
21
4
|
* Abstract base class for incremental parsers that can process input as it becomes available.
|
|
22
5
|
* Supports buffering, lookahead, and backtracking for complex parsing scenarios.
|
package/dist/core/ref.d.ts
CHANGED
|
@@ -22,7 +22,7 @@ export declare class Ref<T> {
|
|
|
22
22
|
value: T | Ref<T>;
|
|
23
23
|
/** Registered callbacks for update notifications */
|
|
24
24
|
callbacks: Array<RefUpdateCallback<T>>;
|
|
25
|
-
|
|
25
|
+
modified: boolean;
|
|
26
26
|
protected immutable: boolean;
|
|
27
27
|
/**
|
|
28
28
|
* Creates a new Ref with an initial value.
|
|
@@ -31,6 +31,8 @@ export declare class Ref<T> {
|
|
|
31
31
|
* @throws Error if attempting to create a self-referencing Ref
|
|
32
32
|
*/
|
|
33
33
|
constructor(value: T | Ref<T>);
|
|
34
|
+
isModified(): boolean;
|
|
35
|
+
setModified(modified?: boolean): void;
|
|
34
36
|
setImmutable(immutable?: boolean): void;
|
|
35
37
|
isImmutable(): boolean;
|
|
36
38
|
/**
|
package/dist/core/ref.js
CHANGED
|
@@ -16,7 +16,7 @@ export class Ref {
|
|
|
16
16
|
value;
|
|
17
17
|
/** Registered callbacks for update notifications */
|
|
18
18
|
callbacks = [];
|
|
19
|
-
|
|
19
|
+
modified = true;
|
|
20
20
|
immutable = false;
|
|
21
21
|
/**
|
|
22
22
|
* Creates a new Ref with an initial value.
|
|
@@ -30,6 +30,12 @@ export class Ref {
|
|
|
30
30
|
}
|
|
31
31
|
this.value = value;
|
|
32
32
|
}
|
|
33
|
+
isModified() {
|
|
34
|
+
return this.modified;
|
|
35
|
+
}
|
|
36
|
+
setModified(modified = true) {
|
|
37
|
+
this.modified = modified;
|
|
38
|
+
}
|
|
33
39
|
setImmutable(immutable = true) {
|
|
34
40
|
this.immutable = immutable;
|
|
35
41
|
}
|
|
@@ -49,10 +55,7 @@ export class Ref {
|
|
|
49
55
|
const resolvedNewValue = newValue instanceof Ref ? newValue.resolve() : newValue;
|
|
50
56
|
const oldValue = this.resolve();
|
|
51
57
|
if (oldValue !== resolvedNewValue) {
|
|
52
|
-
|
|
53
|
-
throw new Error(`Cannot update an immutable Ref (${oldValue} -> ${resolvedNewValue})`);
|
|
54
|
-
}
|
|
55
|
-
this.isModified = true;
|
|
58
|
+
this.modified = true;
|
|
56
59
|
}
|
|
57
60
|
this.value = newValue;
|
|
58
61
|
this.callbacks.forEach((cb) => cb(oldValue, this.resolve()));
|