From 1cc525b5f4bba709ce6f624d26f6d170ca405683 Mon Sep 17 00:00:00 2001 From: Peter Breitenlohner Date: Mon, 11 Aug 2014 08:45:59 +0000 Subject: texk/dvipdfm-x: Add support for JPEG 2000 (and BMP for extractbb), from Shunsaku Hirata git-svn-id: svn://tug.org/texlive/trunk@34905 c570f23f-e606-0410-a88d-b1316a301751 --- Build/source/texk/dvipdfm-x/ChangeLog | 11 + Build/source/texk/dvipdfm-x/Makefile.am | 2 + Build/source/texk/dvipdfm-x/Makefile.in | 104 +++++---- Build/source/texk/dvipdfm-x/bmpimage.c | 309 +++++++++++++++----------- Build/source/texk/dvipdfm-x/bmpimage.h | 2 + Build/source/texk/dvipdfm-x/jp2image.c | 373 ++++++++++++++++++++++++++++++++ Build/source/texk/dvipdfm-x/jp2image.h | 36 +++ Build/source/texk/dvipdfm-x/pdfximage.c | 18 +- Build/source/texk/dvipdfm-x/xbb.c | 41 +++- 9 files changed, 729 insertions(+), 167 deletions(-) create mode 100644 Build/source/texk/dvipdfm-x/jp2image.c create mode 100644 Build/source/texk/dvipdfm-x/jp2image.h diff --git a/Build/source/texk/dvipdfm-x/ChangeLog b/Build/source/texk/dvipdfm-x/ChangeLog index 4d83173d4af..fb682717d7f 100644 --- a/Build/source/texk/dvipdfm-x/ChangeLog +++ b/Build/source/texk/dvipdfm-x/ChangeLog @@ -1,3 +1,14 @@ +2014-08-11 Peter Breitenlohner + + * jp2image.c: Declare scan_file() as static. Drop variables + that are set but not used [-Wunused-but-set-variable]. + +2014-08-11 Shunsaku Hirata + + * bmpimage.[ch], jp2image.[ch] (new), pdfximage.c, xbb.c: + Add support for JPEG 2000 (JP2 and JPX baseline subset) and + BMP support for extractbb. + 2014-08-11 Peter Breitenlohner * Makefile.am: Drop libutil.a, i.e., compile all files once for diff --git a/Build/source/texk/dvipdfm-x/Makefile.am b/Build/source/texk/dvipdfm-x/Makefile.am index 1a8df29ec72..598a49d99fb 100644 --- a/Build/source/texk/dvipdfm-x/Makefile.am +++ b/Build/source/texk/dvipdfm-x/Makefile.am @@ -67,6 +67,8 @@ dvipdfmx_SOURCES = \ error.h \ fontmap.c \ fontmap.h \ + jp2image.c \ + jp2image.h \ jpegimage.c \ jpegimage.h \ mem.c \ diff --git a/Build/source/texk/dvipdfm-x/Makefile.in b/Build/source/texk/dvipdfm-x/Makefile.in index 19f554f6871..dffa27b6d9b 100644 --- a/Build/source/texk/dvipdfm-x/Makefile.in +++ b/Build/source/texk/dvipdfm-x/Makefile.in @@ -159,23 +159,24 @@ am_dvipdfmx_OBJECTS = agl.$(OBJEXT) bmpimage.$(OBJEXT) cff.$(OBJEXT) \ cmap_write.$(OBJEXT) cs_type2.$(OBJEXT) dpxconf.$(OBJEXT) \ dpxcrypt.$(OBJEXT) dpxfile.$(OBJEXT) dpxutil.$(OBJEXT) \ dvi.$(OBJEXT) dvipdfmx.$(OBJEXT) epdf.$(OBJEXT) \ - error.$(OBJEXT) fontmap.$(OBJEXT) jpegimage.$(OBJEXT) \ - mem.$(OBJEXT) mfileio.$(OBJEXT) mpost.$(OBJEXT) \ - numbers.$(OBJEXT) otl_conf.$(OBJEXT) otl_opt.$(OBJEXT) \ - pdfcolor.$(OBJEXT) pdfdev.$(OBJEXT) pdfdoc.$(OBJEXT) \ - pdfdraw.$(OBJEXT) pdfencrypt.$(OBJEXT) pdfencoding.$(OBJEXT) \ - pdffont.$(OBJEXT) pdfnames.$(OBJEXT) pdfobj.$(OBJEXT) \ - pdfparse.$(OBJEXT) pdfresource.$(OBJEXT) pdfximage.$(OBJEXT) \ - pkfont.$(OBJEXT) pngimage.$(OBJEXT) pst.$(OBJEXT) \ - pst_obj.$(OBJEXT) sfnt.$(OBJEXT) spc_color.$(OBJEXT) \ - spc_dvips.$(OBJEXT) spc_html.$(OBJEXT) spc_misc.$(OBJEXT) \ - spc_pdfm.$(OBJEXT) spc_tpic.$(OBJEXT) spc_util.$(OBJEXT) \ - spc_xtx.$(OBJEXT) specials.$(OBJEXT) subfont.$(OBJEXT) \ - t1_char.$(OBJEXT) t1_load.$(OBJEXT) tfm.$(OBJEXT) \ - truetype.$(OBJEXT) tt_aux.$(OBJEXT) tt_cmap.$(OBJEXT) \ - tt_glyf.$(OBJEXT) tt_gsub.$(OBJEXT) tt_post.$(OBJEXT) \ - tt_table.$(OBJEXT) type0.$(OBJEXT) type1.$(OBJEXT) \ - type1c.$(OBJEXT) unicode.$(OBJEXT) vf.$(OBJEXT) xbb.$(OBJEXT) + error.$(OBJEXT) fontmap.$(OBJEXT) jp2image.$(OBJEXT) \ + jpegimage.$(OBJEXT) mem.$(OBJEXT) mfileio.$(OBJEXT) \ + mpost.$(OBJEXT) numbers.$(OBJEXT) otl_conf.$(OBJEXT) \ + otl_opt.$(OBJEXT) pdfcolor.$(OBJEXT) pdfdev.$(OBJEXT) \ + pdfdoc.$(OBJEXT) pdfdraw.$(OBJEXT) pdfencrypt.$(OBJEXT) \ + pdfencoding.$(OBJEXT) pdffont.$(OBJEXT) pdfnames.$(OBJEXT) \ + pdfobj.$(OBJEXT) pdfparse.$(OBJEXT) pdfresource.$(OBJEXT) \ + pdfximage.$(OBJEXT) pkfont.$(OBJEXT) pngimage.$(OBJEXT) \ + pst.$(OBJEXT) pst_obj.$(OBJEXT) sfnt.$(OBJEXT) \ + spc_color.$(OBJEXT) spc_dvips.$(OBJEXT) spc_html.$(OBJEXT) \ + spc_misc.$(OBJEXT) spc_pdfm.$(OBJEXT) spc_tpic.$(OBJEXT) \ + spc_util.$(OBJEXT) spc_xtx.$(OBJEXT) specials.$(OBJEXT) \ + subfont.$(OBJEXT) t1_char.$(OBJEXT) t1_load.$(OBJEXT) \ + tfm.$(OBJEXT) truetype.$(OBJEXT) tt_aux.$(OBJEXT) \ + tt_cmap.$(OBJEXT) tt_glyf.$(OBJEXT) tt_gsub.$(OBJEXT) \ + tt_post.$(OBJEXT) tt_table.$(OBJEXT) type0.$(OBJEXT) \ + type1.$(OBJEXT) type1c.$(OBJEXT) unicode.$(OBJEXT) \ + vf.$(OBJEXT) xbb.$(OBJEXT) dvipdfmx_OBJECTS = $(am_dvipdfmx_OBJECTS) am__DEPENDENCIES_1 = dvipdfmx_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ @@ -190,31 +191,32 @@ am__objects_1 = xdvipdfmx-agl.$(OBJEXT) xdvipdfmx-bmpimage.$(OBJEXT) \ xdvipdfmx-dpxutil.$(OBJEXT) xdvipdfmx-dvi.$(OBJEXT) \ xdvipdfmx-dvipdfmx.$(OBJEXT) xdvipdfmx-epdf.$(OBJEXT) \ xdvipdfmx-error.$(OBJEXT) xdvipdfmx-fontmap.$(OBJEXT) \ - xdvipdfmx-jpegimage.$(OBJEXT) xdvipdfmx-mem.$(OBJEXT) \ - xdvipdfmx-mfileio.$(OBJEXT) xdvipdfmx-mpost.$(OBJEXT) \ - xdvipdfmx-numbers.$(OBJEXT) xdvipdfmx-otl_conf.$(OBJEXT) \ - xdvipdfmx-otl_opt.$(OBJEXT) xdvipdfmx-pdfcolor.$(OBJEXT) \ - xdvipdfmx-pdfdev.$(OBJEXT) xdvipdfmx-pdfdoc.$(OBJEXT) \ - xdvipdfmx-pdfdraw.$(OBJEXT) xdvipdfmx-pdfencrypt.$(OBJEXT) \ - xdvipdfmx-pdfencoding.$(OBJEXT) xdvipdfmx-pdffont.$(OBJEXT) \ - xdvipdfmx-pdfnames.$(OBJEXT) xdvipdfmx-pdfobj.$(OBJEXT) \ - xdvipdfmx-pdfparse.$(OBJEXT) xdvipdfmx-pdfresource.$(OBJEXT) \ - xdvipdfmx-pdfximage.$(OBJEXT) xdvipdfmx-pkfont.$(OBJEXT) \ - xdvipdfmx-pngimage.$(OBJEXT) xdvipdfmx-pst.$(OBJEXT) \ - xdvipdfmx-pst_obj.$(OBJEXT) xdvipdfmx-sfnt.$(OBJEXT) \ - xdvipdfmx-spc_color.$(OBJEXT) xdvipdfmx-spc_dvips.$(OBJEXT) \ - xdvipdfmx-spc_html.$(OBJEXT) xdvipdfmx-spc_misc.$(OBJEXT) \ - xdvipdfmx-spc_pdfm.$(OBJEXT) xdvipdfmx-spc_tpic.$(OBJEXT) \ - xdvipdfmx-spc_util.$(OBJEXT) xdvipdfmx-spc_xtx.$(OBJEXT) \ - xdvipdfmx-specials.$(OBJEXT) xdvipdfmx-subfont.$(OBJEXT) \ - xdvipdfmx-t1_char.$(OBJEXT) xdvipdfmx-t1_load.$(OBJEXT) \ - xdvipdfmx-tfm.$(OBJEXT) xdvipdfmx-truetype.$(OBJEXT) \ - xdvipdfmx-tt_aux.$(OBJEXT) xdvipdfmx-tt_cmap.$(OBJEXT) \ - xdvipdfmx-tt_glyf.$(OBJEXT) xdvipdfmx-tt_gsub.$(OBJEXT) \ - xdvipdfmx-tt_post.$(OBJEXT) xdvipdfmx-tt_table.$(OBJEXT) \ - xdvipdfmx-type0.$(OBJEXT) xdvipdfmx-type1.$(OBJEXT) \ - xdvipdfmx-type1c.$(OBJEXT) xdvipdfmx-unicode.$(OBJEXT) \ - xdvipdfmx-vf.$(OBJEXT) xdvipdfmx-xbb.$(OBJEXT) + xdvipdfmx-jp2image.$(OBJEXT) xdvipdfmx-jpegimage.$(OBJEXT) \ + xdvipdfmx-mem.$(OBJEXT) xdvipdfmx-mfileio.$(OBJEXT) \ + xdvipdfmx-mpost.$(OBJEXT) xdvipdfmx-numbers.$(OBJEXT) \ + xdvipdfmx-otl_conf.$(OBJEXT) xdvipdfmx-otl_opt.$(OBJEXT) \ + xdvipdfmx-pdfcolor.$(OBJEXT) xdvipdfmx-pdfdev.$(OBJEXT) \ + xdvipdfmx-pdfdoc.$(OBJEXT) xdvipdfmx-pdfdraw.$(OBJEXT) \ + xdvipdfmx-pdfencrypt.$(OBJEXT) xdvipdfmx-pdfencoding.$(OBJEXT) \ + xdvipdfmx-pdffont.$(OBJEXT) xdvipdfmx-pdfnames.$(OBJEXT) \ + xdvipdfmx-pdfobj.$(OBJEXT) xdvipdfmx-pdfparse.$(OBJEXT) \ + xdvipdfmx-pdfresource.$(OBJEXT) xdvipdfmx-pdfximage.$(OBJEXT) \ + xdvipdfmx-pkfont.$(OBJEXT) xdvipdfmx-pngimage.$(OBJEXT) \ + xdvipdfmx-pst.$(OBJEXT) xdvipdfmx-pst_obj.$(OBJEXT) \ + xdvipdfmx-sfnt.$(OBJEXT) xdvipdfmx-spc_color.$(OBJEXT) \ + xdvipdfmx-spc_dvips.$(OBJEXT) xdvipdfmx-spc_html.$(OBJEXT) \ + xdvipdfmx-spc_misc.$(OBJEXT) xdvipdfmx-spc_pdfm.$(OBJEXT) \ + xdvipdfmx-spc_tpic.$(OBJEXT) xdvipdfmx-spc_util.$(OBJEXT) \ + xdvipdfmx-spc_xtx.$(OBJEXT) xdvipdfmx-specials.$(OBJEXT) \ + xdvipdfmx-subfont.$(OBJEXT) xdvipdfmx-t1_char.$(OBJEXT) \ + xdvipdfmx-t1_load.$(OBJEXT) xdvipdfmx-tfm.$(OBJEXT) \ + xdvipdfmx-truetype.$(OBJEXT) xdvipdfmx-tt_aux.$(OBJEXT) \ + xdvipdfmx-tt_cmap.$(OBJEXT) xdvipdfmx-tt_glyf.$(OBJEXT) \ + xdvipdfmx-tt_gsub.$(OBJEXT) xdvipdfmx-tt_post.$(OBJEXT) \ + xdvipdfmx-tt_table.$(OBJEXT) xdvipdfmx-type0.$(OBJEXT) \ + xdvipdfmx-type1.$(OBJEXT) xdvipdfmx-type1c.$(OBJEXT) \ + xdvipdfmx-unicode.$(OBJEXT) xdvipdfmx-vf.$(OBJEXT) \ + xdvipdfmx-xbb.$(OBJEXT) nodist_xdvipdfmx_OBJECTS = $(am__objects_1) xdvipdfmx_OBJECTS = $(nodist_xdvipdfmx_OBJECTS) am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ @@ -695,6 +697,8 @@ dvipdfmx_SOURCES = \ error.h \ fontmap.c \ fontmap.h \ + jp2image.c \ + jp2image.h \ jpegimage.c \ jpegimage.h \ mem.c \ @@ -1020,6 +1024,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/epdf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/error.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fontmap.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jp2image.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jpegimage.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mem.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mfileio.Po@am__quote@ @@ -1090,6 +1095,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xdvipdfmx-epdf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xdvipdfmx-error.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xdvipdfmx-fontmap.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xdvipdfmx-jp2image.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xdvipdfmx-jpegimage.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xdvipdfmx-mem.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xdvipdfmx-mfileio.Po@am__quote@ @@ -1459,6 +1465,20 @@ xdvipdfmx-fontmap.obj: fontmap.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-fontmap.obj `if test -f 'fontmap.c'; then $(CYGPATH_W) 'fontmap.c'; else $(CYGPATH_W) '$(srcdir)/fontmap.c'; fi` +xdvipdfmx-jp2image.o: jp2image.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-jp2image.o -MD -MP -MF $(DEPDIR)/xdvipdfmx-jp2image.Tpo -c -o xdvipdfmx-jp2image.o `test -f 'jp2image.c' || echo '$(srcdir)/'`jp2image.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-jp2image.Tpo $(DEPDIR)/xdvipdfmx-jp2image.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='jp2image.c' object='xdvipdfmx-jp2image.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-jp2image.o `test -f 'jp2image.c' || echo '$(srcdir)/'`jp2image.c + +xdvipdfmx-jp2image.obj: jp2image.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-jp2image.obj -MD -MP -MF $(DEPDIR)/xdvipdfmx-jp2image.Tpo -c -o xdvipdfmx-jp2image.obj `if test -f 'jp2image.c'; then $(CYGPATH_W) 'jp2image.c'; else $(CYGPATH_W) '$(srcdir)/jp2image.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-jp2image.Tpo $(DEPDIR)/xdvipdfmx-jp2image.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='jp2image.c' object='xdvipdfmx-jp2image.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o xdvipdfmx-jp2image.obj `if test -f 'jp2image.c'; then $(CYGPATH_W) 'jp2image.c'; else $(CYGPATH_W) '$(srcdir)/jp2image.c'; fi` + xdvipdfmx-jpegimage.o: jpegimage.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(xdvipdfmx_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT xdvipdfmx-jpegimage.o -MD -MP -MF $(DEPDIR)/xdvipdfmx-jpegimage.Tpo -c -o xdvipdfmx-jpegimage.o `test -f 'jpegimage.c' || echo '$(srcdir)/'`jpegimage.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xdvipdfmx-jpegimage.Tpo $(DEPDIR)/xdvipdfmx-jpegimage.Po diff --git a/Build/source/texk/dvipdfm-x/bmpimage.c b/Build/source/texk/dvipdfm-x/bmpimage.c index 8b0bb8d221b..0e5ec092f55 100644 --- a/Build/source/texk/dvipdfm-x/bmpimage.c +++ b/Build/source/texk/dvipdfm-x/bmpimage.c @@ -25,13 +25,15 @@ #endif /* - * BMP SUPPORT: + * BMP SUPPORT: Not fully supported. + * Unsupported features: Transparency, etc. */ #include "system.h" #include "error.h" #include "mem.h" +#include "dvipdfmx.h" /* only for "compat_mode" */ #include "pdfobj.h" #include "bmpimage.h" @@ -49,6 +51,19 @@ #define DIB_HEADER_SIZE_MAX (DIB_FILE_HEADER_SIZE+DIB_INFO_HEADER_SIZE5) +struct hdr_info { + long offset; + long hsize; + long width; + long height; + long compression; + unsigned short bit_count; /* Bits per pix */ + long psize; /* Bytes per palette color: 3 for OS2, 4 for Win */ + unsigned long x_pix_per_meter; + unsigned long y_pix_per_meter; +}; + +static int read_header (FILE *fp, struct hdr_info *hdr); static long read_raster_rle8 (unsigned char *data_ptr, long width, long height, FILE *fp); static long read_raster_rle4 (unsigned char *data_ptr, @@ -69,134 +84,105 @@ check_for_bmp (FILE *fp) return 1; } +static void +get_density (double *xdensity, double *ydensity, struct hdr_info *hdr) +{ + if (compat_mode) + *xdensity = *ydensity = 72.0 / 100.0; + else if (hdr->x_pix_per_meter > 0 && hdr->y_pix_per_meter > 0) { /* 0 for undefined. FIXME */ + *xdensity = 72.0 / (hdr->x_pix_per_meter * 0.0254); + *ydensity = 72.0 / (hdr->y_pix_per_meter * 0.0254); + } else { + *xdensity = 1.0; + *ydensity = 1.0; + } +} + +int +bmp_get_bbox (FILE *fp, long *width, long *height, + double *xdensity, double *ydensity) +{ + int r; + struct hdr_info hdr; + + rewind(fp); + r = read_header(fp, &hdr); + + *width = hdr.width; + *height = hdr.height < 0 ? -hdr.height : hdr.height; + get_density(xdensity, ydensity, &hdr); + + return r; +} + + int bmp_include_image (pdf_ximage *ximage, FILE *fp) { pdf_obj *stream, *stream_dict, *colorspace; - ximage_info info; - unsigned char buf[DIB_HEADER_SIZE_MAX+4]; - unsigned char *p; - long offset, hsize, compression; - long psize; /* Bytes per palette color: 3 for OS2, 4 for Win */ - unsigned short bit_count; /* Bits per pix */ + ximage_info info; + struct hdr_info hdr; int num_palette, flip; int i; - unsigned long biXPelsPerMeter, biYPelsPerMeter; - + pdf_ximage_init_image_info(&info); stream = stream_dict = colorspace = NULL; - p = buf; rewind(fp); - if (fread(buf, 1, DIB_FILE_HEADER_SIZE + 4, fp) - != DIB_FILE_HEADER_SIZE + 4) { - WARN("Could not read BMP file header..."); - } - - if (p[0] != 'B' || p[1] != 'M') { - WARN("File not starting with \'B\' \'M\'... Not a BMP file?"); + if (read_header(fp, &hdr) < 0) return -1; - } - p += 2; -#define ULONG_LE(b) ((b)[0] + ((b)[1] << 8) +\ - ((b)[2] << 16) + ((b)[3] << 24)) -#define USHORT_LE(b) ((b)[0] + ((b)[1] << 8)) - - /* fsize = ULONG_LE(p); */ p += 4; - if (ULONG_LE(p) != 0) { - WARN("Not a BMP file???"); - return -1; - } - p += 4; - offset = ULONG_LE(p); p += 4; - - /* info header */ - hsize = ULONG_LE(p); p += 4; - if (fread(p, sizeof(char), hsize - 4, fp) != hsize - 4) { - WARN("Could not read BMP file header..."); - return -1; - } - flip = 1; - if (hsize == DIB_CORE_HEADER_SIZE) { - info.width = USHORT_LE(p); p += 2; - info.height = USHORT_LE(p); p += 2; - info.xdensity = 1.0; /* assume 72 dpi */ - info.ydensity = 1.0; /* assume 72 dpi */ - if (USHORT_LE(p) != 1) { - WARN("Unknown bcPlanes value in BMP COREHEADER."); - return -1; - } - p += 2; - bit_count = USHORT_LE(p); p += 2; - compression = DIB_COMPRESS_NONE; - psize = 3; - } else if (hsize == DIB_INFO_HEADER_SIZE || - hsize == DIB_INFO_HEADER_SIZE2 || - hsize == DIB_INFO_HEADER_SIZE4 || - hsize == DIB_INFO_HEADER_SIZE5) { - info.width = ULONG_LE(p); p += 4; - info.height = ULONG_LE(p); p += 4; - if (USHORT_LE(p) != 1) { - WARN("Unknown biPlanes value in BMP INFOHEADER."); - return -1; - } - p += 2; - bit_count = USHORT_LE(p); p += 2; - compression = ULONG_LE(p); p += 4; - /* ignore biSizeImage */ p += 4; - biXPelsPerMeter = ULONG_LE(p); p += 4; - biYPelsPerMeter = ULONG_LE(p); p += 4; - info.xdensity = 72.0 / (biXPelsPerMeter * 0.0254); - info.ydensity = 72.0 / (biYPelsPerMeter * 0.0254); - if (info.height < 0) { - info.height = -info.height; - flip = 0; - } - psize = 4; + get_density(&info.xdensity, &info.ydensity, &hdr); + info.width = hdr.width; + info.height = hdr.height; + if (info.height < 0) { + info.height = -info.height; + flip = 0; } else { - ERROR("Unknown BMP header type."); - return -1; /* never reaches here */ + flip = 1; } - if (bit_count < 24) { - if (bit_count != 1 && - bit_count != 4 && bit_count != 8) { - WARN("Unsupported palette size: %ld", bit_count); + + if (hdr.bit_count < 24) { + if (hdr.bit_count != 1 && + hdr.bit_count != 4 && hdr.bit_count != 8) { + WARN("Unsupported palette size: %ld", hdr.bit_count); return -1; } - num_palette = (offset - hsize - DIB_FILE_HEADER_SIZE) / psize; - info.bits_per_component = bit_count; + num_palette = (hdr.offset - hdr.hsize - DIB_FILE_HEADER_SIZE) / hdr.psize; + info.bits_per_component = hdr.bit_count; info.num_components = 1; - } else if (bit_count == 24) { /* full color */ + } else if (hdr.bit_count == 24) { /* full color */ num_palette = 1; /* dummy */ info.bits_per_component = 8; info.num_components = 3; } else { - WARN("Unkown BMP bitCount: %ld", bit_count); + WARN("Unkown/Unsupported BMP bitCount value: %ld", hdr.bit_count); return -1; } if (info.width == 0 || info.height == 0 || num_palette < 1) { WARN("Invalid BMP file: width=%ld, height=%ld, #palette=%d", - info.width, info.height, num_palette); + info.width, info.height, num_palette); return -1; } + /* Start reading raster data */ stream = pdf_new_stream(STREAM_COMPRESS); stream_dict = pdf_stream_dict(stream); - if (bit_count < 24) { + /* Color space: Indexed or DeviceRGB */ + if (hdr.bit_count < 24) { pdf_obj *lookup; unsigned char *palette, bgrq[4]; palette = NEW(num_palette*3+1, unsigned char); for (i = 0; i < num_palette; i++) { - if (fread(bgrq, 1, psize, fp) != psize) { - WARN("Reading file failed..."); - RELEASE(palette); - return -1; + if (fread(bgrq, 1, hdr.psize, fp) != hdr.psize) { + WARN("Reading file failed..."); + RELEASE(palette); + return -1; } /* BGR data */ palette[3*i ] = bgrq[2]; @@ -219,65 +205,65 @@ bmp_include_image (pdf_ximage *ximage, FILE *fp) /* Raster data of BMP is four-byte aligned. */ { long rowbytes, n; - unsigned char *stream_data_ptr = NULL; + unsigned char *p, *stream_data_ptr = NULL; - rowbytes = (info.width * bit_count + 7) / 8; + rowbytes = (info.width * hdr.bit_count + 7) / 8; - seek_absolute(fp, offset); - if (compression == DIB_COMPRESS_NONE) { + seek_absolute(fp, hdr.offset); + if (hdr.compression == DIB_COMPRESS_NONE) { long dib_rowbytes; int padding; padding = (rowbytes % 4) ? 4 - (rowbytes % 4) : 0; dib_rowbytes = rowbytes + padding; - stream_data_ptr = NEW(rowbytes*info.height + padding, - unsigned char); + stream_data_ptr = NEW(rowbytes*info.height + padding, unsigned char); for (n = 0; n < info.height; n++) { - p = stream_data_ptr + n * rowbytes; - if (fread(p, 1, dib_rowbytes, fp) != dib_rowbytes) { - WARN("Reading BMP raster data failed..."); - pdf_release_obj(stream); - RELEASE(stream_data_ptr); - return -1; - } + p = stream_data_ptr + n * rowbytes; + if (fread(p, 1, dib_rowbytes, fp) != dib_rowbytes) { + WARN("Reading BMP raster data failed..."); + pdf_release_obj(stream); + RELEASE(stream_data_ptr); + return -1; + } } - } else if (compression == DIB_COMPRESS_RLE8) { + } else if (hdr.compression == DIB_COMPRESS_RLE8) { stream_data_ptr = NEW(rowbytes*info.height, unsigned char); if (read_raster_rle8(stream_data_ptr, - info.width, info.height, fp) < 0) { - WARN("Reading BMP raster data failed..."); - pdf_release_obj(stream); - RELEASE(stream_data_ptr); - return -1; + info.width, info.height, fp) < 0) { + WARN("Reading BMP raster data failed..."); + pdf_release_obj(stream); + RELEASE(stream_data_ptr); + return -1; } - } else if (compression == DIB_COMPRESS_RLE4) { - stream_data_ptr = NEW(rowbytes*info.height, unsigned char); + } else if (hdr.compression == DIB_COMPRESS_RLE4) { + stream_data_ptr = NEW(rowbytes*info.height, unsigned char); if (read_raster_rle4(stream_data_ptr, info.width, info.height, fp) < 0) { - WARN("Reading BMP raster data failed..."); - pdf_release_obj(stream); - RELEASE(stream_data_ptr); - return -1; + WARN("Reading BMP raster data failed..."); + pdf_release_obj(stream); + RELEASE(stream_data_ptr); + return -1; } } else { + WARN("Unknown/Unsupported compression type for BMP image: %ld", hdr.compression); pdf_release_obj(stream); return -1; } /* gbr --> rgb */ - if (bit_count == 24) { + if (hdr.bit_count == 24) { for (n = 0; n < info.width * info.height * 3; n += 3) { - unsigned char g; - g = stream_data_ptr[n]; - stream_data_ptr[n ] = stream_data_ptr[n+2]; - stream_data_ptr[n+2] = g; + unsigned char g; + g = stream_data_ptr[n]; + stream_data_ptr[n ] = stream_data_ptr[n+2]; + stream_data_ptr[n+2] = g; } } if (flip) { for (n = info.height - 1; n >= 0; n--) { - p = stream_data_ptr + n * rowbytes; - pdf_add_stream(stream, p, rowbytes); + p = stream_data_ptr + n * rowbytes; + pdf_add_stream(stream, p, rowbytes); } } else { pdf_add_stream(stream, stream_data_ptr, rowbytes*info.height); @@ -290,6 +276,85 @@ bmp_include_image (pdf_ximage *ximage, FILE *fp) return 0; } + +static int +read_header (FILE *fp, struct hdr_info *hdr) +{ + unsigned char buf[DIB_HEADER_SIZE_MAX+4]; + unsigned char *p; + + p = buf; + if (fread(buf, 1, DIB_FILE_HEADER_SIZE + 4, fp) + != DIB_FILE_HEADER_SIZE + 4) { + WARN("Could not read BMP file header..."); + return -1; + } + + if (p[0] != 'B' || p[1] != 'M') { + WARN("File not starting with \'B\' \'M\'... Not a BMP file?"); + return -1; + } + p += 2; + +#define ULONG_LE(b) ((b)[0] + ((b)[1] << 8) +\ + ((b)[2] << 16) + ((b)[3] << 24)) +#define USHORT_LE(b) ((b)[0] + ((b)[1] << 8)) + + /* fsize = ULONG_LE(p); */ p += 4; + if (ULONG_LE(p) != 0) { + WARN("Not a BMP file???"); + return -1; + } + p += 4; + hdr->offset = ULONG_LE(p); p += 4; + + /* info header */ + hdr->hsize = ULONG_LE(p); p += 4; + if (fread(p, sizeof(char), hdr->hsize - 4, fp) != hdr->hsize - 4) { + WARN("Could not read BMP file header..."); + return -1; + } + switch (hdr->hsize) { + case DIB_CORE_HEADER_SIZE: + hdr->width = USHORT_LE(p); p += 2; + hdr->height = USHORT_LE(p); p += 2; + hdr->x_pix_per_meter = 0; /* undefined. FIXME */ + hdr->y_pix_per_meter = 0; /* undefined. FIXME */ + if (USHORT_LE(p) != 1) { + WARN("Unknown bcPlanes value in BMP COREHEADER."); + return -1; + } + p += 2; + hdr->bit_count = USHORT_LE(p); p += 2; + hdr->compression = DIB_COMPRESS_NONE; + hdr->psize = 3; + break; + case DIB_INFO_HEADER_SIZE : + case DIB_INFO_HEADER_SIZE2: + case DIB_INFO_HEADER_SIZE4: + case DIB_INFO_HEADER_SIZE5: + hdr->width = ULONG_LE(p); p += 4; + hdr->height = ULONG_LE(p); p += 4; + if (USHORT_LE(p) != 1) { + WARN("Unknown biPlanes value in BMP INFOHEADER."); + return -1; + } + p += 2; + hdr->bit_count = USHORT_LE(p); p += 2; + hdr->compression = ULONG_LE(p); p += 4; + /* ignore biSizeImage */ p += 4; + hdr->x_pix_per_meter = ULONG_LE(p); p += 4; + hdr->y_pix_per_meter = ULONG_LE(p); p += 4; + hdr->psize = 4; + break; + default: + WARN("Unknown BMP header type."); + return -1; + } + + return 0; +} + static long read_raster_rle8 (unsigned char *data_ptr, long width, long height, FILE *fp) diff --git a/Build/source/texk/dvipdfm-x/bmpimage.h b/Build/source/texk/dvipdfm-x/bmpimage.h index 8e6993799ec..111c04eee1f 100644 --- a/Build/source/texk/dvipdfm-x/bmpimage.h +++ b/Build/source/texk/dvipdfm-x/bmpimage.h @@ -29,5 +29,7 @@ extern int bmp_include_image (pdf_ximage *ximage, FILE *file); extern int check_for_bmp (FILE *file); +extern int bmp_get_bbox (FILE *file, long *width, long *height, + double *xdensity, double *ydensity); #endif /* _BMPIMAGE_H_ */ diff --git a/Build/source/texk/dvipdfm-x/jp2image.c b/Build/source/texk/dvipdfm-x/jp2image.c new file mode 100644 index 00000000000..891957fb27d --- /dev/null +++ b/Build/source/texk/dvipdfm-x/jp2image.c @@ -0,0 +1,373 @@ +/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2014 by Jin-Hwan Cho and Matthias Franz, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +/* + * JP2 & JPX baseline SUPPORT: + */ + +#include +#include "system.h" +#include "error.h" +#include "mem.h" + +#include "dvipdfmx.h" + +#include "pdfobj.h" + +#include "jp2image.h" + +/* Box types. */ +#define JP2_BOX_JP__ 0x6a502020 /* Signature */ +#define JP2_BOX_FTYP 0x66747970 /* File Type */ + +#define JP2_BOX_JP2H 0x6a703268 /* JP2 Header */ +#define JP2_BOX_IHDR 0x69686472 /* Image Header */ +#define JP2_BOX_BPCC 0x62706363 /* Bits Per Component */ +#define JP2_BOX_COLR 0x636f6c72 /* Color Specification */ +#define JP2_BOX_PCLR 0x70636c72 /* Palette */ +#define JP2_BOX_CMAP 0x636d6170 /* Component Mapping */ +#define JP2_BOX_CDEF 0x63646566 /* Channel Definition */ +#define JP2_BOX_RES_ 0x72657320 /* Resolution */ +#define JP2_BOX_RESC 0x72657363 /* Capture Resolution */ +#define JP2_BOX_RESD 0x72657364 /* Default Display Resolution */ + +#define JP2_BOX_JP2C 0x6a703263 /* Contiguous Code Stream */ + +#define JPX_BOX_LBL_ 0x6c626c20 /* Label */ + + +static unsigned long +read_box_hdr (FILE *fp, unsigned long *lbox, unsigned long *tbox) +{ + unsigned long bytesread = 0; + + *lbox = get_unsigned_quad(fp); + *tbox = get_unsigned_quad(fp); + bytesread += 8; + if (*lbox == 1) { + *lbox = get_unsigned_quad(fp); + bytesread += 4; + } else if (*lbox > 1 && *lbox < 8) { + WARN("Unknown LBox value %lu in JP2 file!", lbox); + } + + return bytesread; +} + +#define FTYP_BR_JP2_ 0x6a703220 +#define FTYP_BR_JPX_ 0x6a707820 +#define FTYP_CL_JPXB 0x6a707862 + +static int +check_jp___box (FILE *fp) +{ + if (get_unsigned_quad(fp) != 0x0c) + return 0; + if (get_unsigned_quad(fp) != JP2_BOX_JP__) + return 0; + /* Next 4 bytes shall be 0D 0A 87 0A */ + if (get_unsigned_quad(fp) != 0x0D0A870A) + return 0; + return 1; +} + +static int +check_ftyp_data (FILE *fp, unsigned long size) +{ + int supported = 0; + unsigned long BR, CLi; + + BR = get_unsigned_quad(fp); + size -= 4; + /* MinV = */ get_unsigned_quad(fp); + size -= 4; + switch (BR) { + case FTYP_BR_JP2_: /* "jp2 " ... supported */ + seek_relative(fp, size); + size = 0; + supported = 1; + break; + case FTYP_BR_JPX_: /* "jpx " ... baseline subset supported */ + while (size > 0) { + CLi = get_unsigned_quad(fp); + if (CLi == FTYP_CL_JPXB) + supported = 1; + size -= 4; + } + break; + default: + WARN("Unknown JPEG 2000 File Type box Brand field value."); + seek_relative(fp, size); + size = 0; + supported = 0; + } + + return supported; +} + + +static unsigned long +read_res__data (ximage_info *info, FILE *fp, unsigned long size) +{ + unsigned int VR_N, VR_D, HR_N, HR_D; + unsigned char VR_E, HR_E; + + VR_N = get_unsigned_pair(fp); + VR_D = get_unsigned_pair(fp); + HR_N = get_unsigned_pair(fp); + HR_D = get_unsigned_pair(fp); + VR_E = get_unsigned_byte(fp); + HR_E = get_unsigned_byte(fp); + if (compat_mode) + info->xdensity = info->ydensity = 72.0 / 100.0; + else { + info->xdensity = 72.0/(((double) HR_N / HR_D) * pow(10.0, HR_E) * 0.0254); + info->ydensity = 72.0/(((double) VR_N / VR_D) * pow(10.0, VR_E) * 0.0254); + } + + return 10; +} + +static int +scan_res_ (ximage_info *info, FILE *fp, unsigned long size) +{ + unsigned long len, lbox, tbox; + int have_resd = 0; + + while (size > 0) { + len = read_box_hdr(fp, &lbox, &tbox); + if (lbox == 0) { + WARN("Unexpected lbox value 0 in JP2 Resolution box."); + break; + } + switch (tbox) { + case JP2_BOX_RESC: + if (!have_resd) { + read_res__data(info, fp, lbox - len); + } else { + seek_relative(fp, lbox - len); + } + break; + case JP2_BOX_RESD: + read_res__data(info, fp, lbox - len); + have_resd = 1; + break; + default: + WARN("Unknown JPEG 2000 box type in Resolution box."); + seek_relative(fp, lbox - len); + } + size -= lbox; + } + + return size == 0 ? 0 : -1; +} + +static int +scan_jp2h (ximage_info *info, FILE *fp, unsigned long size) +{ + int error = 0, have_ihdr = 0; + unsigned long len, lbox, tbox; + + while (size > 0 && !error) { + len = read_box_hdr(fp, &lbox, &tbox); + if (lbox == 0) { + WARN("Unexpected lbox value 0 in JP2 Header box..."); + error = -1; + break; + } + switch (tbox) { + case JP2_BOX_IHDR: + info->height = get_unsigned_quad(fp); + info->width = get_unsigned_quad(fp); + info->num_components = get_unsigned_pair(fp); + /* c = */ get_unsigned_byte(fp); /* BPC - 1 */ + /* c = */ get_unsigned_byte(fp); /* C: Compression type */ + /* c = */ get_unsigned_byte(fp); /* UnkC */ + /* c = */ get_unsigned_byte(fp); /* IPR */ + have_ihdr = 1; + break; + case JP2_BOX_RES_: + error = scan_res_(info, fp, lbox - len); + break; + case JP2_BOX_BPCC: case JP2_BOX_COLR: case JP2_BOX_PCLR: + case JP2_BOX_CMAP: case JP2_BOX_CDEF: + case JPX_BOX_LBL_: + seek_relative(fp, lbox - len); + break; + default: + WARN("Unknown JPEG 2000 box in JP2 Header box."); + seek_relative(fp, lbox - len); + error = -1; + } + size -= lbox; + } + + if (!have_ihdr) + WARN("Expecting JPEG 2000 Image Header box but could not find."); + return (!error && have_ihdr && size == 0) ? 0 : -1; +} + +static int +scan_file (ximage_info *info, FILE *fp) +{ + int error = 0, have_jp2h = 0; + long size; + unsigned long len, lbox, tbox; + + + size = file_size(fp); + rewind(fp); + + /* Should have already been checked before. */ + /* JPEG 2000 Singature box */ + if (!check_jp___box(fp)) + return -1; + size -= 12; + /* File Type box shall immediately follow */ + len = read_box_hdr(fp, &lbox, &tbox); + if (tbox != JP2_BOX_FTYP) + return -1; + if (!check_ftyp_data(fp, lbox - len)) + return -1; + size -= lbox; + + /* Search for JP2 Header box */ + while (size > 0 && !error) { + len = read_box_hdr(fp, &lbox, &tbox); + if (lbox == 0) + lbox = size; + switch (tbox) { + case JP2_BOX_JP2H: + error = scan_jp2h(info, fp, lbox - len); + have_jp2h = 1; + break; + case JP2_BOX_JP2C: + /* JP2 requires JP2H appears before JP2C. */ + if (!have_jp2h) + WARN("JPEG 2000 Codestream box found before JP2 Header box."); + seek_relative(fp, lbox - len); + break; + default: + seek_relative(fp, lbox - len); + } + size -= lbox; + } + + /* From ISO/IEC 15444-2 M.9.2.7 + The JP2 Header box shall be found in the file before the first + Contiguous Codestream box, Fragment Table box, Media Data box, + Codestream Header box, and Compositing Layer Header box. ... + */ + if (!have_jp2h && !error) { + WARN("No JP2 Header box found. Not a JP2/JPX baseline file?"); + error = -1; + } + return error; +} + +int +check_for_jp2 (FILE *fp) +{ + unsigned long len, lbox, tbox; + + if (!fp) + return 0; + + rewind(fp); + + /* JPEG 2000 Singature box */ + if (!check_jp___box(fp)) + return 0; + + /* File Type box shall immediately follow */ + len = read_box_hdr(fp, &lbox, &tbox); + if (tbox != JP2_BOX_FTYP) + return 0; + if (!check_ftyp_data(fp, lbox - len)) + return 0; + + return 1; +} + +int +jp2_include_image (pdf_ximage *ximage, FILE *fp) +{ + unsigned pdf_version; + pdf_obj *stream, *stream_dict; + ximage_info info; + + pdf_version = pdf_get_version(); + if (pdf_version < 5) { + WARN("JPEG 2000 support requires PDF version >= 1.5 (Current setting 1.%d)\n", pdf_version); + return -1; + } + + pdf_ximage_init_image_info(&info); + stream = stream_dict = NULL; + + rewind(fp); + if (scan_file(&info, fp) < 0) { + WARN("Reading JPEG 2000 file failed."); + return -1; + } + + stream = pdf_new_stream(0); + stream_dict = pdf_stream_dict(stream); + pdf_add_dict(stream_dict, + pdf_new_name("Filter"), pdf_new_name("JPXDecode")); + /* Read whole file */ + { + long nb_read; + rewind(fp); + while ((nb_read = + fread(work_buffer, sizeof(char), WORK_BUFFER_SIZE, fp)) > 0) + pdf_add_stream(stream, work_buffer, nb_read); + } + + pdf_ximage_set_image(ximage, &info, stream); + + return 0; +} + +int +jp2_get_bbox (FILE *fp, long *width, long *height, + double *xdensity, double *ydensity) +{ + int r; + ximage_info info; + + pdf_ximage_init_image_info(&info); + + rewind(fp); + r = scan_file(&info, fp); + + *width = info.width; + *height = info.height; + *xdensity = info.xdensity; + *ydensity = info.ydensity; + + return r; +} \ No newline at end of file diff --git a/Build/source/texk/dvipdfm-x/jp2image.h b/Build/source/texk/dvipdfm-x/jp2image.h new file mode 100644 index 00000000000..0809d9bbaac --- /dev/null +++ b/Build/source/texk/dvipdfm-x/jp2image.h @@ -0,0 +1,36 @@ +/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. + + Copyright (C) 2002-2014 by Jin-Hwan Cho and Matthias Franz, + the dvipdfmx project team. + + Copyright (C) 1998, 1999 by Mark A. Wicks + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. +*/ + +#ifndef _JP2IMAGE_H_ +#define _JP2IMAGE_H_ + +#include "mfileio.h" +#include "pdfximage.h" + +extern int check_for_jp2 (FILE *fp); +extern int jp2_include_image (pdf_ximage *ximage, FILE *fp); +extern int jp2_get_bbox (FILE *fp, long *width, long *height, + double *xdensity, double *ydensity); + +#endif /* _JP2IMAGE_H_ */ + + diff --git a/Build/source/texk/dvipdfm-x/pdfximage.c b/Build/source/texk/dvipdfm-x/pdfximage.c index eefd4f74a6a..53c1ddcab8c 100644 --- a/Build/source/texk/dvipdfm-x/pdfximage.c +++ b/Build/source/texk/dvipdfm-x/pdfximage.c @@ -40,6 +40,7 @@ #include "mpost.h" #include "pngimage.h" #include "jpegimage.h" +#include "jp2image.h" #include "bmpimage.h" #include "pdfximage.h" @@ -56,6 +57,7 @@ static int ps_include_page (pdf_ximage *ximage, const char *file_name); #define IMAGE_TYPE_MPS 4 #define IMAGE_TYPE_EPS 5 #define IMAGE_TYPE_BMP 6 +#define IMAGE_TYPE_JP2 7 struct attr_ @@ -223,6 +225,10 @@ source_image_type (FILE *fp) { format = IMAGE_TYPE_JPEG; } + else if (check_for_jp2(fp)) + { + format = IMAGE_TYPE_JP2; + } #ifdef HAVE_LIBPNG else if (check_for_png(fp)) { @@ -271,6 +277,13 @@ load_image (const char *ident, const char *fullname, int format, FILE *fp, goto error; I->subtype = PDF_XOBJECT_TYPE_IMAGE; break; + case IMAGE_TYPE_JP2: + if (_opts.verbose) + MESG("[JP2]"); + if (jp2_include_image(I, fp) < 0) + goto error; + I->subtype = PDF_XOBJECT_TYPE_IMAGE; + break; #ifdef HAVE_LIBPNG case IMAGE_TYPE_PNG: if (_opts.verbose) @@ -509,8 +522,9 @@ pdf_ximage_set_image (pdf_ximage *I, void *image_info, pdf_obj *resource) pdf_add_dict(dict, pdf_new_name("Subtype"), pdf_new_name("Image")); pdf_add_dict(dict, pdf_new_name("Width"), pdf_new_number(info->width)); pdf_add_dict(dict, pdf_new_name("Height"), pdf_new_number(info->height)); - pdf_add_dict(dict, pdf_new_name("BitsPerComponent"), - pdf_new_number(info->bits_per_component)); + if (info->bits_per_component > 0) /* Ignored for JPXDecode filter. FIXME */ + pdf_add_dict(dict, pdf_new_name("BitsPerComponent"), + pdf_new_number(info->bits_per_component)); if (I->attr_dict) pdf_merge_dict(dict, I->attr_dict); diff --git a/Build/source/texk/dvipdfm-x/xbb.c b/Build/source/texk/dvipdfm-x/xbb.c index 25841155b7e..98fec810056 100644 --- a/Build/source/texk/dvipdfm-x/xbb.c +++ b/Build/source/texk/dvipdfm-x/xbb.c @@ -33,7 +33,9 @@ #include "pdfdoc.h" #include "pdfparse.h" +#include "bmpimage.h" #include "jpegimage.h" +#include "jp2image.h" #include "pngimage.h" #include "dvipdfmx.h" @@ -85,7 +87,8 @@ static void do_time(FILE *file) } const char *extensions[] = { - ".ai", ".AI", ".jpeg", ".JPEG", ".jpg", ".JPG", ".pdf", ".PDF", ".png", ".PNG" + ".ai", ".AI", ".bmp", ".BMP", ".jpeg", ".JPEG", ".jpg", ".JPG", + ".jp2", ".JP2", ".jpf", ".JPF", ".pdf", ".PDF", ".png", ".PNG" }; static int xbb_to_file = 1; @@ -169,6 +172,20 @@ static void write_xbb(char *fname, } } +static void do_bmp (FILE *fp, char *filename) +{ + long width, height; + double xdensity, ydensity; + + if (bmp_get_bbox(fp, &width, &height, &xdensity, &ydensity) < 0) { + WARN("%s does not look like a BMP file...\n", filename); + return; + } + + write_xbb(filename, 0, 0, xdensity*width, ydensity*height, -1, -1); + return; +} + static void do_jpeg (FILE *fp, char *filename) { long width, height; @@ -183,6 +200,20 @@ static void do_jpeg (FILE *fp, char *filename) return; } +static void do_jp2 (FILE *fp, char *filename) +{ + long width, height; + double xdensity, ydensity; + + if (jp2_get_bbox(fp, &width, &height, &xdensity, &ydensity) < 0) { + WARN("%s does not look like a JP2/JPX file...\n", filename); + return; + } + + write_xbb(filename, 0, 0, xdensity*width, ydensity*height, -1, -1); + return; +} + #ifdef HAVE_LIBPNG static void do_png (FILE *fp, char *filename) { @@ -299,10 +330,18 @@ int extractbb (int argc, char *argv[]) WARN("Can't find file (%s), or it is forbidden to read ...skipping\n", argv[0]); goto cont; } + if (check_for_bmp(infile)) { + do_bmp(infile, kpse_file_name); + goto cont; + } if (check_for_jpeg(infile)) { do_jpeg(infile, kpse_file_name); goto cont; } + if (check_for_jp2(infile)) { + do_jp2(infile, kpse_file_name); + goto cont; + } if (check_for_pdf(infile)) { do_pdf(infile, kpse_file_name); goto cont; -- cgit v1.2.3