diff --git a/Makefile b/Makefile index 8dde5b1..ac7ae08 100644 --- a/Makefile +++ b/Makefile @@ -6,8 +6,8 @@ DOC = cpdfunicodedata cpdferror cpdfdebug cpdfjson cpdfstrftime cpdfcoord \ cpdfbookmarks cpdfpage cpdftruetype cpdfremovetext cpdfextracttext \ cpdfembed cpdfaddtext cpdfimage cpdffont cpdftype cpdfpad cpdfocg \ cpdfsqueeze cpdfdraft cpdfspot cpdfpagelabels cpdfcreate cpdfannot \ - cpdfxobject cpdfimpose cpdftweak cpdftexttopdf cpdftoc cpdfdraw \ - cpdfcommand + cpdfxobject cpdfimpose cpdftweak cpdftexttopdf cpdftoc cpdfjpeg \ + cpdfdraw cpdfcommand MODS = $(NONDOC) $(DOC) diff --git a/cpdfcommand.ml b/cpdfcommand.ml index 0020b3e..179b353 100644 --- a/cpdfcommand.ml +++ b/cpdfcommand.ml @@ -1932,7 +1932,7 @@ let addjpeg n = in try let data = Pdfio.bytes_of_string (contents_of_file filename) in - let w, h = Pdfjpeg.jpeg_dimensions data in + let w, h = Cpdfjpeg.jpeg_dimensions data in let d = ["/Length", Pdf.Integer (Pdfio.bytes_size data); "/Filter", Pdf.Name "/DCTDecode"; diff --git a/cpdfjpeg.ml b/cpdfjpeg.ml new file mode 100644 index 0000000..4b3e6cf --- /dev/null +++ b/cpdfjpeg.ml @@ -0,0 +1,39 @@ +open Pdfutil +open Pdfio + +(* Return the width and height of a JPEG image, per Michael Petrov's C version. *) +exception Answer of int * int + +let jpeg_dimensions bs = + try + let get = bget bs in + let i = ref 0 in + if get !i = 0xFF && get (!i + 1) = 0xD8 && get (!i + 2) = 0xFF && get (!i + 3) = 0xE0 then + begin + i += 4; + if + get (!i + 2) = int_of_char 'J' && get (!i + 3) = int_of_char 'F' + && get (!i + 4) = int_of_char 'I' && get (!i + 5) = int_of_char 'F' + && get (!i + 6) = 0 + then + let block_length = ref (get !i * 256 + get (!i + 1)) in + while !i < bytes_size bs do + i := !i + !block_length; + if !i > bytes_size bs then raise (Pdf.PDFError "jpeg_dimensions: too short") else + if get !i <> 0xFF then raise (Pdf.PDFError "jpeg_dimensions: not a valid block") else + if get (!i + 1) = 0xC0 then + raise (Answer (get (!i + 7) * 256 + get (!i + 8), (get (!i + 5) * 256 + get (!i + 6)))) + else + begin + i += 2; + block_length := get !i * 256 + get (!i + 1) + end + done + else + raise (Pdf.PDFError "jpeg_dimensions: Not a valid JFIF string") + end + else + raise (Pdf.PDFError "jpeg_dimensions: Not a valid SOI header"); + assert false + with + Answer (w, h) -> (w, h) diff --git a/cpdfjpeg.mli b/cpdfjpeg.mli new file mode 100644 index 0000000..ed45ae4 --- /dev/null +++ b/cpdfjpeg.mli @@ -0,0 +1,2 @@ +(** Return the dimensions of a JPEG *) +val jpeg_dimensions : Pdfio.bytes -> int * int