summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'pdf/pdf_check.c')
-rw-r--r--pdf/pdf_check.c348
1 files changed, 307 insertions, 41 deletions
diff --git a/pdf/pdf_check.c b/pdf/pdf_check.c
index 00933bdf..19a6d957 100644
--- a/pdf/pdf_check.c
+++ b/pdf/pdf_check.c
@@ -66,7 +66,7 @@
* stores all the objects (which we don't want to do because its wasteful) and checking
* to see if its already tested a given resource for spots/transparency.
* This is a temporary allocation, big enough to hold all the objects in the file (1 per bit)
- * each time we have fully checked a resource we add it here, when checking a resoruce we
+ * each time we have fully checked a resource we add it here, when checking a resource we
* first check this list to see if its already been checked, in which case we can skip
* it. When done we release the memory.
*/
@@ -74,6 +74,7 @@ typedef struct {
bool transparent;
bool has_overprint; /* Does it have OP or op in an ExtGState? */
pdf_dict *spot_dict;
+ pdf_array *font_array;
uint32_t size;
byte *CheckedResources;
} pdfi_check_tracker_t;
@@ -84,6 +85,7 @@ static inline bool resource_is_checked(pdfi_check_tracker_t *tracker, pdf_obj *o
{
uint32_t byte_offset;
byte bit_offset;
+ int object_num;
if(tracker->CheckedResources == NULL)
return 0;
@@ -91,14 +93,15 @@ static inline bool resource_is_checked(pdfi_check_tracker_t *tracker, pdf_obj *o
/* objects with object number 0 are directly defined, we can't
* store those so just return immediately
*/
- if (o->object_num > 0 && (o->object_num >> 3) < tracker->size) {
+ object_num = pdf_object_num(o);
+ if (object_num > 0 && (object_num >> 3) < tracker->size) {
/* CheckedResources is a byte array, each byte represents
* 8 objects. So the object number / 8 is the byte offset
* into the array, and then object number % 8 is the bit
* within that byte that we want.
*/
- bit_offset = 0x01 << (o->object_num % 8);
- byte_offset = o->object_num >> 3;
+ bit_offset = 0x01 << (object_num % 8);
+ byte_offset = object_num >> 3;
/* If its already set, then return that. */
if (tracker->CheckedResources[byte_offset] & bit_offset)
@@ -116,12 +119,13 @@ pdfi_check_free_tracker(pdf_context *ctx, pdfi_check_tracker_t *tracker)
{
gs_free_object(ctx->memory, tracker->CheckedResources, "pdfi_check_free_tracker(flags)");
pdfi_countdown(tracker->spot_dict);
+ pdfi_countdown(tracker->font_array);
memset(tracker, 0, sizeof(*tracker));
return 0;
}
static int
-pdfi_check_init_tracker(pdf_context *ctx, pdfi_check_tracker_t *tracker)
+pdfi_check_init_tracker(pdf_context *ctx, pdfi_check_tracker_t *tracker, pdf_array **fonts_array, pdf_array **spot_array)
{
int code = 0;
@@ -136,16 +140,25 @@ pdfi_check_init_tracker(pdf_context *ctx, pdfi_check_tracker_t *tracker)
memset(tracker->CheckedResources, 0x00, tracker->size);
if (ctx->device_state.spot_capable ||
- (ctx->pgs->device->icc_struct->overprint_control) == gs_overprint_control_simulate) {
+ (ctx->pgs->device->icc_struct->overprint_control) == gs_overprint_control_simulate ||
+ spot_array != NULL)
+ {
code = pdfi_dict_alloc(ctx, 32, &tracker->spot_dict);
if (code < 0)
goto cleanup;
pdfi_countup(tracker->spot_dict);
}
+ if (fonts_array != NULL) {
+ code = pdfi_array_alloc(ctx, 0, &tracker->font_array);
+ if (code < 0)
+ goto cleanup;
+ pdfi_countup(tracker->font_array);
+ }
+
return 0;
- cleanup:
+cleanup:
pdfi_check_free_tracker(ctx, tracker);
return code;
}
@@ -164,6 +177,9 @@ static int pdfi_check_ColorSpace_dict(pdf_context *ctx, pdf_dict *cspace_dict,
if (resource_is_checked(tracker, (pdf_obj *)cspace_dict))
return 0;
+ if (pdfi_type_of(cspace_dict) != PDF_DICT)
+ return_error(gs_error_typecheck);
+
if (pdfi_dict_entries(cspace_dict) > 0) {
code = pdfi_loop_detector_mark(ctx); /* Mark the start of the ColorSpace dictionary loop */
if (code < 0)
@@ -197,7 +213,7 @@ static int pdfi_check_ColorSpace_dict(pdf_context *ctx, pdf_dict *cspace_dict,
}
code = pdfi_dict_next(ctx, cspace_dict, &Key, &Value, &index);
- if (code == 0 && Value->type == PDF_ARRAY)
+ if (code == 0 && pdfi_type_of(Value) == PDF_ARRAY)
break;
pdfi_countdown(Key);
Key = NULL;
@@ -235,6 +251,9 @@ static int pdfi_check_Shading(pdf_context *ctx, pdf_obj *shading,
if (code < 0)
return code;
+ if (pdfi_type_of(shading_dict) != PDF_DICT)
+ return_error(gs_error_typecheck);
+
code = pdfi_dict_knownget(ctx, shading_dict, "ColorSpace", (pdf_obj **)&o);
if (code > 0) {
code = pdfi_check_ColorSpace_for_spots(ctx, o, shading_dict, page_dict, tracker->spot_dict);
@@ -257,13 +276,16 @@ static int pdfi_check_Shading_dict(pdf_context *ctx, pdf_dict *shading_dict,
if (resource_is_checked(tracker, (pdf_obj *)shading_dict))
return 0;
+ if (pdfi_type_of(shading_dict) != PDF_DICT)
+ return_error(gs_error_typecheck);
+
if (pdfi_dict_entries(shading_dict) > 0) {
code = pdfi_loop_detector_mark(ctx); /* Mark the start of the Shading dictionary loop */
if (code < 0)
return code;
code = pdfi_dict_first(ctx, shading_dict, &Key, &Value, &index);
- if (code < 0 || !(Value->type == PDF_DICT || Value->type == PDF_STREAM))
+ if (code < 0 || !(pdfi_type_of(Value) == PDF_DICT || pdfi_type_of(Value) == PDF_STREAM))
goto error1;
i = 1;
@@ -290,7 +312,7 @@ static int pdfi_check_Shading_dict(pdf_context *ctx, pdf_dict *shading_dict,
}
code = pdfi_dict_next(ctx, shading_dict, &Key, &Value, &index);
- if (code == 0 && Value->type == PDF_DICT)
+ if (code == 0 && pdfi_type_of(Value) == PDF_DICT)
break;
pdfi_countdown(Key);
Key = NULL;
@@ -326,6 +348,9 @@ static int pdfi_check_XObject(pdf_context *ctx, pdf_dict *xobject, pdf_dict *pag
if (resource_is_checked(tracker, (pdf_obj *)xobject))
return 0;
+ if (pdfi_type_of(xobject) != PDF_DICT)
+ return_error(gs_error_typecheck);
+
code = pdfi_dict_get_type(ctx, xobject, "Subtype", PDF_NAME, (pdf_obj **)&n);
if (code >= 0) {
if (pdfi_name_is((const pdf_name *)n, "Image")) {
@@ -417,6 +442,9 @@ static int pdfi_check_XObject_dict(pdf_context *ctx, pdf_dict *xobject_dict, pdf
if (resource_is_checked(tracker, (pdf_obj *)xobject_dict))
return 0;
+ if (pdfi_type_of(xobject_dict) != PDF_DICT)
+ return_error(gs_error_typecheck);
+
if (pdfi_dict_entries(xobject_dict) > 0) {
code = pdfi_loop_detector_mark(ctx); /* Mark the start of the XObject dictionary loop */
if (code < 0)
@@ -425,7 +453,7 @@ static int pdfi_check_XObject_dict(pdf_context *ctx, pdf_dict *xobject_dict, pdf
code = pdfi_dict_first(ctx, xobject_dict, &Key, &Value, &index);
if (code < 0)
goto error_exit;
- if (Value->type != PDF_STREAM)
+ if (pdfi_type_of(Value) != PDF_STREAM)
goto error_exit;
i = 1;
@@ -457,7 +485,7 @@ static int pdfi_check_XObject_dict(pdf_context *ctx, pdf_dict *xobject_dict, pdf
}
code = pdfi_dict_next(ctx, xobject_dict, &Key, &Value, &index);
- if (code == 0 && Value->type == PDF_STREAM)
+ if (code == 0 && pdfi_type_of(Value) == PDF_STREAM)
break;
pdfi_countdown(Key);
Key = NULL;
@@ -490,6 +518,9 @@ static int pdfi_check_ExtGState(pdf_context *ctx, pdf_dict *extgstate_dict, pdf_
if (resource_is_checked(tracker, (pdf_obj *)extgstate_dict))
return 0;
+ if (pdfi_type_of(extgstate_dict) != PDF_DICT)
+ return_error(gs_error_typecheck);
+
if (pdfi_dict_entries(extgstate_dict) > 0) {
/* See if /OP or /op is true */
code = pdfi_dict_get_bool(ctx, extgstate_dict, "OP", &overprint);
@@ -502,14 +533,16 @@ static int pdfi_check_ExtGState(pdf_context *ctx, pdf_dict *extgstate_dict, pdf_
/* Check SMask */
code = pdfi_dict_knownget(ctx, extgstate_dict, "SMask", &o);
if (code > 0) {
- if (o->type == PDF_NAME) {
- if (!pdfi_name_is((pdf_name *)o, "None")) {
- pdfi_countdown(o);
- tracker->transparent = true;
- return 0;
- }
- } else {
- if (o->type == PDF_DICT) {
+ switch (pdfi_type_of(o)) {
+ case PDF_NAME:
+ if (!pdfi_name_is((pdf_name *)o, "None")) {
+ pdfi_countdown(o);
+ tracker->transparent = true;
+ return 0;
+ }
+ break;
+ case PDF_DICT:
+ {
pdf_obj *G = NULL;
tracker->transparent = true;
@@ -526,6 +559,8 @@ static int pdfi_check_ExtGState(pdf_context *ctx, pdf_dict *extgstate_dict, pdf_
pdfi_countdown(o);
return code;
}
+ default:
+ break;
}
}
pdfi_countdown(o);
@@ -577,6 +612,9 @@ static int pdfi_check_ExtGState_dict(pdf_context *ctx, pdf_dict *extgstate_dict,
if (resource_is_checked(tracker, (pdf_obj *)extgstate_dict))
return 0;
+ if (pdfi_type_of(extgstate_dict) != PDF_DICT)
+ return_error(gs_error_typecheck);
+
if (pdfi_dict_entries(extgstate_dict) > 0) {
code = pdfi_loop_detector_mark(ctx); /* Mark the start of the ColorSpace dictionary loop */
if (code < 0)
@@ -611,7 +649,7 @@ static int pdfi_check_ExtGState_dict(pdf_context *ctx, pdf_dict *extgstate_dict,
}
code = pdfi_dict_next(ctx, extgstate_dict, &Key, &Value, &index);
- if (code == 0 && Value->type == PDF_DICT)
+ if (code == 0 && pdfi_type_of(Value) == PDF_DICT)
break;
pdfi_countdown(Key);
Key = NULL;
@@ -644,6 +682,9 @@ static int pdfi_check_Pattern(pdf_context *ctx, pdf_dict *pattern, pdf_dict *pag
if (resource_is_checked(tracker, (pdf_obj *)pattern))
return 0;
+ if (pdfi_type_of(pattern) != PDF_DICT)
+ return_error(gs_error_typecheck);
+
if (tracker->spot_dict != NULL) {
code = pdfi_dict_knownget(ctx, pattern, "Shading", &o);
if (code > 0)
@@ -677,7 +718,7 @@ int pdfi_check_Pattern_transparency(pdf_context *ctx, pdf_dict *pattern, pdf_dic
bool *transparent)
{
int code;
- pdfi_check_tracker_t tracker = {0, 0, NULL, 0, NULL};
+ pdfi_check_tracker_t tracker = {0, 0, NULL, NULL, 0, NULL};
/* NOTE: We use a "null" tracker that won't do any optimization to prevent
* checking the same resource twice.
@@ -708,6 +749,9 @@ static int pdfi_check_Pattern_dict(pdf_context *ctx, pdf_dict *pattern_dict, pdf
if (resource_is_checked(tracker, (pdf_obj *)pattern_dict))
return 0;
+ if (pdfi_type_of(pattern_dict) != PDF_DICT)
+ return_error(gs_error_typecheck);
+
if (pdfi_dict_entries(pattern_dict) > 0) {
code = pdfi_loop_detector_mark(ctx); /* Mark the start of the Pattern dictionary loop */
if (code < 0)
@@ -717,7 +761,7 @@ static int pdfi_check_Pattern_dict(pdf_context *ctx, pdf_dict *pattern_dict, pdf
if (code < 0)
goto error1;
- if(Value->type != PDF_DICT && Value->type != PDF_STREAM)
+ if (pdfi_type_of(Value) != PDF_DICT && pdfi_type_of(Value) != PDF_STREAM)
goto transparency_exit;
i = 1;
@@ -748,7 +792,7 @@ static int pdfi_check_Pattern_dict(pdf_context *ctx, pdf_dict *pattern_dict, pdf
}
code = pdfi_dict_next(ctx, pattern_dict, &Key, &Value, &index);
- if (code == 0 && (Value->type == PDF_DICT || Value->type == PDF_STREAM))
+ if (code == 0 && (pdfi_type_of(Value) == PDF_DICT || pdfi_type_of(Value) == PDF_STREAM))
break;
pdfi_countdown(Key);
Key = NULL;
@@ -771,7 +815,8 @@ error1:
/*
* This routine checks a Font dictionary to see if it contains any spot
- * colour definitions, or transparency usage.
+ * colour definitions, or transparency usage. While we are here, if the tracker's font_array
+ * is not NULL, pick up the font information and store it in the array.
*/
static int pdfi_check_Font(pdf_context *ctx, pdf_dict *font, pdf_dict *page_dict,
pdfi_check_tracker_t *tracker)
@@ -782,22 +827,186 @@ static int pdfi_check_Font(pdf_context *ctx, pdf_dict *font, pdf_dict *page_dict
if (resource_is_checked(tracker, (pdf_obj *)font))
return 0;
- if (font->type != PDF_DICT)
+ if (pdfi_type_of(font) != PDF_DICT)
return_error(gs_error_typecheck);
- code = pdfi_dict_knownget_type(ctx, font, "Subtype", PDF_NAME, &o);
- if (code > 0) {
- if (pdfi_name_is((pdf_name *)o, "Type3")) {
- pdfi_countdown(o);
- o = NULL;
+ if (tracker->font_array != NULL) {
+ /* If we get to here this is a font we have not seen before. We need
+ * to make a new font array big enough to hold the existing entries +1
+ * copy the existing entries to the new array and free the old array.
+ * Finally create a dictionary with all the font information we want
+ * and add it to the array.
+ */
+ pdf_array *new_fonts = NULL;
+ int index = 0;
+ pdf_obj *array_obj = NULL;
+ pdf_dict *font_info_dict = NULL;
- code = pdfi_dict_knownget_type(ctx, font, "Resources", PDF_DICT, &o);
- if (code > 0)
- (void)pdfi_check_Resources(ctx, (pdf_dict *)o, page_dict, tracker);
+ /* Let's start by gathering the information we need and storing it in a dictionary */
+ code = pdfi_dict_alloc(ctx, 4, &font_info_dict);
+ if (code < 0)
+ return code;
+ pdfi_countup(font_info_dict);
+
+ if (font->object_num != 0) {
+ pdf_num *int_obj = NULL;
+
+ code = pdfi_object_alloc(ctx, PDF_INT, 0, (pdf_obj **)&int_obj);
+ if (code >= 0) {
+ pdfi_countup(int_obj);
+ int_obj->value.i = font->object_num;
+ code = pdfi_dict_put(ctx, font_info_dict, "ObjectNum", (pdf_obj *)int_obj);
+ pdfi_countdown(int_obj);
+ }
+ if (code < 0) {
+ pdfi_countdown(font_info_dict);
+ return code;
+ }
+ }
+
+ code = pdfi_dict_get(ctx, font, "BaseFont", &array_obj);
+ if (code >= 0) {
+ code = pdfi_dict_put(ctx, font_info_dict, "BaseFont", array_obj);
+ if (code < 0) {
+ pdfi_countdown(array_obj);
+ pdfi_countdown(font_info_dict);
+ return code;
+ }
+ }
+ pdfi_countdown(array_obj);
+ array_obj = NULL;
+
+ code = pdfi_dict_get(ctx, font, "ToUnicode", &array_obj);
+ if (code >= 0)
+ code = pdfi_dict_put(ctx, font_info_dict, "ToUnicode", PDF_TRUE_OBJ);
+ else
+ code = pdfi_dict_put(ctx, font_info_dict, "ToUnicode", PDF_FALSE_OBJ);
+ pdfi_countdown(array_obj);
+ array_obj = NULL;
+ if (code < 0)
+ return code;
+
+ code = pdfi_dict_get(ctx, font, "FontDescriptor", &array_obj);
+ if (code >= 0) {
+ bool known = false;
+
+ (void)pdfi_dict_known(ctx, (pdf_dict *)array_obj, "FontFile", &known);
+ if (!known) {
+ (void)pdfi_dict_known(ctx, (pdf_dict *)array_obj, "FontFile2", &known);
+ if (!known) {
+ (void)pdfi_dict_known(ctx, (pdf_dict *)array_obj, "FontFile3", &known);
+ }
+ }
+
+ if (known >= 0)
+ code = pdfi_dict_put(ctx, font_info_dict, "Embedded", PDF_TRUE_OBJ);
+ else
+ code = pdfi_dict_put(ctx, font_info_dict, "Embedded", PDF_FALSE_OBJ);
+ } else
+ code = pdfi_dict_put(ctx, font_info_dict, "Embedded", PDF_FALSE_OBJ);
+
+ pdfi_countdown(array_obj);
+ array_obj = NULL;
+
+ if (code < 0)
+ return code;
+
+
+ code = pdfi_dict_knownget_type(ctx, font, "Subtype", PDF_NAME, &array_obj);
+ if (code >= 0) {
+ code = pdfi_dict_put(ctx, font_info_dict, "Subtype", array_obj);
+ if (code < 0) {
+ pdfi_countdown(array_obj);
+ pdfi_countdown(font_info_dict);
+ return code;
+ }
+
+ if (pdfi_name_is((pdf_name *)array_obj, "Type3")) {
+ pdfi_countdown(o);
+ o = NULL;
+
+ code = pdfi_dict_knownget_type(ctx, font, "Resources", PDF_DICT, &o);
+ if (code > 0)
+ (void)pdfi_check_Resources(ctx, (pdf_dict *)o, page_dict, tracker);
+ }
+
+ if (pdfi_name_is((const pdf_name *)array_obj, "Type0")){
+ pdf_array *descendants = NULL;
+ pdf_dict *desc_font = NULL;
+
+ code = pdfi_dict_get(ctx, font, "DescendantFonts", (pdf_obj **)&descendants);
+ if (code >= 0) {
+ code = pdfi_array_get(ctx, descendants, 0, (pdf_obj **)&desc_font);
+ if (code >= 0){
+ pdf_array *desc_array = NULL;
+
+ code = pdfi_array_alloc(ctx, 0, &desc_array);
+ pdfi_countup(desc_array);
+ if (code >= 0) {
+ pdf_array *saved = tracker->font_array;
+
+ tracker->font_array = desc_array;
+ (void)pdfi_check_Font(ctx, desc_font, page_dict, tracker);
+ (void)pdfi_dict_put(ctx, font_info_dict, "Descendants", (pdf_obj *)tracker->font_array);
+ pdfi_countdown((pdf_obj *)tracker->font_array);
+ tracker->font_array = saved;
+ }
+ pdfi_countdown(descendants);
+ pdfi_countdown(desc_font);
+ }
+ }
+ }
+ }
+ pdfi_countdown(array_obj);
+ array_obj = NULL;
+
+ code = pdfi_array_alloc(ctx, pdfi_array_size(tracker->font_array) + 1, &new_fonts);
+ if (code < 0) {
+ pdfi_countdown(font_info_dict);
+ return code;
+ }
+ pdfi_countup(new_fonts);
+
+ for (index = 0; index < pdfi_array_size(tracker->font_array); index++) {
+ code = pdfi_array_get(ctx, tracker->font_array, index, &array_obj);
+ if (code < 0) {
+ pdfi_countdown(font_info_dict);
+ pdfi_countdown(new_fonts);
+ return code;
+ }
+ code = pdfi_array_put(ctx, new_fonts, index, array_obj);
+ pdfi_countdown(array_obj);
+ if (code < 0) {
+ pdfi_countdown(font_info_dict);
+ pdfi_countdown(new_fonts);
+ return code;
+ }
+ }
+ code = pdfi_array_put(ctx, new_fonts, index, (pdf_obj *)font_info_dict);
+ if (code < 0) {
+ pdfi_countdown(font_info_dict);
+ pdfi_countdown(new_fonts);
+ return code;
}
+ pdfi_countdown(font_info_dict);
+ pdfi_countdown(tracker->font_array);
+ tracker->font_array = new_fonts;
+ } else {
+ code = pdfi_dict_knownget_type(ctx, font, "Subtype", PDF_NAME, &o);
+ if (code > 0) {
+ if (pdfi_name_is((pdf_name *)o, "Type3")) {
+ pdfi_countdown(o);
+ o = NULL;
+
+ code = pdfi_dict_knownget_type(ctx, font, "Resources", PDF_DICT, &o);
+ if (code > 0)
+ (void)pdfi_check_Resources(ctx, (pdf_dict *)o, page_dict, tracker);
+ }
+ }
+
+ pdfi_countdown(o);
+ o = NULL;
}
- pdfi_countdown(o);
- o = NULL;
return 0;
}
@@ -815,6 +1024,9 @@ static int pdfi_check_Font_dict(pdf_context *ctx, pdf_dict *font_dict, pdf_dict
if (resource_is_checked(tracker, (pdf_obj *)font_dict))
return 0;
+ if (pdfi_type_of(font_dict) != PDF_DICT)
+ return_error(gs_error_typecheck);
+
if (pdfi_dict_entries(font_dict) > 0) {
code = pdfi_loop_detector_mark(ctx); /* Mark the start of the Font dictionary loop */
if (code < 0)
@@ -846,7 +1058,7 @@ static int pdfi_check_Font_dict(pdf_context *ctx, pdf_dict *font_dict, pdf_dict
}
code = pdfi_dict_next(ctx, font_dict, &Key, &Value, &index);
- if (code == 0 && Value->type == PDF_DICT)
+ if (code == 0 && pdfi_type_of(Value) == PDF_DICT)
break;
pdfi_countdown(Key);
Key = NULL;
@@ -875,6 +1087,9 @@ static int pdfi_check_Resources(pdf_context *ctx, pdf_dict *Resources_dict,
if (resource_is_checked(tracker, (pdf_obj *)Resources_dict))
return 0;
+ if (pdfi_type_of(Resources_dict) != PDF_DICT)
+ return_error(gs_error_typecheck);
+
/* First up, check any colour spaces, for new spot colours.
* We only do this if asked because its expensive. spot_dict being NULL
* means we aren't interested in spot colours (not a DeviceN or Separation device)
@@ -937,6 +1152,9 @@ static int pdfi_check_annot_for_transparency(pdf_context *ctx, pdf_dict *annot,
if (resource_is_checked(tracker, (pdf_obj *)annot))
return 0;
+ if (pdfi_type_of(annot) != PDF_DICT)
+ return_error(gs_error_typecheck);
+
/* Check #1 Does the (Normal) Appearnce stream use any Resources which include transparency.
* We check this first, because this also checks for spot colour spaces. Once we've done that we
* can exit the checks as soon as we detect transparency.
@@ -1035,6 +1253,9 @@ static int pdfi_check_Annots_for_transparency(pdf_context *ctx, pdf_array *annot
if (resource_is_checked(tracker, (pdf_obj *)annots_array))
return 0;
+ if (pdfi_type_of(annots_array) != PDF_ARRAY)
+ return_error(gs_error_typecheck);
+
for (i=0; i < pdfi_array_size(annots_array); i++) {
code = pdfi_array_get_type(ctx, annots_array, (uint64_t)i, PDF_DICT, (pdf_obj **)&annot);
if (code >= 0) {
@@ -1084,6 +1305,10 @@ static int pdfi_check_page_inner(pdf_context *ctx, pdf_dict *page_dict,
tracker->transparent = false;
+ if (pdfi_type_of(page_dict) != PDF_DICT)
+ return_error(gs_error_typecheck);
+
+
/* Check if the page dictionary has a page Group entry (for spots).
* Page group should mean the page has transparency but we ignore it for the purposes
* of transparency detection. See above.
@@ -1104,7 +1329,7 @@ static int pdfi_check_page_inner(pdf_context *ctx, pdf_dict *page_dict,
code = pdfi_dict_knownget_type(ctx, page_dict, "Resources", PDF_DICT, (pdf_obj **)&Resources);
if (code > 0)
code = pdfi_check_Resources(ctx, Resources, page_dict, tracker);
- if ((code < 0 && ctx->args.pdfstoponerror) || (code == gs_error_stackoverflow))
+ if ((code < 0 && ctx->args.pdfstoponerror) || (code == gs_error_pdf_stackoverflow))
goto exit;
/* If we are drawing Annotations, check to see if the page uses any Annots */
@@ -1130,7 +1355,7 @@ static int pdfi_check_page_inner(pdf_context *ctx, pdf_dict *page_dict,
* Sets ctx->page.has_transparency and ctx->page.num_spots
* do_setup -- indicates whether to actually set up the device with the spot count.
*/
-int pdfi_check_page(pdf_context *ctx, pdf_dict *page_dict, bool do_setup)
+int pdfi_check_page(pdf_context *ctx, pdf_dict *page_dict, pdf_array **fonts_array, pdf_array **spots_array, bool do_setup)
{
int code;
int spots = 0;
@@ -1145,7 +1370,7 @@ int pdfi_check_page(pdf_context *ctx, pdf_dict *page_dict, bool do_setup)
* TODO: Should probably look into that..
*/
pdfi_device_set_flags(ctx);
- code = pdfi_check_init_tracker(ctx, &tracker);
+ code = pdfi_check_init_tracker(ctx, &tracker, fonts_array, spots_array);
if (code < 0)
goto exit;
@@ -1191,7 +1416,7 @@ int pdfi_check_page(pdf_context *ctx, pdf_dict *page_dict, bool do_setup)
code = pdfi_dict_first(ctx, tracker.spot_dict, (pdf_obj **)&Key, &Value, &index);
while (code >= 0)
{
- if (Key->type == PDF_NAME) {
+ if (pdfi_type_of(Key) == PDF_NAME) {
table[a].data = ((pdf_string *)Key)->data;
table[a].size = ((pdf_string *)Key)->length;
table[a++].persistent = false;
@@ -1263,6 +1488,47 @@ int pdfi_check_page(pdf_context *ctx, pdf_dict *page_dict, bool do_setup)
ctx->page.has_OP = false;
exit:
+ if (fonts_array != NULL) {
+ *fonts_array = tracker.font_array;
+ pdfi_countup(*fonts_array);
+ }
+
+ if (spots_array != NULL && tracker.spot_dict != NULL && pdfi_dict_entries(tracker.spot_dict) != 0) {
+ pdf_array *new_array = NULL;
+ pdf_name *Key = NULL;
+ pdf_obj *Value = NULL;
+ uint64_t index = 0, a_index = 0;
+
+ index = pdfi_dict_entries(tracker.spot_dict);
+
+ code = pdfi_array_alloc(ctx, index, &new_array);
+ if (code < 0)
+ goto error;
+ pdfi_countup(new_array);
+
+ code = pdfi_dict_first(ctx, tracker.spot_dict, (pdf_obj **)&Key, &Value, &index);
+ while (code >= 0)
+ {
+ if (pdfi_type_of(Key) == PDF_NAME) {
+ code = pdfi_array_put(ctx, new_array, a_index++, (pdf_obj *)Key);
+ if (code < 0) {
+ pdfi_countdown(new_array);
+ pdfi_countdown(Key);
+ pdfi_countdown(Value);
+ goto error;
+ }
+ }
+
+ pdfi_countdown(Key);
+ Key = NULL;
+ pdfi_countdown(Value);
+ Value = NULL;
+ code = pdfi_dict_next(ctx, tracker.spot_dict, (pdf_obj **)&Key, &Value, &index);
+ }
+ code = 0;
+ *spots_array = new_array;
+ }
+error:
(void)pdfi_check_free_tracker(ctx, &tracker);
return code;
}