[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(&params.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(-)