Prevent infinite recursion or multiple processing in matrix change

This commit is contained in:
John Whitington 2023-10-17 15:54:06 +01:00
parent 6f5264ffaf
commit 131a7a0060
2 changed files with 27 additions and 20 deletions

View File

@ -3,7 +3,7 @@ let demo = false
let noncomp = false let noncomp = false
let major_version = 2 let major_version = 2
let minor_version = 6 let minor_version = 6
let version_date = "(patch 2, 19th September 2023)" let version_date = "(patch 2, 17th October 2023)"
open Pdfutil open Pdfutil
open Pdfio open Pdfio
@ -2949,7 +2949,7 @@ let really_write_pdf ?(encryption = None) ?(is_decompress=false) mk_id pdf outna
if noncomp && if noncomp &&
(match args.op with Some (SetProducer _) -> false | _ -> match args.producer with None -> true | _ -> false) (match args.op with Some (SetProducer _) -> false | _ -> match args.producer with None -> true | _ -> false)
then then
set_producer "cpdf non-commercial use only. To buy: http://coherentpdf.com/" pdf; set_producer "cpdf non-commercial use only. To buy: https://coherentpdf.com/" pdf;
if args.creator <> None then set_creator (unopt args.creator) pdf; if args.creator <> None then set_creator (unopt args.creator) pdf;
if args.debugcrypt then Printf.printf "really_write_pdf\n"; if args.debugcrypt then Printf.printf "really_write_pdf\n";
let will_linearize = let will_linearize =

View File

@ -86,6 +86,8 @@ let patterns_used pdf content resources =
ops; ops;
used used
let pats_done = null_hash ()
let rec change_pattern_matrices_resources pdf tr resources names_used_with_scn = let rec change_pattern_matrices_resources pdf tr resources names_used_with_scn =
begin match Pdf.lookup_direct pdf "/XObject" resources with begin match Pdf.lookup_direct pdf "/XObject" resources with
| Some (Pdf.Dictionary elts) -> | Some (Pdf.Dictionary elts) ->
@ -93,7 +95,7 @@ let rec change_pattern_matrices_resources pdf tr resources names_used_with_scn =
(fun (k, v) -> (fun (k, v) ->
match v with match v with
| Pdf.Indirect i -> | Pdf.Indirect i ->
(*Printf.printf "Processing form xobject %s for patterns\n" k;*) (*Printf.printf "Processing form xobject %s for patterns\n%!" k;*)
change_pattern_matrices_xobject pdf tr v i change_pattern_matrices_xobject pdf tr v i
| _ -> raise (Pdf.PDFError "change_pattern_matrices_page")) | _ -> raise (Pdf.PDFError "change_pattern_matrices_page"))
elts elts
@ -107,7 +109,7 @@ let rec change_pattern_matrices_resources pdf tr resources names_used_with_scn =
match Hashtbl.find names_used_with_scn name with match Hashtbl.find names_used_with_scn name with
| exception Not_found -> (name, p) | exception Not_found -> (name, p)
| _ -> | _ ->
(*Printf.printf "Changing matrices of pattern %s\n" name;*) (*Printf.printf "Changing matrices of pattern %s\n%!" name;*)
let old_pattern = Pdf.direct pdf p in let old_pattern = Pdf.direct pdf p in
let new_pattern = let new_pattern =
let existing_tr = Pdf.parse_matrix pdf "/Matrix" old_pattern in let existing_tr = Pdf.parse_matrix pdf "/Matrix" old_pattern in
@ -122,28 +124,33 @@ let rec change_pattern_matrices_resources pdf tr resources names_used_with_scn =
end end
and change_pattern_matrices_xobject pdf tr xobj xobjnum = and change_pattern_matrices_xobject pdf tr xobj xobjnum =
let xobj = Pdf.direct pdf xobj in match xobj with
match Pdf.lookup_direct pdf "/Subtype" xobj with | Pdf.Indirect i when (try ignore (Hashtbl.find pats_done i); true with Not_found -> false) -> ()
| Some (Pdf.Name "/Form") -> | _ ->
Pdfcodec.decode_pdfstream pdf xobj; begin match xobj with Pdf.Indirect i -> Hashtbl.add pats_done i () | _ -> () end;
let resources = match Pdf.lookup_direct pdf "/Resources" xobj with Some d -> d | None -> Pdf.Dictionary [] in let xobj = Pdf.direct pdf xobj in
let used = patterns_used pdf [xobj] resources in match Pdf.lookup_direct pdf "/Subtype" xobj with
begin match Pdf.lookup_direct pdf "/Resources" xobj with | Some (Pdf.Name "/Form") ->
| Some resources -> Pdfcodec.decode_pdfstream pdf xobj;
let xobj' = let resources = match Pdf.lookup_direct pdf "/Resources" xobj with Some d -> d | None -> Pdf.Dictionary [] in
Pdf.add_dict_entry xobj "/Resources" (change_pattern_matrices_resources pdf tr resources used) let used = patterns_used pdf [xobj] resources in
in begin match Pdf.lookup_direct pdf "/Resources" xobj with
Pdf.addobj_given_num pdf (xobjnum, xobj') | Some resources ->
let xobj' =
Pdf.add_dict_entry xobj "/Resources" (change_pattern_matrices_resources pdf tr resources used)
in
Pdf.addobj_given_num pdf (xobjnum, xobj')
| _ -> ()
end
| _ -> () | _ -> ()
end
| _ -> ()
let change_pattern_matrices_page pdf tr page = let change_pattern_matrices_page pdf tr page =
Hashtbl.clear pats_done;
(*change_softmask_matrices_page pdf tr page;*) (*change_softmask_matrices_page pdf tr page;*)
let used = patterns_used pdf page.Pdfpage.content page.Pdfpage.resources in let used = patterns_used pdf page.Pdfpage.content page.Pdfpage.resources in
(*Printf.printf "Patterns for translation, due to being used as cs / CS"; (*Printf.printf "Patterns for translation, due to being used as cs / CS";
Hashtbl.iter (fun x _ -> Printf.printf "%s " x) used; Hashtbl.iter (fun x _ -> Printf.printf "%s " x) used;
Printf.printf "\n";*) Printf.printf "\n%!";*)
{page with Pdfpage.resources = change_pattern_matrices_resources pdf tr page.Pdfpage.resources used} {page with Pdfpage.resources = change_pattern_matrices_resources pdf tr page.Pdfpage.resources used}
(* Output information for each page *) (* Output information for each page *)
@ -466,7 +473,7 @@ let scale_pdf ?(fast=false) sxsylist pdf range =
and matrix = Pdftransform.matrix_of_op (Pdftransform.Scale ((0., 0.), sx, sy)) in and matrix = Pdftransform.matrix_of_op (Pdftransform.Scale ((0., 0.), sx, sy)) in
let transform_op = let transform_op =
Pdfops.Op_cm matrix Pdfops.Op_cm matrix
and page = in let page =
change_pattern_matrices_page pdf matrix page change_pattern_matrices_page pdf matrix page
in in
Pdfannot.transform_annotations pdf matrix page.Pdfpage.rest; Pdfannot.transform_annotations pdf matrix page.Pdfpage.rest;