Merge pull request #16558 from Snuffleupagus/writeStream-filter-fixes
Improve handling of /Filter-entries in `writeStream`
This commit is contained in:
		
						commit
						04c31a55d2
					
				@ -14,7 +14,7 @@
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import { bytesToString, info, stringToBytes, warn } from "../shared/util.js";
 | 
			
		||||
import { Dict, Name, Ref } from "./primitives.js";
 | 
			
		||||
import { Dict, isName, Name, Ref } from "./primitives.js";
 | 
			
		||||
import {
 | 
			
		||||
  escapePDFName,
 | 
			
		||||
  escapeString,
 | 
			
		||||
@ -49,28 +49,29 @@ async function writeStream(stream, buffer, transform) {
 | 
			
		||||
  if (transform !== null) {
 | 
			
		||||
    string = transform.encryptString(string);
 | 
			
		||||
  }
 | 
			
		||||
  const { dict } = stream;
 | 
			
		||||
 | 
			
		||||
  // eslint-disable-next-line no-undef
 | 
			
		||||
  if (typeof CompressionStream === "undefined") {
 | 
			
		||||
    stream.dict.set("Length", string.length);
 | 
			
		||||
    await writeDict(stream.dict, buffer, transform);
 | 
			
		||||
    dict.set("Length", string.length);
 | 
			
		||||
    await writeDict(dict, buffer, transform);
 | 
			
		||||
    buffer.push(" stream\n", string, "\nendstream");
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const filter = await stream.dict.getAsync("Filter");
 | 
			
		||||
  const flateDecode = Name.get("FlateDecode");
 | 
			
		||||
  const filter = await dict.getAsync("Filter");
 | 
			
		||||
  const params = await dict.getAsync("DecodeParms");
 | 
			
		||||
 | 
			
		||||
  // If the string is too small there is no real benefit
 | 
			
		||||
  // in compressing it.
 | 
			
		||||
  const filterZero = Array.isArray(filter)
 | 
			
		||||
    ? await dict.xref.fetchIfRefAsync(filter[0])
 | 
			
		||||
    : filter;
 | 
			
		||||
  const isFilterZeroFlateDecode = isName(filterZero, "FlateDecode");
 | 
			
		||||
 | 
			
		||||
  // If the string is too small there is no real benefit in compressing it.
 | 
			
		||||
  // The number 256 is arbitrary, but it should be reasonable.
 | 
			
		||||
  const MIN_LENGTH_FOR_COMPRESSING = 256;
 | 
			
		||||
 | 
			
		||||
  if (
 | 
			
		||||
    string.length >= MIN_LENGTH_FOR_COMPRESSING ||
 | 
			
		||||
    (Array.isArray(filter) && filter.includes(flateDecode)) ||
 | 
			
		||||
    (filter instanceof Name && filter.name === flateDecode.name)
 | 
			
		||||
  ) {
 | 
			
		||||
  if (string.length >= MIN_LENGTH_FOR_COMPRESSING || isFilterZeroFlateDecode) {
 | 
			
		||||
    try {
 | 
			
		||||
      const byteArray = stringToBytes(string);
 | 
			
		||||
      // eslint-disable-next-line no-undef
 | 
			
		||||
@ -83,25 +84,32 @@ async function writeStream(stream, buffer, transform) {
 | 
			
		||||
      const buf = await new Response(cs.readable).arrayBuffer();
 | 
			
		||||
      string = bytesToString(new Uint8Array(buf));
 | 
			
		||||
 | 
			
		||||
      if (Array.isArray(filter)) {
 | 
			
		||||
        if (!filter.includes(flateDecode)) {
 | 
			
		||||
          filter.push(flateDecode);
 | 
			
		||||
      let newFilter, newParams;
 | 
			
		||||
      if (!filter) {
 | 
			
		||||
        newFilter = Name.get("FlateDecode");
 | 
			
		||||
      } else if (!isFilterZeroFlateDecode) {
 | 
			
		||||
        newFilter = Array.isArray(filter)
 | 
			
		||||
          ? [Name.get("FlateDecode"), ...filter]
 | 
			
		||||
          : [Name.get("FlateDecode"), filter];
 | 
			
		||||
        if (params) {
 | 
			
		||||
          newParams = Array.isArray(params)
 | 
			
		||||
            ? [null, ...params]
 | 
			
		||||
            : [null, params];
 | 
			
		||||
        }
 | 
			
		||||
      } else if (!filter) {
 | 
			
		||||
        stream.dict.set("Filter", flateDecode);
 | 
			
		||||
      } else if (
 | 
			
		||||
        !(filter instanceof Name) ||
 | 
			
		||||
        filter.name !== flateDecode.name
 | 
			
		||||
      ) {
 | 
			
		||||
        stream.dict.set("Filter", [filter, flateDecode]);
 | 
			
		||||
      }
 | 
			
		||||
      if (newFilter) {
 | 
			
		||||
        dict.set("Filter", newFilter);
 | 
			
		||||
      }
 | 
			
		||||
      if (newParams) {
 | 
			
		||||
        dict.set("DecodeParms", newParams);
 | 
			
		||||
      }
 | 
			
		||||
    } catch (ex) {
 | 
			
		||||
      info(`writeStream - cannot compress data: "${ex}".`);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  stream.dict.set("Length", string.length);
 | 
			
		||||
  await writeDict(stream.dict, buffer, transform);
 | 
			
		||||
  dict.set("Length", string.length);
 | 
			
		||||
  await writeDict(dict, buffer, transform);
 | 
			
		||||
  buffer.push(" stream\n", string, "\nendstream");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1979,7 +1979,7 @@ describe("api", function () {
 | 
			
		||||
      await loadingTask.destroy();
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it("write a a new annotation, save the pdf and check that the prev entry in xref stream is correct", async function () {
 | 
			
		||||
    it("write a new annotation, save the pdf and check that the prev entry in xref stream is correct", async function () {
 | 
			
		||||
      if (isNodeJS) {
 | 
			
		||||
        pending("Linked test-cases are not supported in Node.js.");
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user