Extend PNG loading to greyscale and 16bpp

This commit is contained in:
John Whitington 2024-01-01 11:46:32 +00:00
parent e31f3c2562
commit bb620c8f06
4 changed files with 30 additions and 21 deletions

View File

@ -24,6 +24,7 @@ Extended features:
o -list-images-used[-json] extends -image-resolution o -list-images-used[-json] extends -image-resolution
o Use -raw with -extract-images to get PNMs o Use -raw with -extract-images to get PNMs
o -extract-images can extract JBIG2 images and their globals o -extract-images can extract JBIG2 images and their globals
o more PNGs - greyscale 1, 2, 4, 8, 16bpp and RGB 16bpp
Fixes: Fixes:

View File

@ -433,11 +433,11 @@ let obj_of_png_data data =
["/Length", Pdf.Integer (Pdfio.bytes_size png.idat); ["/Length", Pdf.Integer (Pdfio.bytes_size png.idat);
"/Filter", Pdf.Name "/FlateDecode"; "/Filter", Pdf.Name "/FlateDecode";
"/Subtype", Pdf.Name "/Image"; "/Subtype", Pdf.Name "/Image";
"/BitsPerComponent", Pdf.Integer 8; "/BitsPerComponent", Pdf.Integer png.bitdepth;
"/ColorSpace", Pdf.Name "/DeviceRGB"; "/ColorSpace", Pdf.Name (match png.colortype with 0 -> "/DeviceGray" | 2 -> "/DeviceRGB" | _ -> error "obj_of_png_data 1");
"/DecodeParms", Pdf.Dictionary "/DecodeParms", Pdf.Dictionary
["/BitsPerComponent", Pdf.Integer 8; ["/BitsPerComponent", Pdf.Integer png.bitdepth;
"/Colors", Pdf.Integer 3; "/Colors", Pdf.Integer (match png.colortype with 0 -> 1 | 2 -> 3 | _ -> error "obj_of_png_data 2");
"/Columns", Pdf.Integer png.width; "/Columns", Pdf.Integer png.width;
"/Predictor", Pdf.Integer 15]; "/Predictor", Pdf.Integer 15];
"/Width", Pdf.Integer png.width; "/Width", Pdf.Integer png.width;

View File

@ -1,12 +1,15 @@
(* Read non-interlaced, non-transparent 24 bit PNGs. Such a PNG may (* Read non-interlaced, non-transparent PNGs. Such a PNG may
be loaded into a PDF simply by extracting its width and height from the be loaded into a PDF simply by extracting its width and height from the
IHDR, and concatenating all its IDAT data sections together. *) IHDR, and concatenating all its IDAT data sections together, and specifying
the appropriate Filter and Predictor.*)
open Pdfutil open Pdfutil
open Pdfio open Pdfio
type t = type t =
{width : int; {width : int;
height : int; height : int;
bitdepth : int;
colortype : int;
idat : bytes} idat : bytes}
(* Writing *) (* Writing *)
@ -121,9 +124,8 @@ let read_png i =
let width = read_unsigned_4byte hdr in let width = read_unsigned_4byte hdr in
let height = read_unsigned_4byte hdr in let height = read_unsigned_4byte hdr in
let bitdepth = hdr.input_byte () in let bitdepth = hdr.input_byte () in
if bitdepth <> 8 then raise (Pdf.PDFError "read_png: bit depth not 8") else
let colortype = hdr.input_byte () in let colortype = hdr.input_byte () in
if colortype <> 2 then raise (Pdf.PDFError "read_png: only 24 bit non-alpha PNGs") else if colortype <> 2 && colortype <> 0 then raise (Pdf.PDFError "read_png: only non-alpha non-palette PNGs") else
let _ (*compressionmethod*) = hdr.input_byte () in let _ (*compressionmethod*) = hdr.input_byte () in
let _ (*filtermethod*) = hdr.input_byte () in let _ (*filtermethod*) = hdr.input_byte () in
let interlacemethod = hdr.input_byte () in let interlacemethod = hdr.input_byte () in
@ -137,6 +139,10 @@ let read_png i =
with with
_ -> () _ -> ()
end; end;
{width = i32toi width; height = i32toi height; idat = concat_bytes (rev !idat)} {width = i32toi width;
height = i32toi height;
colortype;
bitdepth;
idat = concat_bytes (rev !idat)}
with with
e -> raise (Pdf.PDFError (Printf.sprintf "read_png: failed on %s" (Printexc.to_string e))) e -> raise (Pdf.PDFError (Printf.sprintf "read_png: failed on %s" (Printexc.to_string e)))

View File

@ -4,7 +4,9 @@
type t = type t =
{width : int; {width : int;
height : int; height : int;
bitdepth : int;
colortype : int;
idat : Pdfio.bytes} idat : Pdfio.bytes}
(** Read a non-interlaced, non-transparent 24 bit PNG for inclusion in a PDF file. *) (** Read a non-interlaced, non-alpha, non-palette PNG for inclusion in a PDF file. *)
val read_png : Pdfio.input -> t val read_png : Pdfio.input -> t