From eb358a76afd128e61231e50a97170238cb778641 Mon Sep 17 00:00:00 2001 From: John Whitington Date: Fri, 22 Mar 2024 13:57:04 +0000 Subject: [PATCH] Skeleton for JPEG2000 images --- Changes | 6 ++++++ cpdfcommand.ml | 7 +++++++ cpdfimage.ml | 11 +++++++++++ cpdfimage.mli | 1 + cpdfjpeg2000.ml | 4 ++-- 5 files changed, 27 insertions(+), 2 deletions(-) diff --git a/Changes b/Changes index a106f85..d345743 100644 --- a/Changes +++ b/Changes @@ -1,3 +1,9 @@ +2.8 (To come) + +New features: + +o Build PDF files from JPEG2000 (.jp2, .jpx) files + 2.7 (February 2024) New features: diff --git a/cpdfcommand.ml b/cpdfcommand.ml index 5797654..76da0c8 100644 --- a/cpdfcommand.ml +++ b/cpdfcommand.ml @@ -1014,6 +1014,8 @@ let set_input_png s = set_input_image (fun () -> Cpdfimage.obj_of_png_data) s let set_input_jpeg s = set_input_image (fun () -> Cpdfimage.obj_of_jpeg_data) s +let set_input_jpeg2000 s = set_input_image (fun () -> Cpdfimage.obj_of_jpeg2000_data) s + let set_input_jbig2 s = set_input_image (fun () -> Cpdfimage.obj_of_jbig2_data ?global:!jbig2_global) s; @@ -1059,6 +1061,8 @@ let anon_fun s = | a::b::c::d::e::'.'::r when implode (map Char.uppercase_ascii [e; d; c; b; a]) = "JBIG2" -> set_input_jbig2 s | a::b::c::d::'.'::r when implode (map Char.uppercase_ascii [d; c; b; a]) = "JPEG" -> set_input_jpeg s | a::b::c::'.'::r when implode (map Char.uppercase_ascii [c; b; a]) = "JPG" -> set_input_jpeg s + | a::b::c::'.'::r when implode (map Char.uppercase_ascii [c; b; a]) = "JP2" -> set_input_jpeg2000 s + | a::b::c::'.'::r when implode (map Char.uppercase_ascii [c; b; a]) = "JPX" -> set_input_jpeg2000 s | a::b::c::'.'::r when implode (map Char.uppercase_ascii [c; b; a]) = "PNG" -> set_input_png s | _ -> args.inputs <- (InFile s, "all", "", "", ref false, None)::args.inputs end; @@ -1872,6 +1876,9 @@ and specs = ("-jpeg", Arg.String set_input_jpeg, " Load from a JPEG file, converting to PDF"); + ("-jpeg2000", + Arg.String set_input_jpeg2000, + " Load from a JPEG2000 file, converting to PDF"); ("-jbig2", Arg.String set_input_jbig2, " Load from a JBIG2 fragment, converting to PDF"); diff --git a/cpdfimage.ml b/cpdfimage.ml index ca0ec82..427d7c1 100644 --- a/cpdfimage.ml +++ b/cpdfimage.ml @@ -456,6 +456,17 @@ let obj_of_png_data data = in Pdf.Stream {contents = (Pdf.Dictionary d, Pdf.Got png.idat)}, [] +let obj_of_jpeg2000_data data = + let w, h = Cpdfjpeg2000.jpeg2000_dimensions data in + let d = + ["/Length", Pdf.Integer (Pdfio.bytes_size data); + "/Filter", Pdf.Name "/JPXDecode"; + "/Subtype", Pdf.Name "/Image"; + "/Width", Pdf.Integer w; + "/Height", Pdf.Integer h] + in + Pdf.Stream {contents = (Pdf.Dictionary d, Pdf.Got data)}, [] + let jbig2_dimensions data = (bget data 11 * 256 * 256 * 256 + bget data 12 * 256 * 256 + bget data 13 * 256 + bget data 14, bget data 15 * 256 * 256 * 256 + bget data 16 * 256 * 256 + bget data 17 * 256 + bget data 18) diff --git a/cpdfimage.mli b/cpdfimage.mli index 66fcb14..2f88d7f 100644 --- a/cpdfimage.mli +++ b/cpdfimage.mli @@ -29,3 +29,4 @@ val image_of_input : (unit -> Pdfio.bytes -> Pdf.pdfobject * (int * Pdf.pdfobjec val obj_of_jpeg_data : Pdfio.bytes -> Pdf.pdfobject * (int * Pdf.pdfobject) list val obj_of_png_data : Pdfio.bytes -> Pdf.pdfobject * (int * Pdf.pdfobject) list val obj_of_jbig2_data : ?global:Pdfio.bytes -> Pdfio.bytes -> Pdf.pdfobject * (int * Pdf.pdfobject) list +val obj_of_jpeg2000_data : Pdfio.bytes -> Pdf.pdfobject * (int * Pdf.pdfobject) list diff --git a/cpdfjpeg2000.ml b/cpdfjpeg2000.ml index bcbd084..a27acd1 100644 --- a/cpdfjpeg2000.ml +++ b/cpdfjpeg2000.ml @@ -1,5 +1,5 @@ open Pdfutil open Pdfio -(* Return the width and height of a JPEG2000 image, per Michael Petrov's C version. *) -let jpeg2000_dimensions bs = (0, 0) +(* Return the width and height of a JPEG2000 image. *) +let jpeg2000_dimensions bs = (28, 30)