The /Filter + /DecodeParms chain — ISO 32000-2 §7.4.

Module pdfFilterDispatch | Source packages/front/office/pdf/src/syntax/filters/dispatch.js | Deps pdfErrors, pdfFlate, pdfAsciiHex, pdfAscii85, pdfRunLength | Worker-safe yes

Reads /Filter (a name or an array of names) and applies the decoders in order — the first name is applied first, which is the spec convention and the reverse of the encoding order. Recognised PDF abbreviations: Fl, AHx, A85, RL, LZW, DCT, JPX, CCF. Opaque filters exposed as passthrough: DCTDecode, JPXDecode, Crypt. Any filter absent from decoders raises pdf/filter/unsupported.

decodeStream marshals /DecodeParms from the typed AST form ({type:'dict', entries:{K: {type, value}}}) to a plain key → value object (reading entry.value per key) before handing it to a decoder — decoders such as pdfFlate read plain properties (params.Predictor, params.Columns, …), never typed nodes. The three /DecodeParms shapes are all handled: absent (→ null params for every filter), a single dict (→ applies to the first filter only, null for the rest, per spec), and an array parallel to /Filter (→ one marshalled dict per filter, null entries preserved).

Resolve

const dispatch = runtime.resolve('pdfFilterDispatch');
// Returns: { decode, decodeChain, encodeChain, register, names, decoders,
//            normalizeFilterList, applyDecodeChain, applyEncodeChain,
//            decodeStream }

API

Member Signature Returns
decode (streamObj: PdfStream) => Uint8Array End-to-end decode from the typed stream, against the built-in decoders.
decodeChain (bytes, filters: string[], params?: object[]) => Uint8Array Explicit decode against the built-in decoders.
encodeChain (bytes, filters: string[], params?: object[]) => Uint8Array Explicit encode against the built-in decoders.
register (name: string, impl: { decode, encode? }) => void Adds or replaces a decoder in decoders.
names () => string[] Lists the currently registered filter names.
decoders object The live map itself (escape hatch — mutating it is what register does).
normalizeFilterList (filterEntry) => string[] Expands abbreviations and returns the canonical name list. Useful to inspect a chain without decoding.
applyDecodeChain (bytes, filters, params, decoders) => Uint8Array Lower-level decode against a caller-supplied decoder map.
applyEncodeChain (bytes, filters, params, decoders) => Uint8Array Lower-level encode against a caller-supplied decoder map.
decodeStream (streamObj, decoders) => Uint8Array Lower-level decode: reads /Filter + /DecodeParms off the stream dictionary, then delegates to applyDecodeChain.

decode, decodeChain and encodeChain are thin bindings of the three lower-level helpers over the module's own decoders map; the apply*/ decodeStream triple is exported so a caller can run a chain against an isolated map without mutating the shared one.

Examples

End-to-end decode

const dispatch = runtime.resolve('pdfFilterDispatch');
const decoded = dispatch.decode(streamObj);   // reads Filter + DecodeParms

Explicit chain

const out = dispatch.decodeChain(bytes, ['ASCII85Decode', 'FlateDecode']);
// Applies ASCII85 then Flate (= array order).

Register a custom decoder (LZW)

const legacy = runtime.resolve('pdfLegacyDeprecatedFilters');
dispatch.register('LZWDecode', {
    decode: (bytes, params) => legacy.lzwDecode(bytes, params),
    encode: (bytes) => legacy.lzwEncode(bytes)
});

Decode against an isolated map

const isolated = { ...dispatch.decoders, DCTDecode: myJpegDecoder };
const out = dispatch.decodeStream(streamObj, isolated);

Inspect a chain without decoding

dispatch.normalizeFilterList(streamObj.dict.entries.Filter);
// ['ASCII85Decode', 'FlateDecode']

List the available filters

dispatch.names();
// ['FlateDecode', 'ASCIIHexDecode', 'ASCII85Decode', 'RunLengthDecode',
//  'DCTDecode', 'JPXDecode', 'Crypt']

Errors

Code Class When
pdf/filter/non-name ParseError An entry of the /Filter array is not a name.
pdf/filter/bad-type ParseError /Filter is neither a name nor an array.
pdf/filter/unsupported ParseError Filter absent from decoders.
pdf/filter/no-encoder ParseError encodeChain invoked for a filter with no encode.
pdf/filter/not-stream ParseError decode()/decodeStream() given something other than a typed stream.
pdf/filter/bad-decodeparms ParseError /DecodeParms is neither a dict, an array, nor null.

See also