summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Breitenlohner <peb@mppmu.mpg.de>2014-08-11 08:45:59 +0000
committerPeter Breitenlohner <peb@mppmu.mpg.de>2014-08-11 08:45:59 +0000
commit1cc525b5f4bba709ce6f624d26f6d170ca405683 (patch)
tree94d4bdb301f7b67abe78c6158601b1557e666e34
parent82c4fbd59ef01eb96adfd4c62bbab9f43fcbf7cb (diff)
texk/dvipdfm-x: Add support for JPEG 2000 (and BMP for extractbb),
from Shunsaku Hirata <shunsaku.hirata74@gmail.com> git-svn-id: svn://tug.org/texlive/trunk@34905 c570f23f-e606-0410-a88d-b1316a301751
-rw-r--r--Build/source/texk/dvipdfm-x/ChangeLog11
-rw-r--r--Build/source/texk/dvipdfm-x/Makefile.am2
-rw-r--r--Build/source/texk/dvipdfm-x/Makefile.in104
-rw-r--r--Build/source/texk/dvipdfm-x/bmpimage.c309
-rw-r--r--Build/source/texk/dvipdfm-x/bmpimage.h2
-rw-r--r--Build/source/texk/dvipdfm-x/jp2image.c373
-rw-r--r--Build/source/texk/dvipdfm-x/jp2image.h36
-rw-r--r--Build/source/texk/dvipdfm-x/pdfximage.c18
-rw-r--r--Build/source/texk/dvipdfm-x/xbb.c41
9 files changed, 729 insertions, 167 deletions
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,5 +1,16 @@
2014-08-11 Peter Breitenlohner <peb@mppmu.mpg.de>
+ * jp2image.c: Declare scan_file() as static. Drop variables
+ that are set but not used [-Wunused-but-set-variable].
+
+2014-08-11 Shunsaku Hirata <shunsaku.hirata74@gmail.com>
+
+ * 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 <peb@mppmu.mpg.de>
+
* Makefile.am: Drop libutil.a, i.e., compile all files once for
dvipdfmx and once for xdvipdfmx.
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 <mwicks@kettering.edu>
+
+ 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 <config.h>
+#endif
+
+/*
+ * JP2 & JPX baseline SUPPORT:
+ */
+
+#include <math.h>
+#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 <mwicks@kettering.edu>
+
+ 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;