summaryrefslogtreecommitdiff
path: root/Build/source/texk/dvipdfm-x/pdfximage.c
diff options
context:
space:
mode:
authorAkira Kakuto <kakuto@fuk.kindai.ac.jp>2020-07-20 20:56:58 +0000
committerAkira Kakuto <kakuto@fuk.kindai.ac.jp>2020-07-20 20:56:58 +0000
commitdbfd3d35c0325197dec305820484818e46f8ac13 (patch)
treea85efc199f7dc07a4ac77be05e0aac00b6b72566 /Build/source/texk/dvipdfm-x/pdfximage.c
parent42232d1095a8b15d33ecf3448250569fc6ed6915 (diff)
support forward reference of image objects (S. Hirata)
git-svn-id: svn://tug.org/texlive/trunk@55887 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/dvipdfm-x/pdfximage.c')
-rw-r--r--Build/source/texk/dvipdfm-x/pdfximage.c245
1 files changed, 180 insertions, 65 deletions
diff --git a/Build/source/texk/dvipdfm-x/pdfximage.c b/Build/source/texk/dvipdfm-x/pdfximage.c
index be8e9a4da55..27894763c4b 100644
--- a/Build/source/texk/dvipdfm-x/pdfximage.c
+++ b/Build/source/texk/dvipdfm-x/pdfximage.c
@@ -37,6 +37,8 @@
#include "pdfdoc.h"
#include "pdfdev.h"
#include "pdfdraw.h"
+#include "pdfnames.h"
+#include "specials.h"
#include "epdf.h"
#include "mpost.h"
@@ -90,9 +92,11 @@ struct pdf_ximage_
struct attr_ attr;
char *filename;
+ char *fullname;
pdf_obj *reference;
pdf_obj *resource;
+ int reserved;
};
@@ -120,12 +124,14 @@ static void
pdf_init_ximage_struct (pdf_ximage *I)
{
I->ident = NULL;
- I->filename = NULL;
+ I->filename = NULL;
+ I->fullname = NULL;
I->subtype = -1;
memset(I->res_name, 0, 16);
I->reference = NULL;
I->resource = NULL;
+ I->reserved = 0;
I->attr.width = I->attr.height = 0;
I->attr.xdensity = I->attr.ydensity = 1.0;
@@ -141,12 +147,12 @@ pdf_init_ximage_struct (pdf_ximage *I)
}
static void
-pdf_set_ximage_tempfile (pdf_ximage *I, const char *filename)
+pdf_set_ximage_tempfile (pdf_ximage *I, const char *fullname)
{
- if (I->filename)
- RELEASE(I->filename);
- I->filename = NEW(strlen(filename)+1, char);
- strcpy(I->filename, filename);
+ if (I->fullname)
+ RELEASE(I->fullname);
+ I->fullname = NEW(strlen(fullname)+1, char);
+ strcpy(I->fullname, fullname);
I->attr.tempfile = 1;
}
@@ -157,6 +163,8 @@ pdf_clean_ximage_struct (pdf_ximage *I)
RELEASE(I->ident);
if (I->filename)
RELEASE(I->filename);
+ if (I->fullname)
+ RELEASE(I->fullname);
if (I->reference)
pdf_release_obj(I->reference);
if (I->resource)
@@ -196,8 +204,8 @@ pdf_close_images (void)
if (dpx_conf.verbose_level > 1 &&
dpx_conf.file.keep_cache != 1)
MESG("pdf_image>> deleting temporary file \"%s\"\n", I->filename);
- dpx_delete_temp_file(I->filename, false); /* temporary filename freed here */
- I->filename = NULL;
+ dpx_delete_temp_file(I->fullname, false); /* temporary filename freed here */
+ I->fullname = NULL;
}
pdf_clean_ximage_struct(I);
}
@@ -253,28 +261,45 @@ source_image_type (FILE *fp)
}
static int
-load_image (const char *ident, const char *fullname, int format, FILE *fp,
+load_image (const char *ident, const char *filename, const char *fullname, int format, FILE *fp,
load_options options)
{
struct ic_ *ic = &_ic;
- int id = -1; /* ret */
+ int id = -1, reserved = 0;
pdf_ximage *I;
- id = ic->count;
- if (ic->count >= ic->capacity) {
- ic->capacity += 16;
- ic->ximages = RENEW(ic->ximages, ic->capacity, pdf_ximage);
- }
-
- I = &ic->ximages[id];
- pdf_init_ximage_struct(I);
if (ident) {
- I->ident = NEW(strlen(ident)+1, char);
- strcpy(I->ident, ident);
+ for (id = 0; id < ic->count; id++) {
+ I = &ic->ximages[id];
+ if (I->ident && !strcmp(ident, I->ident)) {
+ if (I->reserved) {
+ reserved = 1;
+ break;
+ }
+ }
+ }
+ }
+ if (!reserved) {
+ id = ic->count;
+ if (ic->count >= ic->capacity) {
+ ic->capacity += 16;
+ ic->ximages = RENEW(ic->ximages, ic->capacity, pdf_ximage);
+ }
+ I = &ic->ximages[id];
+ pdf_init_ximage_struct(I);
+ if (ident) {
+ I->ident = NEW(strlen(ident)+1, char);
+ strcpy(I->ident, ident);
+ }
+ ic->count++;
+ }
+ if (filename) {
+ I->filename = NEW(strlen(filename)+1, char);
+ strcpy(I->filename, filename);
}
if (fullname) {
- I->filename = NEW(strlen(fullname)+1, char);
- strcpy(I->filename, fullname);
+ I->fullname = NEW(strlen(fullname)+1, char);
+ strcpy(I->fullname, fullname);
}
I->attr.page_no = options.page_no;
@@ -352,8 +377,6 @@ load_image (const char *ident, const char *fullname, int format, FILE *fp,
goto error;
}
- ic->count++;
-
return id;
error:
@@ -371,30 +394,30 @@ int utf8name_failed = 0;
#endif /* WIN32 */
int
-pdf_ximage_findresource (const char *ident, load_options options)
+pdf_ximage_load_image (const char *ident, const char *filename, load_options options)
{
struct ic_ *ic = &_ic;
- int id = -1;
+ int i, id = -1;
pdf_ximage *I;
char *fullname, *f = NULL;
int format;
FILE *fp;
- /* I don't understand why there is comparision against I->attr.dict here...
- * I->attr.dict and options.dict are simply pointers to PDF dictionaries.
- */
- for (id = 0; id < ic->count; id++) {
- I = &ic->ximages[id];
- if (I->ident && !strcmp(ident, I->ident)) {
- f = I->filename;
- if (I->attr.page_no == options.page_no /* Not sure */
- && I->attr.dict == options.dict /* ????? */
- && I->attr.bbox_type == options.bbox_type) {
- return id;
- }
- }
+ for (i = 0; i < ic->count; i++) {
+ I = &ic->ximages[i];
+ if (I->filename && !strcmp(filename, I->filename)) {
+ id = i;
+ break;
}
-
+ }
+ if (id >= 0) {
+ if (I->attr.page_no == options.page_no &&
+ !pdf_compare_object(I->attr.dict, options.dict) && /* ????? */
+ I->attr.bbox_type == options.bbox_type) {
+ return id;
+ }
+ f = I->filename;
+ }
if (f) {
/* we already have converted this file; f is the temporary file name */
fullname = NEW(strlen(f)+1, char);
@@ -404,13 +427,13 @@ pdf_ximage_findresource (const char *ident, load_options options)
#if defined(WIN32)
utf8name_failed = 0;
#endif /* WIN32 */
- fullname = dpx_find_file(ident, "_pic_", "");
+ fullname = dpx_find_file(filename, "_pic_", "");
#if defined(WIN32)
if (!fullname && file_system_codepage != win32_codepage) {
int tmpcp = file_system_codepage;
utf8name_failed = 1;
file_system_codepage = win32_codepage;
- fullname = dpx_find_file(ident, "_pic_", "");
+ fullname = dpx_find_file(filename, "_pic_", "");
file_system_codepage = tmpcp;
}
#endif /* WIN32 */
@@ -418,7 +441,6 @@ pdf_ximage_findresource (const char *ident, load_options options)
#if defined(WIN32)
utf8name_failed = 0;
#endif /* WIN32 */
- WARN("Error locating image file \"%s\"", ident);
return -1;
}
}
@@ -430,7 +452,7 @@ pdf_ximage_findresource (const char *ident, load_options options)
return -1;
}
if (dpx_conf.verbose_level > 0) {
- MESG("(Image:%s", ident);
+ MESG("(Image:%s", filename);
if (dpx_conf.verbose_level > 1)
MESG("[%s]", fullname);
}
@@ -440,7 +462,7 @@ pdf_ximage_findresource (const char *ident, load_options options)
case IMAGE_TYPE_MPS:
if (dpx_conf.verbose_level > 0)
MESG("[MPS]");
- id = mps_include_page(ident, fp);
+ id = mps_include_page(filename, fp);
if (id < 0) {
WARN("Try again with the distiller.");
format = IMAGE_TYPE_EPS;
@@ -448,7 +470,7 @@ pdf_ximage_findresource (const char *ident, load_options options)
} else
break;
default:
- id = load_image(ident, fullname, format, fp, options);
+ id = load_image(ident, filename, fullname, format, fp, options);
break;
}
dpx_fclose(fp);
@@ -459,11 +481,28 @@ pdf_ximage_findresource (const char *ident, load_options options)
MESG(")");
if (id < 0)
- WARN("pdf: image inclusion failed for \"%s\".", ident);
+ WARN("pdf: image inclusion failed for \"%s\".", filename);
return id;
}
+int
+pdf_ximage_findresource (const char *ident)
+{
+ struct ic_ *ic = &_ic;
+ int id = -1;
+ pdf_ximage *I;
+
+ for (id = 0; id < ic->count; id++) {
+ I = &ic->ximages[id];
+ if (I->ident && !strcmp(ident, I->ident)) {
+ return id;
+ }
+ }
+
+ return -1;
+}
+
/* Reference: PDF Reference 1.5 v6, pp.321--322
*
* TABLE 4.42 Additional entries specific to a type 1 form dictionary
@@ -552,8 +591,6 @@ pdf_ximage_set_image (pdf_ximage *I, void *image_info, pdf_obj *resource)
I->attr.xdensity = info->xdensity;
I->attr.ydensity = info->ydensity;
- I->reference = pdf_ref_obj(resource);
-
dict = pdf_stream_dict(resource);
pdf_add_dict(dict, pdf_new_name("Type"), pdf_new_name("XObject"));
pdf_add_dict(dict, pdf_new_name("Subtype"), pdf_new_name("Image"));
@@ -565,6 +602,17 @@ pdf_ximage_set_image (pdf_ximage *I, void *image_info, pdf_obj *resource)
if (I->attr.dict)
pdf_merge_dict(dict, I->attr.dict);
+ if (I->ident) {
+ pdf_names_add_object(global_names, I->ident, strlen(I->ident), pdf_link_obj(resource));
+ if (I->reference)
+ pdf_release_obj(I->reference);
+ /* Need to create object reference before closing it */
+ I->reference = pdf_names_lookup_reference(global_names, I->ident, strlen(I->ident));
+ pdf_names_close_object(global_names, I->ident, strlen(I->ident));
+ I->reserved = 0;
+ } else {
+ I->reference = pdf_ref_obj(resource);
+ }
pdf_release_obj(resource); /* Caller don't know we are using reference. */
I->resource = NULL;
}
@@ -594,8 +642,17 @@ pdf_ximage_set_form (pdf_ximage *I, void *form_info, pdf_obj *resource)
I->attr.bbox.urx = max4(p1.x, p2.x, p3.x, p4.x);
I->attr.bbox.ury = max4(p1.y, p2.y, p3.y, p4.y);
- I->reference = pdf_ref_obj(resource);
-
+ if (I->ident) {
+ pdf_names_add_object(global_names, I->ident, strlen(I->ident), pdf_link_obj(resource));
+ if (I->reference)
+ pdf_release_obj(I->reference);
+ /* Need to create object reference before closing it */
+ I->reference = pdf_names_lookup_reference(global_names, I->ident, strlen(I->ident));
+ pdf_names_close_object(global_names, I->ident, strlen(I->ident));
+ I->reserved = 0;
+ } else {
+ I->reference = pdf_ref_obj(resource);
+ }
pdf_release_obj(resource); /* Caller don't know we are using reference. */
I->resource = NULL;
}
@@ -622,7 +679,7 @@ pdf_ximage_get_reference (int id)
CHECK_ID(ic, id);
I = GET_IMAGE(ic, id);
- if (!I->reference)
+ if (!I->reference && I->resource)
I->reference = pdf_ref_obj(I->resource);
return pdf_link_obj(I->reference);
@@ -634,22 +691,33 @@ pdf_ximage_defineresource (const char *ident,
int subtype, void *info, pdf_obj *resource)
{
struct ic_ *ic = &_ic;
- int id;
+ int id, reserved = 0;
pdf_ximage *I;
- id = ic->count;
- if (ic->count >= ic->capacity) {
- ic->capacity += 16;
- ic->ximages = RENEW(ic->ximages, ic->capacity, pdf_ximage);
+ if (ident) {
+ for (id = 0; id < ic->count; id++) {
+ I = &ic->ximages[id];
+ if (I->ident && !strcmp(ident, I->ident) && I->reserved) {
+ reserved = 1;
+ break;
+ }
+ }
}
- I = &ic->ximages[id];
-
- pdf_init_ximage_struct(I);
+ if (!reserved) {
+ id = ic->count;
+ if (ic->count >= ic->capacity) {
+ ic->capacity += 16;
+ ic->ximages = RENEW(ic->ximages, ic->capacity, pdf_ximage);
+ }
+ I = &ic->ximages[id];
+ pdf_init_ximage_struct(I);
- if (ident) {
- I->ident = NEW(strlen(ident)+1, char);
- strcpy(I->ident, ident);
+ if (ident) {
+ I->ident = NEW(strlen(ident)+1, char);
+ strcpy(I->ident, ident);
+ }
+ ic->count++;
}
switch (subtype) {
@@ -664,11 +732,46 @@ pdf_ximage_defineresource (const char *ident,
default:
ERROR("Unknown XObject subtype: %d", subtype);
}
- ic->count++;
return id;
}
+int
+pdf_ximage_reserve (const char *ident)
+{
+ struct ic_ *ic = &_ic;
+ int id;
+ pdf_ximage *I;
+
+ for (id = 0; id < ic->count; id++) {
+ I = &ic->ximages[id];
+ if (I->ident && !strcmp(ident, I->ident)) {
+ WARN("XObject ID \"%s\" already used!", ident);
+ return -1;
+ }
+ }
+
+ id = ic->count;
+ if (ic->count >= ic->capacity) {
+ ic->capacity += 16;
+ ic->ximages = RENEW(ic->ximages, ic->capacity, pdf_ximage);
+ }
+
+ I = &ic->ximages[id];
+
+ pdf_init_ximage_struct(I);
+
+ if (ident) {
+ I->ident = NEW(strlen(ident)+1, char);
+ strcpy(I->ident, ident);
+ }
+ I->reference = pdf_names_reserve(global_names, ident, strlen(ident));
+ sprintf(I->res_name, "Fm%d", id);
+ I->reserved = 1;
+ ic->count++;
+
+ return id;
+}
char *
pdf_ximage_get_resname (int id)
@@ -908,6 +1011,18 @@ pdf_ximage_scale_image (int id,
r->ury = I->attr.bbox.ury;
}
break;
+ default: /* maybe reserved */
+ if (p->flags & INFO_HAS_USER_BBOX) {
+ r->llx = p->bbox.llx;
+ r->lly = p->bbox.lly;
+ r->urx = p->bbox.urx;
+ r->ury = p->bbox.ury;
+ } else { /* I->attr.bbox from the image bounding box */
+ r->llx = 0.0;
+ r->lly = 0.0;
+ r->urx = 1.0;
+ r->ury = 1.0;
+ }
}
return 0;
@@ -1069,7 +1184,7 @@ pdf_error_cleanup_cache (void)
for (i = 0; i < ic->count; i++) {
I = &ic->ximages[i];
if (I->attr.tempfile) {
- dpx_delete_temp_file(I->filename, false); /* temporary filename freed here */
+ dpx_delete_temp_file(I->fullname, false); /* temporary filename freed here */
}
}
}