summaryrefslogtreecommitdiff
path: root/Build/source/texk/xdvipdfmx/src/pdfximage.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/xdvipdfmx/src/pdfximage.c')
-rw-r--r--Build/source/texk/xdvipdfmx/src/pdfximage.c271
1 files changed, 187 insertions, 84 deletions
diff --git a/Build/source/texk/xdvipdfmx/src/pdfximage.c b/Build/source/texk/xdvipdfmx/src/pdfximage.c
index 72c287fe2d1..c67b8047b73 100644
--- a/Build/source/texk/xdvipdfmx/src/pdfximage.c
+++ b/Build/source/texk/xdvipdfmx/src/pdfximage.c
@@ -1,8 +1,8 @@
-/* $Header: /home/cvsroot/dvipdfmx/src/pdfximage.c,v 1.14 2005/07/30 11:44:18 hirata Exp $
+/* $Header: /home/cvsroot/dvipdfmx/src/pdfximage.c,v 1.17 2008/02/13 20:22:21 matthias Exp $
This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
- Copyright (C) 2002 by Jin-Hwan Cho and Shunsaku Hirata,
+ Copyright (C) 2007 by Jin-Hwan Cho and Shunsaku Hirata,
the dvipdfmx project team <dvipdfmx@project.ktug.or.kr>
Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
@@ -63,14 +63,15 @@ static int ps_include_page (pdf_ximage *ximage, const char *file_name);
struct attr_
{
long width, height;
+ double xdensity, ydensity;
pdf_rect bbox;
- double xdpi, ydpi;
};
struct pdf_ximage_
{
char *ident;
char res_name[16];
+ long page_no, page_count;
int subtype;
@@ -79,7 +80,6 @@ struct pdf_ximage_
char *filename;
pdf_obj *reference;
pdf_obj *resource;
- int page_index;
int pdf_box;
};
@@ -112,18 +112,18 @@ static void
pdf_init_ximage_struct (pdf_ximage *I)
{
I->ident = NULL;
+ I->page_no = I->page_count = 0;
I->filename = NULL;
I->subtype = -1;
memset(I->res_name, 0, 16);
I->reference = NULL;
I->resource = NULL;
- I->page_index = 0;
I->pdf_box = 0;
I->attr.width = I->attr.height = 0;
+ I->attr.xdensity = I->attr.ydensity = 1.0;
I->attr.bbox.llx = I->attr.bbox.lly = 0;
I->attr.bbox.urx = I->attr.bbox.ury = 0;
- I->attr.xdpi = I->attr.ydpi = 72.0;
}
static void
@@ -256,8 +256,8 @@ filter_put_form_attr (pdf_obj *kp, pdf_obj *vp, void *dp)
static int
-load_image (const char *ident, int page_index, int pdf_box,
- const char *fullname, int format, FILE *fp)
+load_image (const char *ident,
+ const char *fullname, int format, FILE *fp, long page_no)
{
struct ic_ *ic = &_ic;
int id = -1; /* ret */
@@ -271,6 +271,7 @@ load_image (const char *ident, int page_index, int pdf_box,
I = &ic->ximages[id];
pdf_init_ximage_struct(I);
+ pdf_ximage_set_page(I, page_no, 0);
switch (format) {
case IMAGE_TYPE_JPEG:
@@ -299,11 +300,12 @@ load_image (const char *ident, int page_index, int pdf_box,
case IMAGE_TYPE_PDF:
if (_opts.verbose)
MESG("[PDF]");
- if (pdf_include_page(I, fp, page_index, pdf_box) < 0)
+// if (pdf_include_page(I, fp, page_index, pdf_box) < 0)
+ if (pdf_include_page(I, fp) < 0)
return -1;
I->subtype = PDF_XOBJECT_TYPE_FORM;
- I->page_index = page_index;
- I->pdf_box = pdf_box;
+// I->page_index = page_index;
+// I->pdf_box = pdf_box;
break;
case IMAGE_TYPE_EPS:
if (_opts.verbose)
@@ -348,7 +350,7 @@ load_image (const char *ident, int page_index, int pdf_box,
#define dpx_fclose(f) (MFCLOSE((f)))
int
-pdf_ximage_findresource (const char *ident, int page_index, int pdf_box)
+pdf_ximage_findresource (const char *ident, long page_no)
{
struct ic_ *ic = &_ic;
int id = -1;
@@ -359,9 +361,8 @@ pdf_ximage_findresource (const char *ident, int page_index, int pdf_box)
for (id = 0; id < ic->count; id++) {
I = &ic->ximages[id];
- if (I->ident && !strcmp(ident, I->ident)
- && page_index == I->page_index
- && pdf_box == I->pdf_box) {
+ if (I->ident && !strcmp(ident, I->ident) &&
+ I->page_no == page_no + (page_no < 0 ? I->page_count+1 : 0)) {
return id;
}
}
@@ -393,7 +394,7 @@ pdf_ximage_findresource (const char *ident, int page_index, int pdf_box)
id = mps_include_page(ident, fp);
break;
default:
- id = load_image(ident, page_index, pdf_box, fullname, format, fp);
+ id = load_image(ident, fullname, format, fp, page_no);
break;
}
dpx_fclose(fp);
@@ -409,6 +410,20 @@ pdf_ximage_findresource (const char *ident, int page_index, int pdf_box)
return id;
}
+/* Reference: PDF Reference 1.5 v6, pp.321--322
+ *
+ * TABLE 4.42 Additional entries specific to a type 1 form dictionary
+ *
+ * BBox rectangle (Required) An array of four numbers in the form coordinate
+ * system, giving the coordinates of the left, bottom, right,
+ * and top edges, respectively, of the form XObject's bounding
+ * box. These boundaries are used to clip the form XObject and
+ * to determine its size for caching.
+ *
+ * Matrix array (Optional) An array of six numbers specifying the form
+ * matrix, which maps form space into user space.
+ * Default value: the identity matrix [1 0 0 1 0 0].
+ */
void
pdf_ximage_init_form_info (xform_info *info)
{
@@ -425,6 +440,36 @@ pdf_ximage_init_form_info (xform_info *info)
info->matrix.f = 0.0;
}
+/* Reference: PDF Reference 1.5 v6, pp.303--306
+ *
+ * TABLE 4.42 Additional entries specific to an image dictionary
+ *
+ * Width integer (Required) The width of the image, in samples.
+ *
+ * Height integer (Required) The height of the image, in samples.
+ *
+ * ColorSpace name or array
+ * (Required for images, except those that use the JPXDecode
+ * filter; not allowed for image masks) The color space in
+ * which image samples are specified. This may be any type
+ * of color space except Patter.
+ *
+ * If the image uses the JPXDecode filter, this entry is
+ * optional.
+ *
+ * BitsPerComponent integer
+ * (Required except for image masks and images that use the
+ * JPXDecode filter) The number of bits used to represent
+ * each color component. Only a single value may be specified;
+ * the number of bits is the same for all color components.
+ * Valid values are 1,2,4,8, and (in PDF1.5) 16. If ImageMask
+ * is true, this entry is optional, and if speficified, its
+ * value must be 1.
+ *
+ * If the image stream uses the JPXDecode filter, this entry
+ * is optional and ignored if present. The bit depth is
+ * determined in the process of decoding the JPEG2000 image.
+ */
void
pdf_ximage_init_image_info (ximage_info *info)
{
@@ -434,7 +479,7 @@ pdf_ximage_init_image_info (ximage_info *info)
info->bits_per_component = 0;
info->num_components = 0;
info->min_dpi = 0;
- info->xdpi = info->ydpi = 72.0;
+ info->xdensity = info->ydensity = 1.0;
}
void
@@ -444,15 +489,14 @@ pdf_ximage_set_image (pdf_ximage *I, void *image_info, pdf_obj *resource)
ximage_info *info = image_info;
if (!PDF_OBJ_STREAMTYPE(resource))
- ERROR("Image XObject must be stream type.");
+ ERROR("Image XObject must be of stream type.");
I->subtype = PDF_XOBJECT_TYPE_IMAGE;
- I->attr.width = info->width;
- I->attr.height = info->height;
-
- I->attr.xdpi = info->xdpi;
- I->attr.ydpi = info->ydpi;
+ I->attr.width = info->width; /* The width of the image, in samples */
+ I->attr.height = info->height; /* The height of the image, in samples */
+ I->attr.xdensity = info->xdensity;
+ I->attr.ydensity = info->ydensity;
I->reference = pdf_ref_obj(resource);
@@ -469,21 +513,36 @@ pdf_ximage_set_image (pdf_ximage *I, void *image_info, pdf_obj *resource)
}
void
-pdf_ximage_set_form (pdf_ximage *I, void *form_info, pdf_obj *resource)
+pdf_ximage_set_form (pdf_ximage *I, void *form_info, pdf_obj *resource)
{
- xform_info *info = form_info;
+ xform_info *info = form_info;
I->subtype = PDF_XOBJECT_TYPE_FORM;
+
I->attr.bbox.llx = info->bbox.llx;
I->attr.bbox.lly = info->bbox.lly;
I->attr.bbox.urx = info->bbox.urx;
I->attr.bbox.ury = info->bbox.ury;
I->reference = pdf_ref_obj(resource);
+
pdf_release_obj(resource); /* Caller don't know we are using reference. */
I->resource = NULL;
}
+long
+pdf_ximage_get_page (pdf_ximage *I)
+{
+ return I->page_no;
+}
+
+void
+pdf_ximage_set_page (pdf_ximage *I, long page_no, long page_count)
+{
+ I->page_no = page_no;
+ I->page_count = page_count;
+}
+
#define CHECK_ID(c,n) do {\
if ((n) < 0 || (n) >= (c)->count) {\
@@ -495,8 +554,8 @@ pdf_ximage_set_form (pdf_ximage *I, void *form_info, pdf_obj *resource)
pdf_obj *
pdf_ximage_get_reference (int id)
{
- struct ic_ *ic = &_ic;
- pdf_ximage *I;
+ struct ic_ *ic = &_ic;
+ pdf_ximage *I;
CHECK_ID(ic, id);
@@ -504,16 +563,17 @@ pdf_ximage_get_reference (int id)
if (!I->reference)
I->reference = pdf_ref_obj(I->resource);
- return pdf_link_obj(I->reference);
+ return pdf_link_obj(I->reference);
}
+/* called from pdfdoc.c only for late binding */
int
pdf_ximage_defineresource (const char *ident,
int subtype, void *info, pdf_obj *resource)
{
- struct ic_ *ic = &_ic;
- int id;
- pdf_ximage *I;
+ struct ic_ *ic = &_ic;
+ int id;
+ pdf_ximage *I;
id = ic->count;
if (ic->count >= ic->capacity) {
@@ -532,12 +592,10 @@ pdf_ximage_defineresource (const char *ident,
switch (subtype) {
case PDF_XOBJECT_TYPE_IMAGE:
pdf_ximage_set_image(I, info, resource);
- I->subtype = PDF_XOBJECT_TYPE_IMAGE;
sprintf(I->res_name, "Im%d", id);
break;
case PDF_XOBJECT_TYPE_FORM:
pdf_ximage_set_form (I, info, resource);
- I->subtype = PDF_XOBJECT_TYPE_FORM;
sprintf(I->res_name, "Fm%d", id);
break;
default:
@@ -552,71 +610,77 @@ pdf_ximage_defineresource (const char *ident,
char *
pdf_ximage_get_resname (int id)
{
- struct ic_ *ic = &_ic;
- pdf_ximage *I;
+ struct ic_ *ic = &_ic;
+ pdf_ximage *I;
CHECK_ID(ic, id);
I = GET_IMAGE(ic, id);
- return I->res_name;
+ return I->res_name;
}
+
/* depth...
* Dvipdfm treat "depth" as "yoffset" for pdf:image and pdf:uxobj
* not as vertical dimension of scaled image. (And there are bugs.)
* This part contains incompatibile behaviour than dvipdfm!
*/
-#define EBB_DPI 72 /* was 100 in dvipdfmx; changed to 72 to match xetex's ideas
- about graphics resolution/scaling */
+#define EBB_DPI 72
+
static void
scale_to_fit_I (pdf_tmatrix *T,
transform_info *p,
pdf_ximage *I)
{
- double s_x, s_y;
- long wdx = I->attr.width;
- long htx = I->attr.height;
- double ar, dp;
- double xdpi = I->attr.xdpi;
- double ydpi = I->attr.ydpi;
-
- /* if image didn't have DPI info, then treat it as EBB_DPI */
- if (xdpi == 0.0)
- xdpi = EBB_DPI;
- if (ydpi == 0.0)
- ydpi = EBB_DPI;
+ double s_x, s_y, d_x, d_y;
+ double wd0, ht0, dp, xscale, yscale;
- if (htx == 0) {
- WARN("Image height=0!");
- htx = 1;
+ if (p->flags & INFO_HAS_USER_BBOX) {
+ wd0 = p->bbox.urx - p->bbox.llx;
+ ht0 = p->bbox.ury - p->bbox.lly;
+ xscale = I->attr.width * I->attr.xdensity / wd0;
+ yscale = I->attr.height * I->attr.ydensity / ht0;
+ d_x = -p->bbox.llx / wd0;
+ d_y = -p->bbox.lly / ht0;
+ } else {
+ wd0 = I->attr.width * I->attr.xdensity;
+ ht0 = I->attr.height * I->attr.ydensity;
+ xscale = yscale = 1.0;
+ d_x = 0.0;
+ d_y = 0.0;
}
- ar = (double) wdx / htx;
+ if (wd0 == 0.0) {
+ WARN("Image width=0.0!");
+ wd0 = 1.0;
+ }
+ if (ht0 == 0.0) {
+ WARN("Image height=0.0!");
+ ht0 = 1.0;
+ }
- /* only width/height --> uniform (keep aspect ratio)
- * no width-height --> uniform with 72dpi implied (?)
- * both width-height --> non-uniform
- */
if ( (p->flags & INFO_HAS_WIDTH ) &&
(p->flags & INFO_HAS_HEIGHT) ) {
- s_x = p->width; s_y = p->height + p->depth;
- dp = p->depth;
- } else if ( p->flags & INFO_HAS_WIDTH ) {
- s_x = p->width; s_y = s_x / ar;
+ s_x = p->width * xscale;
+ s_y = (p->height + p->depth) * yscale;
+ dp = p->depth * yscale;
+ } else if ( p->flags & INFO_HAS_WIDTH ) {
+ s_x = p->width * xscale;
+ s_y = s_x * ((double)I->attr.height / I->attr.width);
dp = 0.0;
- } else if ( p->flags & INFO_HAS_HEIGHT ) {
- s_y = p->height + p->depth; s_x = s_y * ar;
- dp = p->depth;
+ } else if ( p->flags & INFO_HAS_HEIGHT) {
+ s_y = (p->height + p->depth) * yscale;
+ s_x = s_y * ((double)I->attr.width / I->attr.height);
+ dp = p->depth * yscale;
} else {
- s_x = wdx * 72.0 / xdpi;
- s_y = htx * 72.0 / ydpi;
+ s_x = wd0;
+ s_y = ht0;
dp = 0.0;
}
-
- T->a = s_x; T->c = 0.0;
- T->b = 0.0; T->d = s_y;
- T->e = 0.0; T->f = -dp;
+ T->a = s_x; T->c = 0.0;
+ T->b = 0.0; T->d = s_y;
+ T->e = d_x * s_x / xscale; T->f = d_y * s_y / yscale - dp;
return;
}
@@ -677,15 +741,16 @@ scale_to_fit_F (pdf_tmatrix *T,
}
+/* called from pdfdev.c and spc_html.c */
int
pdf_ximage_scale_image (int id,
- pdf_tmatrix *M, /* ret */
- pdf_rect *r, /* ret */
- transform_info *p /* arg */
+ pdf_tmatrix *M, /* return value for trans matrix */
+ pdf_rect *r, /* return value for clipping */
+ transform_info *p /* argument from specials */
)
{
- struct ic_ *ic = &_ic;
- pdf_ximage *I;
+ struct ic_ *ic = &_ic;
+ pdf_ximage *I;
CHECK_ID(ic, id);
@@ -694,13 +759,47 @@ pdf_ximage_scale_image (int id,
pdf_setmatrix(M, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
switch (I->subtype) {
+ /* Reference: PDF Reference 1.5 v6, p.302
+ *
+ * An image can be placed on the output page in any desired position,
+ * orientation, and size by using the cm operator to modify the current
+ * transformation matrix (CTM) so as to map the unit square of user space
+ * to the rectangle or parallelogram in which the image is to be painted.
+ *
+ * There is neither BBox nor Matrix key in the image XObject.
+ * Everything must be controlled by the cm operator.
+ *
+ * The argument [p] contains the user-defined bounding box, the scailing
+ * factor of which is bp as EPS and PDF. On the other hand, I->attr
+ * contains the (sampling) width and the (sampling) height of the image.
+ *
+ * There is no problem if a bitmap image has density information.
+ * Otherwise, DVIPDFM's ebb generates bounding box as 100px = 72bp = 1in.
+ * In this case, screen captured images look bad. Moreover, DVIPDFM's ebb
+ * ignores all density information and use just 100px = 72bp = 1in.
+ *
+ * On the other hand, pdfTeX uses 100px = 100bp to get a better quality
+ * for screen captured images.
+ *
+ * DVIPDFMx's xbb generates bounding box as 100px = 100bp in the same
+ * way as pdfTeX. Furthermore, it takes care of density information too.
+ */
case PDF_XOBJECT_TYPE_IMAGE:
scale_to_fit_I(M, p, I);
- r->llx = 0.0;
- r->lly = 0.0;
- r->urx = M->a;
- r->ury = M->d;
+ if (p->flags & INFO_HAS_USER_BBOX) {
+ r->llx = p->bbox.llx / (I->attr.width * I->attr.xdensity);
+ r->lly = p->bbox.lly / (I->attr.height * I->attr.ydensity);
+ r->urx = p->bbox.urx / (I->attr.width * I->attr.xdensity);
+ r->ury = p->bbox.ury / (I->attr.height * I->attr.ydensity);
+ } else {
+ r->llx = 0.0;
+ r->lly = 0.0;
+ r->urx = 1.0;
+ r->ury = 1.0;
+ }
break;
+ /* User-defined transformation and clipping are controlled by
+ * the cm operator and W operator, explicitly */
case PDF_XOBJECT_TYPE_FORM:
scale_to_fit_F(M, p, I);
if (p->flags & INFO_HAS_USER_BBOX) {
@@ -708,7 +807,7 @@ pdf_ximage_scale_image (int id,
r->lly = p->bbox.lly;
r->urx = p->bbox.urx;
r->ury = p->bbox.ury;
- } else {
+ } else { /* I->attr.bbox from the image bounding box */
r->llx = I->attr.bbox.llx;
r->lly = I->attr.bbox.lly;
r->urx = I->attr.bbox.urx;
@@ -736,6 +835,11 @@ void set_distiller_template (char *s)
return;
}
+char *get_distiller_template (void)
+{
+ return _opts.cmdtmpl;
+}
+
static int
ps_include_page (pdf_ximage *ximage, const char *filename)
{
@@ -776,7 +880,8 @@ ps_include_page (pdf_ximage *ximage, const char *filename)
dpx_delete_temp_file(temp);
return -1;
}
- error = pdf_include_page(ximage, fp, 0, pdfbox_crop);
+// error = pdf_include_page(ximage, fp, 0, pdfbox_crop);
+ error = pdf_include_page(ximage, fp);
MFCLOSE(fp);
if (_opts.verbose > 1) {
@@ -803,5 +908,3 @@ static int check_for_ps (FILE *image_file)
return 1;
return 0;
}
-
-