[gs-commits] ghostpdl branch, pdfi, updated. jbig2dec-0.14-2646-g100783e
[email protected] (Nancy Durgin) Tue, 10 Dec 2019 20:30:00 +0000 (UTC)
| Newsgroups | gmane.comp.printing.ghostscript.cvs |
|---|---|
| Message-ID | <[email protected]> |
The ghostpdl branch, pdfi has been updated
via 100783e3848941b7cb2ebf46e3b41e625a36c38a (commit)
from bb8b501e7a13c40d2590d6bb03afbcef043d5028 (commit)
----------------------------------------------------------------------
commit 100783e3848941b7cb2ebf46e3b41e625a36c38a
Author: Nancy Durgin <[email protected]>
Date: Tue Dec 10 08:11:17 2019 -0800
Add funcs to deal with stream Length, and use them.
This adds a Length to the pdf_dict type, and since dicts are created
in various ways I decided to do a lazy evaluation, which means we also
need to keep track of whether Length is valid.
The is_stream flag indicates whether there was a Length key or not.
A Length of 0 means either there was no Length key, or it's a
zero-length stream, which either way the user can probably make sense
of.
Also cleaned up error handling in pdfi_create_iccbased() which would have
had a memory leak.
Also fixed bug in pdfi_build_function_0() where 'code' was being checked
instead of 'Length'. Would have only mattered if there was an error.
diff --git a/pdf/pdf_colour.c b/pdf/pdf_colour.c
index 690c875..1433059 100644
--- a/pdf/pdf_colour.c
+++ b/pdf/pdf_colour.c
@@ -971,13 +971,14 @@ static int pdfi_create_iccbased(pdf_context *ctx, pdf_array *color_array, int in
if (code < 0)
return code;
- code = pdfi_dict_get_int(ctx, ICC_dict, "Length", &Length);
- if (code < 0)
- return code;
+ if (!pdfi_dict_is_stream(ctx, ICC_dict)) {
+ gs_note_error(gs_error_undefined);
+ goto done;
+ }
+ Length = pdfi_dict_stream_length(ctx, ICC_dict);
code = pdfi_dict_get_int(ctx, ICC_dict, "N", &N);
- if (code < 0) {
- return code;
- }
+ if (code < 0)
+ goto done;
code = pdfi_dict_knownget(ctx, ICC_dict, "Name", &Name);
if (code > 0) {
if(Name->type == PDF_STRING || Name->type == PDF_NAME) {
@@ -992,12 +993,11 @@ static int pdfi_create_iccbased(pdf_context *ctx, pdf_array *color_array, int in
pdfi_countdown(Name);
}
if (code < 0)
- return code;
-
+ goto done;
code = pdfi_dict_knownget_type(ctx, ICC_dict, "Range", PDF_ARRAY, (pdf_obj **)&a);
if (code < 0)
- return code;
+ goto done;
if (code > 0) {
double dbl;
int i;
diff --git a/pdf/pdf_dict.c b/pdf/pdf_dict.c
index 7ab3dd0..1b8a928 100644
--- a/pdf/pdf_dict.c
+++ b/pdf/pdf_dict.c
@@ -826,3 +826,49 @@ int pdfi_merge_dicts(pdf_dict *target, pdf_dict *source)
}
return 0;
}
+
+/* Check if dict is a stream
+ * It's a stream if it has a Length key
+ * Not a stream if it has no Length, or some other error happened when looking it up.
+ *
+ * Since dicts get created in various ways, we do a lazy-evaluation on whether there is a
+ * Length key, then cache it in the object so we don't have to check next time.
+ */
+bool pdfi_dict_is_stream(pdf_context *ctx, pdf_dict *d)
+{
+ int64_t Length = 0;
+ int code;
+
+ if (d->length_valid)
+ goto exit;
+
+ code = pdfi_dict_get_int(ctx, d, "Length", &Length);
+ if (code < 0) {
+ /* Includes undefined */
+ d->is_stream = false;
+ } else {
+ d->is_stream = true;
+ }
+
+ /* Make sure Length is not negative... */
+ if (Length < 0)
+ Length = 0;
+
+ /* Cache it */
+ d->Length = Length;
+ d->length_valid = true;
+
+ exit:
+ return d->is_stream;
+}
+
+/* Return Length of a stream, or 0 if it's not a stream
+ * Note that a stream is just a dict with a Length.
+ */
+int64_t pdfi_dict_stream_length(pdf_context *ctx, pdf_dict *d)
+{
+ if (pdfi_dict_is_stream(ctx, d))
+ return d->Length;
+ else
+ return 0;
+}
diff --git a/pdf/pdf_dict.h b/pdf/pdf_dict.h
index 58691f3..cddb1e9 100644
--- a/pdf/pdf_dict.h
+++ b/pdf/pdf_dict.h
@@ -55,5 +55,7 @@ int pdfi_dict_copy(pdf_dict *target, pdf_dict *source);
int pdfi_alloc_dict(pdf_context *ctx, uint64_t size, pdf_dict **returned);
int pdfi_dict_next(pdf_context *ctx, pdf_dict *d, pdf_obj **Key, pdf_obj **Value, void *index);
int pdfi_dict_first(pdf_context *ctx, pdf_dict *d, pdf_obj **Key, pdf_obj **Value, void *index);
+bool pdfi_dict_is_stream(pdf_context *ctx, pdf_dict *d);
+int64_t pdfi_dict_stream_length(pdf_context *ctx, pdf_dict *d);
#endif
diff --git a/pdf/pdf_file.c b/pdf/pdf_file.c
index 904d18f..db70947 100644
--- a/pdf/pdf_file.c
+++ b/pdf/pdf_file.c
@@ -1301,9 +1301,11 @@ pdfi_stream_to_buffer(pdf_context *ctx, pdf_dict *stream_dict, byte **buf, int64
} while (bytes >= 0);
pdfi_close_file(ctx, stream);
} else {
- code = pdfi_dict_get_int(ctx, stream_dict, "Length", &buflen);
- if (code < 0)
+ if (!pdfi_dict_is_stream(ctx, stream_dict)) {
+ code = gs_note_error(gs_error_undefined);
goto exit;
+ }
+ buflen = pdfi_dict_stream_length(ctx, stream_dict);
}
/* Alloc buffer */
diff --git a/pdf/pdf_func.c b/pdf/pdf_func.c
index 5e92ee0..ebe7dd8 100644
--- a/pdf/pdf_func.c
+++ b/pdf/pdf_func.c
@@ -291,9 +291,9 @@ pdfi_build_function_4(pdf_context *ctx, gs_function_params_t * mnDR,
params.ops.data = 0; /* in case of failure */
params.ops.size = 0; /* ditto */
- code = pdfi_dict_get_int(ctx, function_dict, "Length", &Length);
- if (code < 0)
- return code;
+ if (!pdfi_dict_is_stream(ctx, function_dict))
+ return_error(gs_error_undefined);
+ Length = pdfi_dict_stream_length(ctx, function_dict);
savedoffset = pdfi_tell(ctx->main_stream);
code = pdfi_seek(ctx, ctx->main_stream, function_dict->stream_offset, SEEK_SET);
@@ -359,7 +359,7 @@ pdfi_build_function_0(pdf_context *ctx, gs_function_params_t * mnDR,
{
gs_function_Sd_params_t params;
pdf_stream *function_stream = NULL;
- int code;
+ int code = 0;
int64_t Length, temp;
byte *data_source_buffer;
gs_offset_t savedoffset;
@@ -371,17 +371,17 @@ pdfi_build_function_0(pdf_context *ctx, gs_function_params_t * mnDR,
params.Size = params.array_step = params.stream_step = NULL;
params.Order = 0;
- code = pdfi_dict_get_int(ctx, function_dict, "Length", &Length);
- if (code < 0)
- return code;
+ if (!pdfi_dict_is_stream(ctx, function_dict))
+ return_error(gs_error_undefined);
+ Length = pdfi_dict_stream_length(ctx, function_dict);
savedoffset = pdfi_tell(ctx->main_stream);
pdfi_seek(ctx, ctx->main_stream, function_dict->stream_offset, SEEK_SET);
Length = pdfi_open_memory_stream_from_filtered_stream(ctx, function_dict, (unsigned int)Length, &data_source_buffer, ctx->main_stream, &function_stream);
- if (code < 0) {
+ if (Length < 0) {
pdfi_seek(ctx, ctx->main_stream, savedoffset, SEEK_SET);
- return code;
+ return Length;
}
data_source_init_stream(¶ms.DataSource, function_stream->s);
diff --git a/pdf/pdf_image.c b/pdf/pdf_image.c
index 4f7a6b5..bf5a66c 100644
--- a/pdf/pdf_image.c
+++ b/pdf/pdf_image.c
@@ -437,13 +437,8 @@ pdfi_get_image_info(pdf_context *ctx, pdf_dict *image_dict,
/* Not Handled: "ID", "OPI" */
- /* Length if it's in a stream dict (?) */
- code = pdfi_dict_get_int(ctx, image_dict, "Length", &info->Length);
- if (code != 0) {
- if (code != gs_error_undefined)
- goto errorExit;
- info->Length = 0;
- }
+ /* Length if it's in a stream dict */
+ info->Length = pdfi_dict_stream_length(ctx, image_dict);
/* Required */
code = pdfi_dict_get_number2(ctx, image_dict, "Height", "H", &temp_f);
diff --git a/pdf/pdf_shading.c b/pdf/pdf_shading.c
index 6216203..5c71687 100644
--- a/pdf/pdf_shading.c
+++ b/pdf/pdf_shading.c
@@ -262,9 +262,9 @@ static int pdfi_build_mesh_shading(pdf_context *ctx, gs_shading_mesh_params_t *p
if (shading_dict->stream_offset == 0)
return_error(gs_error_typecheck);
- code = pdfi_dict_get_int(ctx, shading_dict, "Length", &Length);
- if (code < 0)
- return code;
+ if (!pdfi_dict_is_stream(ctx, shading_dict))
+ return_error(gs_error_undefined);
+ Length = pdfi_dict_stream_length(ctx, shading_dict);
savedoffset = pdfi_tell(ctx->main_stream);
code = pdfi_seek(ctx, ctx->main_stream, shading_dict->stream_offset, SEEK_SET);
diff --git a/pdf/pdf_types.h b/pdf/pdf_types.h
index 98cb06c..a615044 100644
--- a/pdf/pdf_types.h
+++ b/pdf/pdf_types.h
@@ -124,6 +124,9 @@ typedef struct pdf_dict_s {
pdf_obj **keys;
pdf_obj **values;
gs_offset_t stream_offset;
+ int64_t Length; /* Value of Length in dict, 0 if undefined. non-zero means it's a stream */
+ bool is_stream; /* True if it has a Length param */
+ bool length_valid; /* True if Length and is_stream have been cached above */
} pdf_dict;
typedef struct pdf_indirect_ref_s {
Summary of changes:
pdf/pdf_colour.c | 18 +++++++++---------
pdf/pdf_dict.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
pdf/pdf_dict.h | 2 ++
pdf/pdf_file.c | 6 ++++--
pdf/pdf_func.c | 18 +++++++++---------
pdf/pdf_image.c | 9 ++-------
pdf/pdf_shading.c | 6 +++---
pdf/pdf_types.h | 3 +++
8 files changed, 78 insertions(+), 30 deletions(-)