summaryrefslogtreecommitdiff
path: root/source/pdf/pdf-xref.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/pdf/pdf-xref.c')
-rw-r--r--source/pdf/pdf-xref.c1072
1 files changed, 552 insertions, 520 deletions
diff --git a/source/pdf/pdf-xref.c b/source/pdf/pdf-xref.c
index 5308a272..586aab2d 100644
--- a/source/pdf/pdf-xref.c
+++ b/source/pdf/pdf-xref.c
@@ -20,9 +20,8 @@ static inline int iswhite(int ch)
* xref tables
*/
-static void pdf_free_xref_sections(pdf_document *doc)
+static void pdf_drop_xref_sections(fz_context *ctx, pdf_document *doc)
{
- fz_context *ctx = doc->ctx;
int x, e;
for (x = 0; x < doc->num_xref_sections; x++)
@@ -39,7 +38,7 @@ static void pdf_free_xref_sections(pdf_document *doc)
if (entry->obj)
{
- pdf_drop_obj(entry->obj);
+ pdf_drop_obj(ctx, entry->obj);
fz_drop_buffer(ctx, entry->stm_buf);
}
}
@@ -48,8 +47,8 @@ static void pdf_free_xref_sections(pdf_document *doc)
sub = next_sub;
}
- pdf_drop_obj(xref->pre_repair_trailer);
- pdf_drop_obj(xref->trailer);
+ pdf_drop_obj(ctx, xref->pre_repair_trailer);
+ pdf_drop_obj(ctx, xref->trailer);
}
fz_free(ctx, doc->xref_sections);
@@ -57,6 +56,19 @@ static void pdf_free_xref_sections(pdf_document *doc)
doc->num_xref_sections = 0;
}
+static void
+extend_xref_index(fz_context *ctx, pdf_document *doc, int newlen)
+{
+ int i;
+
+ doc->xref_index = fz_resize_array(ctx, doc->xref_index, newlen, sizeof(int));
+ for (i = doc->max_xref_len; i < newlen; i++)
+ {
+ doc->xref_index[i] = 0;
+ }
+ doc->max_xref_len = newlen;
+}
+
/* This is only ever called when we already have an incremental
* xref. This means there will only be 1 subsec, and it will be
* a complete subsec. */
@@ -84,13 +96,13 @@ static void pdf_resize_xref(fz_context *ctx, pdf_document *doc, int newlen)
xref->num_objects = newlen;
sub->len = newlen;
if (doc->max_xref_len < newlen)
- doc->max_xref_len = newlen;
+ extend_xref_index(ctx, doc, newlen);
}
-static void pdf_populate_next_xref_level(pdf_document *doc)
+static void pdf_populate_next_xref_level(fz_context *ctx, pdf_document *doc)
{
pdf_xref *xref;
- doc->xref_sections = fz_resize_array(doc->ctx, doc->xref_sections, doc->num_xref_sections + 1, sizeof(pdf_xref));
+ doc->xref_sections = fz_resize_array(ctx, doc->xref_sections, doc->num_xref_sections + 1, sizeof(pdf_xref));
doc->num_xref_sections++;
xref = &doc->xref_sections[doc->num_xref_sections - 1];
@@ -100,7 +112,7 @@ static void pdf_populate_next_xref_level(pdf_document *doc)
xref->pre_repair_trailer = NULL;
}
-pdf_obj *pdf_trailer(pdf_document *doc)
+pdf_obj *pdf_trailer(fz_context *ctx, pdf_document *doc)
{
/* Return the document's final trailer */
pdf_xref *xref = &doc->xref_sections[0];
@@ -108,19 +120,19 @@ pdf_obj *pdf_trailer(pdf_document *doc)
return xref->trailer;
}
-void pdf_set_populating_xref_trailer(pdf_document *doc, pdf_obj *trailer)
+void pdf_set_populating_xref_trailer(fz_context *ctx, pdf_document *doc, pdf_obj *trailer)
{
/* Update the trailer of the xref section being populated */
pdf_xref *xref = &doc->xref_sections[doc->num_xref_sections - 1];
if (xref->trailer)
{
- pdf_drop_obj(xref->pre_repair_trailer);
+ pdf_drop_obj(ctx, xref->pre_repair_trailer);
xref->pre_repair_trailer = xref->trailer;
}
- xref->trailer = pdf_keep_obj(trailer);
+ xref->trailer = pdf_keep_obj(ctx, trailer);
}
-int pdf_xref_len(pdf_document *doc)
+int pdf_xref_len(fz_context *ctx, pdf_document *doc)
{
return doc->max_xref_len;
}
@@ -128,9 +140,8 @@ int pdf_xref_len(pdf_document *doc)
/* Ensure that the given xref has a single subsection
* that covers the entire range. */
static void
-ensure_solid_xref(pdf_document *doc, int num, int which)
+ensure_solid_xref(fz_context *ctx, pdf_document *doc, int num, int which)
{
- fz_context *ctx = doc->ctx;
pdf_xref *xref = &doc->xref_sections[which];
pdf_xref_subsec *sub = xref->subsec;
pdf_xref_subsec *new_sub;
@@ -174,11 +185,11 @@ ensure_solid_xref(pdf_document *doc, int num, int which)
xref->num_objects = num;
xref->subsec = new_sub;
if (doc->max_xref_len < num)
- doc->max_xref_len = num;
+ extend_xref_index(ctx, doc, num);
}
/* Used while reading the individual xref sections from a file */
-pdf_xref_entry *pdf_get_populating_xref_entry(pdf_document *doc, int num)
+pdf_xref_entry *pdf_get_populating_xref_entry(fz_context *ctx, pdf_document *doc, int num)
{
/* Return an entry within the xref currently being populated */
pdf_xref *xref;
@@ -186,13 +197,13 @@ pdf_xref_entry *pdf_get_populating_xref_entry(pdf_document *doc, int num)
if (doc->num_xref_sections == 0)
{
- doc->xref_sections = fz_calloc(doc->ctx, 1, sizeof(pdf_xref));
+ doc->xref_sections = fz_calloc(ctx, 1, sizeof(pdf_xref));
doc->num_xref_sections = 1;
}
/* Prevent accidental heap underflow */
if (num < 0)
- fz_throw(doc->ctx, FZ_ERROR_GENERIC, "object number must not be negative (%d)", num);
+ fz_throw(ctx, FZ_ERROR_GENERIC, "object number must not be negative (%d)", num);
/* Return the pointer to the entry in the last section. */
xref = &doc->xref_sections[doc->num_xref_sections-1];
@@ -204,7 +215,7 @@ pdf_xref_entry *pdf_get_populating_xref_entry(pdf_document *doc, int num)
}
/* We've been asked for an object that's not in a subsec. */
- ensure_solid_xref(doc, num+1, doc->num_xref_sections-1);
+ ensure_solid_xref(ctx, doc, num+1, doc->num_xref_sections-1);
xref = &doc->xref_sections[doc->num_xref_sections-1];
sub = xref->subsec;
@@ -215,9 +226,8 @@ pdf_xref_entry *pdf_get_populating_xref_entry(pdf_document *doc, int num)
/* This will never throw anything, or return NULL if it is
* only asked to return objects in range within a 'solid'
* xref. */
-pdf_xref_entry *pdf_get_xref_entry(pdf_document *doc, int i)
+pdf_xref_entry *pdf_get_xref_entry(fz_context *ctx, pdf_document *doc, int i)
{
- fz_context *ctx = doc->ctx;
pdf_xref *xref;
pdf_xref_subsec *sub;
int j;
@@ -225,12 +235,17 @@ pdf_xref_entry *pdf_get_xref_entry(pdf_document *doc, int i)
if (i < 0)
fz_throw(ctx, FZ_ERROR_GENERIC, "Negative object number requested");
+ if (i <= doc->max_xref_len)
+ j = doc->xref_index[i];
+ else
+ j = 0;
+
/* Find the first xref section where the entry is defined. */
- for (j = 0; j < doc->num_xref_sections; j++)
+ for (; j < doc->num_xref_sections; j++)
{
xref = &doc->xref_sections[j];
- if (i >= 0 && i < xref->num_objects)
+ if (i < xref->num_objects)
{
for (sub = xref->subsec; sub != NULL; sub = sub->next)
{
@@ -241,13 +256,17 @@ pdf_xref_entry *pdf_get_xref_entry(pdf_document *doc, int i)
entry = &sub->table[i - sub->start];
if (entry->type)
+ {
+ doc->xref_index[i] = j;
return entry;
+ }
}
}
}
/* Didn't find the entry in any section. Return the entry from
* the final section. */
+ doc->xref_index[i] = 0;
if (i < xref->num_objects)
{
xref = &doc->xref_sections[0];
@@ -262,7 +281,7 @@ pdf_xref_entry *pdf_get_xref_entry(pdf_document *doc, int i)
* can return a pointer. This is the only case where this function
* might throw an exception, and it will never happen when we are
* working within a 'solid' xref. */
- ensure_solid_xref(doc, i+1, 0);
+ ensure_solid_xref(ctx, doc, i+1, 0);
xref = &doc->xref_sections[0];
sub = xref->subsec;
return &sub->table[i - sub->start];
@@ -273,9 +292,8 @@ pdf_xref_entry *pdf_get_xref_entry(pdf_document *doc, int i)
updated versions of indirect objects. This is a new xref section
consisting of a single xref subsection.
*/
-static void ensure_incremental_xref(pdf_document *doc)
+static void ensure_incremental_xref(fz_context *ctx, pdf_document *doc)
{
- fz_context *ctx = doc->ctx;
if (!doc->xref_altered)
{
@@ -284,12 +302,13 @@ static void ensure_incremental_xref(pdf_document *doc)
pdf_xref_entry *new_table = fz_calloc(ctx, xref->num_objects, sizeof(pdf_xref_entry));
pdf_xref_subsec *sub;
pdf_obj *trailer = NULL;
+ int i;
fz_var(trailer);
fz_try(ctx)
{
sub = fz_malloc_struct(ctx, pdf_xref_subsec);
- trailer = pdf_copy_dict(xref->trailer);
+ trailer = pdf_copy_dict(ctx, xref->trailer);
doc->xref_sections = fz_resize_array(ctx, doc->xref_sections, doc->num_xref_sections + 1, sizeof(pdf_xref));
xref = &doc->xref_sections[0];
pxref = &doc->xref_sections[1];
@@ -308,21 +327,26 @@ static void ensure_incremental_xref(pdf_document *doc)
fz_catch(ctx)
{
fz_free(ctx, new_table);
- pdf_drop_obj(trailer);
+ pdf_drop_obj(ctx, trailer);
fz_rethrow(ctx);
}
+
+ /* Update the xref_index */
+ for (i = 0; i < doc->max_xref_len; i++)
+ {
+ doc->xref_index[i]++;
+ }
}
}
/* Used when altering a document */
-static pdf_xref_entry *pdf_get_incremental_xref_entry(pdf_document *doc, int i)
+static pdf_xref_entry *pdf_get_incremental_xref_entry(fz_context *ctx, pdf_document *doc, int i)
{
- fz_context *ctx = doc->ctx;
pdf_xref *xref;
pdf_xref_subsec *sub;
/* Make a new final xref section if we haven't already */
- ensure_incremental_xref(doc);
+ ensure_incremental_xref(ctx, doc);
xref = &doc->xref_sections[0];
if (i >= xref->num_objects)
@@ -331,10 +355,11 @@ static pdf_xref_entry *pdf_get_incremental_xref_entry(pdf_document *doc, int i)
sub = xref->subsec;
assert(sub != NULL && sub->next == NULL);
assert(i >= sub->start && i < sub->start + sub->len);
+ doc->xref_index[i] = 0;
return &sub->table[i - sub->start];
}
-int pdf_xref_is_incremental(pdf_document *doc, int num)
+int pdf_xref_is_incremental(fz_context *ctx, pdf_document *doc, int num)
{
pdf_xref *xref = &doc->xref_sections[0];
pdf_xref_subsec *sub = xref->subsec;
@@ -346,26 +371,26 @@ int pdf_xref_is_incremental(pdf_document *doc, int num)
/* Ensure that the current populating xref has a single subsection
* that covers the entire range. */
-void pdf_ensure_solid_xref(pdf_document *doc, int num)
+void pdf_ensure_solid_xref(fz_context *ctx, pdf_document *doc, int num)
{
if (doc->num_xref_sections == 0)
- pdf_populate_next_xref_level(doc);
+ pdf_populate_next_xref_level(ctx, doc);
- ensure_solid_xref(doc, num, doc->num_xref_sections-1);
+ ensure_solid_xref(ctx, doc, num, doc->num_xref_sections-1);
}
/* Ensure that an object has been cloned into the incremental xref section */
-void pdf_xref_ensure_incremental_object(pdf_document *doc, int num)
+void pdf_xref_ensure_incremental_object(fz_context *ctx, pdf_document *doc, int num)
{
pdf_xref_entry *new_entry, *old_entry;
pdf_xref_subsec *sub = NULL;
int i;
/* Make sure we have created an xref section for incremental updates */
- ensure_incremental_xref(doc);
+ ensure_incremental_xref(ctx, doc);
/* Search for the section that contains this object */
- for (i = 0; i < doc->num_xref_sections; i++)
+ for (i = doc->xref_index[num]; i < doc->num_xref_sections; i++)
{
pdf_xref *xref = &doc->xref_sections[i];
@@ -386,28 +411,29 @@ void pdf_xref_ensure_incremental_object(pdf_document *doc, int num)
return;
/* Move the object to the incremental section */
+ doc->xref_index[num] = 0;
old_entry = &sub->table[num - sub->start];
- new_entry = pdf_get_incremental_xref_entry(doc, num);
+ new_entry = pdf_get_incremental_xref_entry(ctx, doc, num);
*new_entry = *old_entry;
old_entry->obj = NULL;
old_entry->stm_buf = NULL;
}
-void pdf_replace_xref(pdf_document *doc, pdf_xref_entry *entries, int n)
+void pdf_replace_xref(fz_context *ctx, pdf_document *doc, pdf_xref_entry *entries, int n)
{
- fz_context *ctx = doc->ctx;
- pdf_xref *xref;
+ pdf_xref *xref = NULL;
pdf_xref_subsec *sub;
- pdf_obj *trailer = pdf_keep_obj(pdf_trailer(doc));
+ pdf_obj *trailer = pdf_keep_obj(ctx, pdf_trailer(ctx, doc));
fz_var(xref);
fz_try(ctx)
{
+ doc->xref_index = fz_calloc(ctx, n, sizeof(int));
xref = fz_malloc_struct(ctx, pdf_xref);
sub = fz_malloc_struct(ctx, pdf_xref_subsec);
/* The new table completely replaces the previous separate sections */
- pdf_free_xref_sections(doc);
+ pdf_drop_xref_sections(ctx, doc);
sub->table = entries;
sub->start = 0;
@@ -420,11 +446,13 @@ void pdf_replace_xref(pdf_document *doc, pdf_xref_entry *entries, int n)
doc->xref_sections = xref;
doc->num_xref_sections = 1;
doc->max_xref_len = n;
+
+ memset(doc->xref_index, 0, sizeof(int)*doc->max_xref_len);
}
fz_catch(ctx)
{
fz_free(ctx, xref);
- pdf_drop_obj(trailer);
+ pdf_drop_obj(ctx, trailer);
fz_rethrow(ctx);
}
}
@@ -434,33 +462,33 @@ void pdf_replace_xref(pdf_document *doc, pdf_xref_entry *entries, int n)
*/
static void
-pdf_load_version(pdf_document *doc)
+pdf_load_version(fz_context *ctx, pdf_document *doc)
{
char buf[20];
- fz_seek(doc->file, 0, SEEK_SET);
- fz_read_line(doc->file, buf, sizeof buf);
+ fz_seek(ctx, doc->file, 0, SEEK_SET);
+ fz_read_line(ctx, doc->file, buf, sizeof buf);
if (memcmp(buf, "%PDF-", 5) != 0)
- fz_throw(doc->ctx, FZ_ERROR_GENERIC, "cannot recognize version marker");
+ fz_throw(ctx, FZ_ERROR_GENERIC, "cannot recognize version marker");
doc->version = 10 * (fz_atof(buf+5) + 0.05);
}
static void
-pdf_read_start_xref(pdf_document *doc)
+pdf_read_start_xref(fz_context *ctx, pdf_document *doc)
{
unsigned char buf[1024];
int t, n;
int i;
- fz_seek(doc->file, 0, SEEK_END);
+ fz_seek(ctx, doc->file, 0, SEEK_END);
- doc->file_size = fz_tell(doc->file);
+ doc->file_size = fz_tell(ctx, doc->file);
t = fz_maxi(0, doc->file_size - (int)sizeof buf);
- fz_seek(doc->file, t, SEEK_SET);
+ fz_seek(ctx, doc->file, t, SEEK_SET);
- n = fz_read(doc->file, buf, sizeof buf);
+ n = fz_read(ctx, doc->file, buf, sizeof buf);
for (i = n - 9; i >= 0; i--)
{
@@ -478,7 +506,7 @@ pdf_read_start_xref(pdf_document *doc)
}
}
- fz_throw(doc->ctx, FZ_ERROR_GENERIC, "cannot find startxref");
+ fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find startxref");
}
/*
@@ -486,7 +514,7 @@ pdf_read_start_xref(pdf_document *doc)
*/
static int
-pdf_xref_size_from_old_trailer(pdf_document *doc, pdf_lexbuf *buf)
+pdf_xref_size_from_old_trailer(fz_context *ctx, pdf_document *doc, pdf_lexbuf *buf)
{
int len;
char *s;
@@ -500,82 +528,81 @@ pdf_xref_size_from_old_trailer(pdf_document *doc, pdf_lexbuf *buf)
fz_var(trailer);
/* Record the current file read offset so that we can reinstate it */
- ofs = fz_tell(doc->file);
+ ofs = fz_tell(ctx, doc->file);
- fz_read_line(doc->file, buf->scratch, buf->size);
+ fz_read_line(ctx, doc->file, buf->scratch, buf->size);
if (strncmp(buf->scratch, "xref", 4) != 0)
- fz_throw(doc->ctx, FZ_ERROR_GENERIC, "cannot find xref marker");
+ fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find xref marker");
while (1)
{
- c = fz_peek_byte(doc->file);
+ c = fz_peek_byte(ctx, doc->file);
if (!(c >= '0' && c <= '9'))
break;
- fz_read_line(doc->file, buf->scratch, buf->size);
+ fz_read_line(ctx, doc->file, buf->scratch, buf->size);
s = buf->scratch;
fz_strsep(&s, " "); /* ignore ofs */
if (!s)
- fz_throw(doc->ctx, FZ_ERROR_GENERIC, "invalid range marker in xref");
+ fz_throw(ctx, FZ_ERROR_GENERIC, "invalid range marker in xref");
len = fz_atoi(fz_strsep(&s, " "));
if (len < 0)
- fz_throw(doc->ctx, FZ_ERROR_GENERIC, "xref range marker must be positive");
+ fz_throw(ctx, FZ_ERROR_GENERIC, "xref range marker must be positive");
/* broken pdfs where the section is not on a separate line */
if (s && *s != '\0')
- fz_seek(doc->file, -(2 + (int)strlen(s)), SEEK_CUR);
+ fz_seek(ctx, doc->file, -(2 + (int)strlen(s)), SEEK_CUR);
- t = fz_tell(doc->file);
+ t = fz_tell(ctx, doc->file);
if (t < 0)
- fz_throw(doc->ctx, FZ_ERROR_GENERIC, "cannot tell in file");
+ fz_throw(ctx, FZ_ERROR_GENERIC, "cannot tell in file");
if (len > (INT_MAX - t) / 20)
- fz_throw(doc->ctx, FZ_ERROR_GENERIC, "xref has too many entries");
+ fz_throw(ctx, FZ_ERROR_GENERIC, "xref has too many entries");
- fz_seek(doc->file, t + 20 * len, SEEK_SET);
+ fz_seek(ctx, doc->file, t + 20 * len, SEEK_SET);
}
- fz_try(doc->ctx)
+ fz_try(ctx)
{
- tok = pdf_lex(doc->file, buf);
+ tok = pdf_lex(ctx, doc->file, buf);
if (tok != PDF_TOK_TRAILER)
- fz_throw(doc->ctx, FZ_ERROR_GENERIC, "expected trailer marker");
+ fz_throw(ctx, FZ_ERROR_GENERIC, "expected trailer marker");
- tok = pdf_lex(doc->file, buf);
+ tok = pdf_lex(ctx, doc->file, buf);
if (tok != PDF_TOK_OPEN_DICT)
- fz_throw(doc->ctx, FZ_ERROR_GENERIC, "expected trailer dictionary");
+ fz_throw(ctx, FZ_ERROR_GENERIC, "expected trailer dictionary");
- trailer = pdf_parse_dict(doc, doc->file, buf);
+ trailer = pdf_parse_dict(ctx, doc, doc->file, buf);
- size = pdf_to_int(pdf_dict_gets(trailer, "Size"));
+ size = pdf_to_int(ctx, pdf_dict_gets(ctx, trailer, "Size"));
if (!size)
- fz_throw(doc->ctx, FZ_ERROR_GENERIC, "trailer missing Size entry");
+ fz_throw(ctx, FZ_ERROR_GENERIC, "trailer missing Size entry");
}
- fz_always(doc->ctx)
+ fz_always(ctx)
{
- pdf_drop_obj(trailer);
+ pdf_drop_obj(ctx, trailer);
}
- fz_catch(doc->ctx)
+ fz_catch(ctx)
{
- fz_rethrow_message(doc->ctx, "cannot parse trailer");
+ fz_rethrow_message(ctx, "cannot parse trailer");
}
- fz_seek(doc->file, ofs, SEEK_SET);
+ fz_seek(ctx, doc->file, ofs, SEEK_SET);
return size;
}
pdf_obj *
-pdf_new_ref(pdf_document *doc, pdf_obj *obj)
+pdf_new_ref(fz_context *ctx, pdf_document *doc, pdf_obj *obj)
{
- int num = pdf_create_object(doc);
- pdf_update_object(doc, num, obj);
- return pdf_new_indirect(doc, num, 0);
+ int num = pdf_create_object(ctx, doc);
+ pdf_update_object(ctx, doc, num, obj);
+ return pdf_new_indirect(ctx, doc, num, 0);
}
static pdf_xref_entry *
-pdf_xref_find_subsection(pdf_document *doc, int ofs, int len)
+pdf_xref_find_subsection(fz_context *ctx, pdf_document *doc, int ofs, int len)
{
- fz_context *ctx = doc->ctx;
pdf_xref *xref = &doc->xref_sections[doc->num_xref_sections-1];
pdf_xref_subsec *sub;
int new_max;
@@ -619,20 +646,23 @@ pdf_xref_find_subsection(pdf_document *doc, int ofs, int len)
}
xref->num_objects = new_max;
if (doc->max_xref_len < new_max)
- doc->max_xref_len = new_max;
+ extend_xref_index(ctx, doc, new_max);
}
else
{
/* Case 3 */
- ensure_solid_xref(doc, new_max, 0);
+ ensure_solid_xref(ctx, doc, new_max, doc->num_xref_sections-1);
+ xref = &doc->xref_sections[doc->num_xref_sections-1];
sub = xref->subsec;
}
return &sub->table[ofs-sub->start];
}
static pdf_obj *
-pdf_read_old_xref(pdf_document *doc, pdf_lexbuf *buf)
+pdf_read_old_xref(fz_context *ctx, pdf_document *doc, pdf_lexbuf *buf)
{
+ fz_stream *file = doc->file;
+
int ofs, len;
char *s;
int n;
@@ -640,20 +670,20 @@ pdf_read_old_xref(pdf_document *doc, pdf_lexbuf *buf)
int i;
int c;
pdf_obj *trailer;
- int xref_len = pdf_xref_size_from_old_trailer(doc, buf);
+ int xref_len = pdf_xref_size_from_old_trailer(ctx, doc, buf);
pdf_xref_entry *table;
- fz_read_line(doc->file, buf->scratch, buf->size);
+ fz_read_line(ctx, file, buf->scratch, buf->size);
if (strncmp(buf->scratch, "xref", 4) != 0)
- fz_throw(doc->ctx, FZ_ERROR_GENERIC, "cannot find xref marker");
+ fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find xref marker");
while (1)
{
- c = fz_peek_byte(doc->file);
+ c = fz_peek_byte(ctx, file);
if (!(c >= '0' && c <= '9'))
break;
- fz_read_line(doc->file, buf->scratch, buf->size);
+ fz_read_line(ctx, file, buf->scratch, buf->size);
s = buf->scratch;
ofs = fz_atoi(fz_strsep(&s, " "));
len = fz_atoi(fz_strsep(&s, " "));
@@ -661,27 +691,27 @@ pdf_read_old_xref(pdf_document *doc, pdf_lexbuf *buf)
/* broken pdfs where the section is not on a separate line */
if (s && *s != '\0')
{
- fz_warn(doc->ctx, "broken xref section. proceeding anyway.");
- fz_seek(doc->file, -(2 + (int)strlen(s)), SEEK_CUR);
+ fz_warn(ctx, "broken xref section. proceeding anyway.");
+ fz_seek(ctx, file, -(2 + (int)strlen(s)), SEEK_CUR);
}
if (ofs < 0)
- fz_throw(doc->ctx, FZ_ERROR_GENERIC, "out of range object num in xref: %d", ofs);
+ fz_throw(ctx, FZ_ERROR_GENERIC, "out of range object num in xref: %d", ofs);
/* broken pdfs where size in trailer undershoots entries in xref sections */
if (ofs + len > xref_len)
{
- fz_warn(doc->ctx, "broken xref section, proceeding anyway.");
+ fz_warn(ctx, "broken xref section, proceeding anyway.");
}
- table = pdf_xref_find_subsection(doc, ofs, len);
+ table = pdf_xref_find_subsection(ctx, doc, ofs, len);
for (i = ofs; i < ofs + len; i++)
{
pdf_xref_entry *entry = &table[i-ofs];
- n = fz_read(doc->file, (unsigned char *) buf->scratch, 20);
+ n = fz_read(ctx, file, (unsigned char *) buf->scratch, 20);
if (n != 20)
- fz_throw(doc->ctx, FZ_ERROR_GENERIC, "unexpected EOF in xref table");
+ fz_throw(ctx, FZ_ERROR_GENERIC, "unexpected EOF in xref table");
if (!entry->type)
{
s = buf->scratch;
@@ -694,42 +724,42 @@ pdf_read_old_xref(pdf_document *doc, pdf_lexbuf *buf)
entry->gen = atoi(s + 11);
entry->type = s[17];
if (s[17] != 'f' && s[17] != 'n' && s[17] != 'o')
- fz_throw(doc->ctx, FZ_ERROR_GENERIC, "unexpected xref type: %#x (%d %d R)", s[17], i, entry->gen);
+ fz_throw(ctx, FZ_ERROR_GENERIC, "unexpected xref type: %#x (%d %d R)", s[17], i, entry->gen);
}
}
}
- fz_try(doc->ctx)
+ fz_try(ctx)
{
- tok = pdf_lex(doc->file, buf);
+ tok = pdf_lex(ctx, file, buf);
if (tok != PDF_TOK_TRAILER)
- fz_throw(doc->ctx, FZ_ERROR_GENERIC, "expected trailer marker");
+ fz_throw(ctx, FZ_ERROR_GENERIC, "expected trailer marker");
- tok = pdf_lex(doc->file, buf);
+ tok = pdf_lex(ctx, file, buf);
if (tok != PDF_TOK_OPEN_DICT)
- fz_throw(doc->ctx, FZ_ERROR_GENERIC, "expected trailer dictionary");
+ fz_throw(ctx, FZ_ERROR_GENERIC, "expected trailer dictionary");
- trailer = pdf_parse_dict(doc, doc->file, buf);
+ trailer = pdf_parse_dict(ctx, doc, file, buf);
}
- fz_catch(doc->ctx)
+ fz_catch(ctx)
{
- fz_rethrow_message(doc->ctx, "cannot parse trailer");
+ fz_rethrow_message(ctx, "cannot parse trailer");
}
return trailer;
}
static void
-pdf_read_new_xref_section(pdf_document *doc, fz_stream *stm, int i0, int i1, int w0, int w1, int w2)
+pdf_read_new_xref_section(fz_context *ctx, pdf_document *doc, fz_stream *stm, int i0, int i1, int w0, int w1, int w2)
{
- int i, n;
pdf_xref_entry *table;
+ int i, n;
if (i0 < 0 || i1 < 0)
- fz_throw(doc->ctx, FZ_ERROR_GENERIC, "negative xref stream entry index");
- //if (i0 + i1 > pdf_xref_len(doc))
- // fz_throw(doc->ctx, FZ_ERROR_GENERIC, "xref stream has too many entries");
+ fz_throw(ctx, FZ_ERROR_GENERIC, "negative xref stream entry index");
+ //if (i0 + i1 > pdf_xref_len(ctx, doc))
+ // fz_throw(ctx, FZ_ERROR_GENERIC, "xref stream has too many entries");
- table = pdf_xref_find_subsection(doc, i0, i1);
+ table = pdf_xref_find_subsection(ctx, doc, i0, i1);
for (i = i0; i < i0 + i1; i++)
{
pdf_xref_entry *entry = &table[i-i0];
@@ -737,15 +767,15 @@ pdf_read_new_xref_section(pdf_document *doc, fz_stream *stm, int i0, int i1, int
int b = 0;
int c = 0;
- if (fz_is_eof(stm))
- fz_throw(doc->ctx, FZ_ERROR_GENERIC, "truncated xref stream");
+ if (fz_is_eof(ctx, stm))
+ fz_throw(ctx, FZ_ERROR_GENERIC, "truncated xref stream");
for (n = 0; n < w0; n++)
- a = (a << 8) + fz_read_byte(stm);
+ a = (a << 8) + fz_read_byte(ctx, stm);
for (n = 0; n < w1; n++)
- b = (b << 8) + fz_read_byte(stm);
+ b = (b << 8) + fz_read_byte(ctx, stm);
for (n = 0; n < w2; n++)
- c = (c << 8) + fz_read_byte(stm);
+ c = (c << 8) + fz_read_byte(ctx, stm);
if (!entry->type)
{
@@ -761,7 +791,7 @@ pdf_read_new_xref_section(pdf_document *doc, fz_stream *stm, int i0, int i1, int
/* Entered with file locked, remains locked throughout. */
static pdf_obj *
-pdf_read_new_xref(pdf_document *doc, pdf_lexbuf *buf)
+pdf_read_new_xref(fz_context *ctx, pdf_document *doc, pdf_lexbuf *buf)
{
fz_stream *stm = NULL;
pdf_obj *trailer = NULL;
@@ -770,19 +800,18 @@ pdf_read_new_xref(pdf_document *doc, pdf_lexbuf *buf)
int num, gen, ofs, stm_ofs;
int size, w0, w1, w2;
int t;
- fz_context *ctx = doc->ctx;
fz_var(trailer);
fz_var(stm);
fz_try(ctx)
{
- ofs = fz_tell(doc->file);
- trailer = pdf_parse_ind_obj(doc, doc->file, buf, &num, &gen, &stm_ofs, NULL);
+ ofs = fz_tell(ctx, doc->file);
+ trailer = pdf_parse_ind_obj(ctx, doc, doc->file, buf, &num, &gen, &stm_ofs, NULL);
}
fz_catch(ctx)
{
- pdf_drop_obj(trailer);
+ pdf_drop_obj(ctx, trailer);
fz_rethrow_message(ctx, "cannot parse compressed xref stream object");
}
@@ -790,18 +819,18 @@ pdf_read_new_xref(pdf_document *doc, pdf_lexbuf *buf)
{
pdf_xref_entry *entry;
- obj = pdf_dict_gets(trailer, "Size");
+ obj = pdf_dict_gets(ctx, trailer, "Size");
if (!obj)
fz_throw(ctx, FZ_ERROR_GENERIC, "xref stream missing Size entry (%d %d R)", num, gen);
- size = pdf_to_int(obj);
+ size = pdf_to_int(ctx, obj);
- obj = pdf_dict_gets(trailer, "W");
+ obj = pdf_dict_gets(ctx, trailer, "W");
if (!obj)
fz_throw(ctx, FZ_ERROR_GENERIC, "xref stream missing W entry (%d %d R)", num, gen);
- w0 = pdf_to_int(pdf_array_get(obj, 0));
- w1 = pdf_to_int(pdf_array_get(obj, 1));
- w2 = pdf_to_int(pdf_array_get(obj, 2));
+ w0 = pdf_to_int(ctx, pdf_array_get(ctx, obj, 0));
+ w1 = pdf_to_int(ctx, pdf_array_get(ctx, obj, 1));
+ w2 = pdf_to_int(ctx, pdf_array_get(ctx, obj, 2));
if (w0 < 0)
fz_warn(ctx, "xref stream objects have corrupt type");
@@ -814,39 +843,39 @@ pdf_read_new_xref(pdf_document *doc, pdf_lexbuf *buf)
w1 = w1 < 0 ? 0 : w1;
w2 = w2 < 0 ? 0 : w2;
- index = pdf_dict_gets(trailer, "Index");
+ index = pdf_dict_gets(ctx, trailer, "Index");
- stm = pdf_open_stream_with_offset(doc, num, gen, trailer, stm_ofs);
+ stm = pdf_open_stream_with_offset(ctx, doc, num, gen, trailer, stm_ofs);
if (!index)
{
- pdf_read_new_xref_section(doc, stm, 0, size, w0, w1, w2);
+ pdf_read_new_xref_section(ctx, doc, stm, 0, size, w0, w1, w2);
}
else
{
- int n = pdf_array_len(index);
+ int n = pdf_array_len(ctx, index);
for (t = 0; t < n; t += 2)
{
- int i0 = pdf_to_int(pdf_array_get(index, t + 0));
- int i1 = pdf_to_int(pdf_array_get(index, t + 1));
- pdf_read_new_xref_section(doc, stm, i0, i1, w0, w1, w2);
+ int i0 = pdf_to_int(ctx, pdf_array_get(ctx, index, t + 0));
+ int i1 = pdf_to_int(ctx, pdf_array_get(ctx, index, t + 1));
+ pdf_read_new_xref_section(ctx, doc, stm, i0, i1, w0, w1, w2);
}
}
- entry = pdf_get_populating_xref_entry(doc, num);
+ entry = pdf_get_populating_xref_entry(ctx, doc, num);
entry->ofs = ofs;
entry->gen = gen;
entry->stm_ofs = stm_ofs;
- pdf_drop_obj(entry->obj);
- entry->obj = pdf_keep_obj(trailer);
+ pdf_drop_obj(ctx, entry->obj);
+ entry->obj = pdf_keep_obj(ctx, trailer);
entry->type = 'n';
}
fz_always(ctx)
{
- fz_close(stm);
+ fz_drop_stream(ctx, stm);
}
fz_catch(ctx)
{
- pdf_drop_obj(trailer);
+ pdf_drop_obj(ctx, trailer);
fz_rethrow(ctx);
}
@@ -854,24 +883,23 @@ pdf_read_new_xref(pdf_document *doc, pdf_lexbuf *buf)
}
static pdf_obj *
-pdf_read_xref(pdf_document *doc, int ofs, pdf_lexbuf *buf)
+pdf_read_xref(fz_context *ctx, pdf_document *doc, int ofs, pdf_lexbuf *buf)
{
- int c;
- fz_context *ctx = doc->ctx;
pdf_obj *trailer;
+ int c;
- fz_seek(doc->file, ofs, SEEK_SET);
+ fz_seek(ctx, doc->file, ofs, SEEK_SET);
- while (iswhite(fz_peek_byte(doc->file)))
- fz_read_byte(doc->file);
+ while (iswhite(fz_peek_byte(ctx, doc->file)))
+ fz_read_byte(ctx, doc->file);
fz_try(ctx)
{
- c = fz_peek_byte(doc->file);
+ c = fz_peek_byte(ctx, doc->file);
if (c == 'x')
- trailer = pdf_read_old_xref(doc, buf);
+ trailer = pdf_read_old_xref(ctx, doc, buf);
else if (c >= '0' && c <= '9')
- trailer = pdf_read_new_xref(doc, buf);
+ trailer = pdf_read_new_xref(ctx, doc, buf);
else
fz_throw(ctx, FZ_ERROR_GENERIC, "cannot recognize xref format");
}
@@ -892,10 +920,9 @@ struct ofs_list_s
};
static int
-read_xref_section(pdf_document *doc, int ofs, pdf_lexbuf *buf, ofs_list *offsets)
+read_xref_section(fz_context *ctx, pdf_document *doc, int ofs, pdf_lexbuf *buf, ofs_list *offsets)
{
pdf_obj *trailer = NULL;
- fz_context *ctx = doc->ctx;
int xrefstmofs = 0;
int prevofs = 0;
@@ -922,13 +949,13 @@ read_xref_section(pdf_document *doc, int ofs, pdf_lexbuf *buf, ofs_list *offsets
}
offsets->list[offsets->len++] = ofs;
- trailer = pdf_read_xref(doc, ofs, buf);
+ trailer = pdf_read_xref(ctx, doc, ofs, buf);
- pdf_set_populating_xref_trailer(doc, trailer);
+ pdf_set_populating_xref_trailer(ctx, doc, trailer);
/* FIXME: do we overwrite free entries properly? */
/* FIXME: Does this work properly with progression? */
- xrefstmofs = pdf_to_int(pdf_dict_gets(trailer, "XRefStm"));
+ xrefstmofs = pdf_to_int(ctx, pdf_dict_gets(ctx, trailer, "XRefStm"));
if (xrefstmofs)
{
if (xrefstmofs < 0)
@@ -939,16 +966,16 @@ read_xref_section(pdf_document *doc, int ofs, pdf_lexbuf *buf, ofs_list *offsets
follow any Prev tag therein, as specified on Page 108 of the PDF reference
1.7
*/
- pdf_drop_obj(pdf_read_xref(doc, xrefstmofs, buf));
+ pdf_drop_obj(ctx, pdf_read_xref(ctx, doc, xrefstmofs, buf));
}
- prevofs = pdf_to_int(pdf_dict_gets(trailer, "Prev"));
+ prevofs = pdf_to_int(ctx, pdf_dict_gets(ctx, trailer, "Prev"));
if (prevofs < 0)
fz_throw(ctx, FZ_ERROR_GENERIC, "negative xref stream offset for previous xref stream");
}
fz_always(ctx)
{
- pdf_drop_obj(trailer);
+ pdf_drop_obj(ctx, trailer);
}
fz_catch(ctx)
{
@@ -959,9 +986,8 @@ read_xref_section(pdf_document *doc, int ofs, pdf_lexbuf *buf, ofs_list *offsets
}
static void
-pdf_read_xref_sections(pdf_document *doc, int ofs, pdf_lexbuf *buf, int read_previous)
+pdf_read_xref_sections(fz_context *ctx, pdf_document *doc, int ofs, pdf_lexbuf *buf, int read_previous)
{
- fz_context *ctx = doc->ctx;
ofs_list list;
list.len = 0;
@@ -971,8 +997,8 @@ pdf_read_xref_sections(pdf_document *doc, int ofs, pdf_lexbuf *buf, int read_pre
{
while(ofs)
{
- pdf_populate_next_xref_level(doc);
- ofs = read_xref_section(doc, ofs, buf, &list);
+ pdf_populate_next_xref_level(ctx, doc);
+ ofs = read_xref_section(ctx, doc, ofs, buf, &list);
if (!read_previous)
break;
}
@@ -987,6 +1013,32 @@ pdf_read_xref_sections(pdf_document *doc, int ofs, pdf_lexbuf *buf, int read_pre
}
}
+static void
+pdf_prime_xref_index(fz_context *ctx, pdf_document *doc)
+{
+ int i, j;
+ int *idx = doc->xref_index;
+
+ for (i = doc->num_xref_sections-1; i >= 0; i--)
+ {
+ pdf_xref *xref = &doc->xref_sections[i];
+ pdf_xref_subsec *subsec = xref->subsec;
+ while (subsec != NULL)
+ {
+ int start = subsec->start;
+ int end = subsec->start + subsec->len;
+ for (j = start; j < end; j++)
+ {
+ char t = subsec->table[j-start].type;
+ if (t != 0 && t != 'f')
+ idx[j] = i;
+ }
+
+ subsec = subsec->next;
+ }
+ }
+}
+
/*
* load xref tables from pdf
*
@@ -994,21 +1046,22 @@ pdf_read_xref_sections(pdf_document *doc, int ofs, pdf_lexbuf *buf, int read_pre
*/
static void
-pdf_load_xref(pdf_document *doc, pdf_lexbuf *buf)
+pdf_load_xref(fz_context *ctx, pdf_document *doc, pdf_lexbuf *buf)
{
int i;
int xref_len;
pdf_xref_entry *entry;
- fz_context *ctx = doc->ctx;
- pdf_read_start_xref(doc);
+ pdf_read_start_xref(ctx, doc);
- pdf_read_xref_sections(doc, doc->startxref, buf, 1);
+ pdf_read_xref_sections(ctx, doc, doc->startxref, buf, 1);
- if (pdf_xref_len(doc) == 0)
+ if (pdf_xref_len(ctx, doc) == 0)
fz_throw(ctx, FZ_ERROR_GENERIC, "found xref was empty");
- entry = pdf_get_xref_entry(doc, 0);
+ pdf_prime_xref_index(ctx, doc);
+
+ entry = pdf_get_xref_entry(ctx, doc, 0);
/* broken pdfs where first object is missing */
if (!entry->type)
{
@@ -1020,10 +1073,10 @@ pdf_load_xref(pdf_document *doc, pdf_lexbuf *buf)
fz_throw(ctx, FZ_ERROR_GENERIC, "first object in xref is not free");
/* broken pdfs where object offsets are out of range */
- xref_len = pdf_xref_len(doc);
+ xref_len = pdf_xref_len(ctx, doc);
for (i = 0; i < xref_len; i++)
{
- pdf_xref_entry *entry = pdf_get_xref_entry(doc, i);
+ pdf_xref_entry *entry = pdf_get_xref_entry(ctx, doc, i);
if (entry->type == 'n')
{
/* Special case code: "0000000000 * n" means free,
@@ -1034,19 +1087,18 @@ pdf_load_xref(pdf_document *doc, pdf_lexbuf *buf)
fz_throw(ctx, FZ_ERROR_GENERIC, "object offset out of range: %d (%d 0 R)", entry->ofs, i);
}
if (entry->type == 'o')
- if (entry->ofs <= 0 || entry->ofs >= xref_len || pdf_get_xref_entry(doc, entry->ofs)->type != 'n')
+ if (entry->ofs <= 0 || entry->ofs >= xref_len || pdf_get_xref_entry(ctx, doc, entry->ofs)->type != 'n')
fz_throw(ctx, FZ_ERROR_GENERIC, "invalid reference to an objstm that does not exist: %d (%d 0 R)", entry->ofs, i);
}
}
static void
-pdf_load_linear(pdf_document *doc)
+pdf_load_linear(fz_context *ctx, pdf_document *doc)
{
pdf_obj *dict = NULL;
pdf_obj *hint = NULL;
pdf_obj *o;
int num, gen, stmofs, lin, len;
- fz_context *ctx = doc->ctx;
fz_var(dict);
fz_var(hint);
@@ -1055,39 +1107,39 @@ pdf_load_linear(pdf_document *doc)
{
pdf_xref_entry *entry;
- dict = pdf_parse_ind_obj(doc, doc->file, &doc->lexbuf.base, &num, &gen, &stmofs, NULL);
- if (!pdf_is_dict(dict))
+ dict = pdf_parse_ind_obj(ctx, doc, doc->file, &doc->lexbuf.base, &num, &gen, &stmofs, NULL);
+ if (!pdf_is_dict(ctx, dict))
fz_throw(ctx, FZ_ERROR_GENERIC, "Failed to read linearized dictionary");
- o = pdf_dict_gets(dict, "Linearized");
+ o = pdf_dict_gets(ctx, dict, "Linearized");
if (o == NULL)
fz_throw(ctx, FZ_ERROR_GENERIC, "Failed to read linearized dictionary");
- lin = pdf_to_int(o);
+ lin = pdf_to_int(ctx, o);
if (lin != 1)
fz_throw(ctx, FZ_ERROR_GENERIC, "Unexpected version of Linearized tag (%d)", lin);
- len = pdf_to_int(pdf_dict_gets(dict, "L"));
+ len = pdf_to_int(ctx, pdf_dict_gets(ctx, dict, "L"));
if (len != doc->file_length)
fz_throw(ctx, FZ_ERROR_GENERIC, "File has been updated since linearization");
- pdf_read_xref_sections(doc, fz_tell(doc->file), &doc->lexbuf.base, 0);
+ pdf_read_xref_sections(ctx, doc, fz_tell(ctx, doc->file), &doc->lexbuf.base, 0);
- doc->page_count = pdf_to_int(pdf_dict_gets(dict, "N"));
+ doc->page_count = pdf_to_int(ctx, pdf_dict_gets(ctx, dict, "N"));
doc->linear_page_refs = fz_resize_array(ctx, doc->linear_page_refs, doc->page_count, sizeof(pdf_obj *));
memset(doc->linear_page_refs, 0, doc->page_count * sizeof(pdf_obj*));
doc->linear_obj = dict;
- doc->linear_pos = fz_tell(doc->file);
- doc->linear_page1_obj_num = pdf_to_int(pdf_dict_gets(dict, "O"));
- doc->linear_page_refs[0] = pdf_new_indirect(doc, doc->linear_page1_obj_num, 0);
+ doc->linear_pos = fz_tell(ctx, doc->file);
+ doc->linear_page1_obj_num = pdf_to_int(ctx, pdf_dict_gets(ctx, dict, "O"));
+ doc->linear_page_refs[0] = pdf_new_indirect(ctx, doc, doc->linear_page1_obj_num, 0);
doc->linear_page_num = 0;
- hint = pdf_dict_gets(dict, "H");
- doc->hint_object_offset = pdf_to_int(pdf_array_get(hint, 0));
- doc->hint_object_length = pdf_to_int(pdf_array_get(hint, 1));
+ hint = pdf_dict_gets(ctx, dict, "H");
+ doc->hint_object_offset = pdf_to_int(ctx, pdf_array_get(ctx, hint, 0));
+ doc->hint_object_length = pdf_to_int(ctx, pdf_array_get(ctx, hint, 1));
- entry = pdf_get_populating_xref_entry(doc, 0);
+ entry = pdf_get_populating_xref_entry(ctx, doc, 0);
entry->type = 'f';
}
fz_catch(ctx)
{
- pdf_drop_obj(dict);
+ pdf_drop_obj(ctx, dict);
fz_rethrow_if(ctx, FZ_ERROR_TRYLATER);
/* Drop back to non linearized reading mode */
doc->file_reading_linearly = 0;
@@ -1095,41 +1147,41 @@ pdf_load_linear(pdf_document *doc)
}
void
-pdf_ocg_set_config(pdf_document *doc, int config)
+pdf_ocg_set_config(fz_context *ctx, pdf_document *doc, int config)
{
int i, j, len, len2;
pdf_ocg_descriptor *desc = doc->ocg;
pdf_obj *obj, *cobj;
char *name;
- obj = pdf_dict_gets(pdf_dict_gets(pdf_trailer(doc), "Root"), "OCProperties");
+ obj = pdf_dict_gets(ctx, pdf_dict_gets(ctx, pdf_trailer(ctx, doc), "Root"), "OCProperties");
if (!obj)
{
if (config == 0)
return;
else
- fz_throw(doc->ctx, FZ_ERROR_GENERIC, "Unknown OCG config (None known!)");
+ fz_throw(ctx, FZ_ERROR_GENERIC, "Unknown OCG config (None known!)");
}
if (config == 0)
{
- cobj = pdf_dict_gets(obj, "D");
+ cobj = pdf_dict_gets(ctx, obj, "D");
if (!cobj)
- fz_throw(doc->ctx, FZ_ERROR_GENERIC, "No default OCG config");
+ fz_throw(ctx, FZ_ERROR_GENERIC, "No default OCG config");
}
else
{
- cobj = pdf_array_get(pdf_dict_gets(obj, "Configs"), config);
+ cobj = pdf_array_get(ctx, pdf_dict_gets(ctx, obj, "Configs"), config);
if (!cobj)
- fz_throw(doc->ctx, FZ_ERROR_GENERIC, "Illegal OCG config");
+ fz_throw(ctx, FZ_ERROR_GENERIC, "Illegal OCG config");
}
- pdf_drop_obj(desc->intent);
- desc->intent = pdf_dict_gets(cobj, "Intent");
+ pdf_drop_obj(ctx, desc->intent);
+ desc->intent = pdf_dict_gets(ctx, cobj, "Intent");
if (desc->intent)
- pdf_keep_obj(desc->intent);
+ pdf_keep_obj(ctx, desc->intent);
len = desc->len;
- name = pdf_to_name(pdf_dict_gets(cobj, "BaseState"));
+ name = pdf_to_name(ctx, pdf_dict_gets(ctx, cobj, "BaseState"));
if (strcmp(name, "Unchanged") == 0)
{
/* Do nothing */
@@ -1149,13 +1201,13 @@ pdf_ocg_set_config(pdf_document *doc, int config)
}
}
- obj = pdf_dict_gets(cobj, "ON");
- len2 = pdf_array_len(obj);
+ obj = pdf_dict_gets(ctx, cobj, "ON");
+ len2 = pdf_array_len(ctx, obj);
for (i = 0; i < len2; i++)
{
- pdf_obj *o = pdf_array_get(obj, i);
- int n = pdf_to_num(o);
- int g = pdf_to_gen(o);
+ pdf_obj *o = pdf_array_get(ctx, obj, i);
+ int n = pdf_to_num(ctx, o);
+ int g = pdf_to_gen(ctx, o);
for (j=0; j < len; j++)
{
if (desc->ocgs[j].num == n && desc->ocgs[j].gen == g)
@@ -1166,13 +1218,13 @@ pdf_ocg_set_config(pdf_document *doc, int config)
}
}
- obj = pdf_dict_gets(cobj, "OFF");
- len2 = pdf_array_len(obj);
+ obj = pdf_dict_gets(ctx, cobj, "OFF");
+ len2 = pdf_array_len(ctx, obj);
for (i = 0; i < len2; i++)
{
- pdf_obj *o = pdf_array_get(obj, i);
- int n = pdf_to_num(o);
- int g = pdf_to_gen(o);
+ pdf_obj *o = pdf_array_get(ctx, obj, i);
+ int n = pdf_to_num(ctx, o);
+ int g = pdf_to_gen(ctx, o);
for (j=0; j < len; j++)
{
if (desc->ocgs[j].num == n && desc->ocgs[j].gen == g)
@@ -1199,23 +1251,22 @@ pdf_ocg_set_config(pdf_document *doc, int config)
}
static void
-pdf_read_ocg(pdf_document *doc)
+pdf_read_ocg(fz_context *ctx, pdf_document *doc)
{
pdf_obj *obj, *ocg;
int len, i;
pdf_ocg_descriptor *desc;
- fz_context *ctx = doc->ctx;
fz_var(desc);
- obj = pdf_dict_gets(pdf_dict_gets(pdf_trailer(doc), "Root"), "OCProperties");
+ obj = pdf_dict_gets(ctx, pdf_dict_gets(ctx, pdf_trailer(ctx, doc), "Root"), "OCProperties");
if (!obj)
return;
- ocg = pdf_dict_gets(obj, "OCGs");
- if (!ocg || !pdf_is_array(ocg))
+ ocg = pdf_dict_gets(ctx, obj, "OCGs");
+ if (!ocg || !pdf_is_array(ctx, ocg))
/* Not ever supposed to happen, but live with it. */
return;
- len = pdf_array_len(ocg);
+ len = pdf_array_len(ctx, ocg);
fz_try(ctx)
{
desc = fz_calloc(ctx, 1, sizeof(*desc));
@@ -1224,9 +1275,9 @@ pdf_read_ocg(pdf_document *doc)
desc->intent = NULL;
for (i=0; i < len; i++)
{
- pdf_obj *o = pdf_array_get(ocg, i);
- desc->ocgs[i].num = pdf_to_num(o);
- desc->ocgs[i].gen = pdf_to_gen(o);
+ pdf_obj *o = pdf_array_get(ctx, ocg, i);
+ desc->ocgs[i].num = pdf_to_num(ctx, o);
+ desc->ocgs[i].gen = pdf_to_gen(ctx, o);
desc->ocgs[i].state = 1;
}
doc->ocg = desc;
@@ -1239,16 +1290,16 @@ pdf_read_ocg(pdf_document *doc)
fz_rethrow(ctx);
}
- pdf_ocg_set_config(doc, 0);
+ pdf_ocg_set_config(ctx, doc, 0);
}
static void
-pdf_free_ocg(fz_context *ctx, pdf_ocg_descriptor *desc)
+pdf_drop_ocg(fz_context *ctx, pdf_ocg_descriptor *desc)
{
if (!desc)
return;
- pdf_drop_obj(desc->intent);
+ pdf_drop_obj(ctx, desc->intent);
fz_free(ctx, desc->ocgs);
fz_free(ctx, desc);
}
@@ -1259,9 +1310,8 @@ pdf_free_ocg(fz_context *ctx, pdf_ocg_descriptor *desc)
*/
static void
-pdf_init_document(pdf_document *doc)
+pdf_init_document(fz_context *ctx, pdf_document *doc)
{
- fz_context *ctx = doc->ctx;
pdf_obj *encrypt, *id;
pdf_obj *dict = NULL;
pdf_obj *obj;
@@ -1273,30 +1323,30 @@ pdf_init_document(pdf_document *doc)
fz_try(ctx)
{
- pdf_load_version(doc);
+ pdf_load_version(ctx, doc);
- doc->file_length = fz_stream_meta(doc->file, FZ_STREAM_META_LENGTH, 0, NULL);
+ doc->file_length = fz_stream_meta(ctx, doc->file, FZ_STREAM_META_LENGTH, 0, NULL);
if (doc->file_length < 0)
doc->file_length = 0;
/* Check to see if we should work in progressive mode */
- if (fz_stream_meta(doc->file, FZ_STREAM_META_PROGRESSIVE, 0, NULL) > 0)
+ if (fz_stream_meta(ctx, doc->file, FZ_STREAM_META_PROGRESSIVE, 0, NULL) > 0)
doc->file_reading_linearly = 1;
/* Try to load the linearized file if we are in progressive
* mode. */
if (doc->file_reading_linearly)
- pdf_load_linear(doc);
+ pdf_load_linear(ctx, doc);
/* If we aren't in progressive mode (or the linear load failed
* and has set us back to non-progressive mode), load normally.
*/
if (!doc->file_reading_linearly)
- pdf_load_xref(doc, &doc->lexbuf.base);
+ pdf_load_xref(ctx, doc, &doc->lexbuf.base);
}
fz_catch(ctx)
{
- pdf_free_xref_sections(doc);
+ pdf_drop_xref_sections(ctx, doc);
fz_rethrow_if(ctx, FZ_ERROR_TRYLATER);
fz_warn(ctx, "trying to repair broken xref");
repaired = 1;
@@ -1307,33 +1357,38 @@ pdf_init_document(pdf_document *doc)
int hasroot, hasinfo;
if (repaired)
- pdf_repair_xref(doc, &doc->lexbuf.base);
+ {
+ /* pdf_repair_xref may access xref_index, so reset it properly */
+ memset(doc->xref_index, 0, sizeof(int) * doc->max_xref_len);
+ pdf_repair_xref(ctx, doc);
+ pdf_prime_xref_index(ctx, doc);
+ }
- encrypt = pdf_dict_gets(pdf_trailer(doc), "Encrypt");
- id = pdf_dict_gets(pdf_trailer(doc), "ID");
- if (pdf_is_dict(encrypt))
+ encrypt = pdf_dict_gets(ctx, pdf_trailer(ctx, doc), "Encrypt");
+ id = pdf_dict_gets(ctx, pdf_trailer(ctx, doc), "ID");
+ if (pdf_is_dict(ctx, encrypt))
doc->crypt = pdf_new_crypt(ctx, encrypt, id);
/* Allow lazy clients to read encrypted files with a blank password */
- pdf_authenticate_password(doc, "");
+ pdf_authenticate_password(ctx, doc, "");
if (repaired)
{
- int xref_len = pdf_xref_len(doc);
- pdf_repair_obj_stms(doc);
+ int xref_len = pdf_xref_len(ctx, doc);
+ pdf_repair_obj_stms(ctx, doc);
- hasroot = (pdf_dict_gets(pdf_trailer(doc), "Root") != NULL);
- hasinfo = (pdf_dict_gets(pdf_trailer(doc), "Info") != NULL);
+ hasroot = (pdf_dict_gets(ctx, pdf_trailer(ctx, doc), "Root") != NULL);
+ hasinfo = (pdf_dict_gets(ctx, pdf_trailer(ctx, doc), "Info") != NULL);
for (i = 1; i < xref_len; i++)
{
- pdf_xref_entry *entry = pdf_get_xref_entry(doc, i);
+ pdf_xref_entry *entry = pdf_get_xref_entry(ctx, doc, i);
if (entry->type == 0 || entry->type == 'f')
continue;
fz_try(ctx)
{
- dict = pdf_load_object(doc, i, 0);
+ dict = pdf_load_object(ctx, doc, i, 0);
}
fz_catch(ctx)
{
@@ -1344,46 +1399,46 @@ pdf_init_document(pdf_document *doc)
if (!hasroot)
{
- obj = pdf_dict_gets(dict, "Type");
- if (pdf_is_name(obj) && !strcmp(pdf_to_name(obj), "Catalog"))
+ obj = pdf_dict_gets(ctx, dict, "Type");
+ if (pdf_is_name(ctx, obj) && !strcmp(pdf_to_name(ctx, obj), "Catalog"))
{
- nobj = pdf_new_indirect(doc, i, 0);
- pdf_dict_puts(pdf_trailer(doc), "Root", nobj);
- pdf_drop_obj(nobj);
+ nobj = pdf_new_indirect(ctx, doc, i, 0);
+ pdf_dict_puts(ctx, pdf_trailer(ctx, doc), "Root", nobj);
+ pdf_drop_obj(ctx, nobj);
nobj = NULL;
}
}
if (!hasinfo)
{
- if (pdf_dict_gets(dict, "Creator") || pdf_dict_gets(dict, "Producer"))
+ if (pdf_dict_gets(ctx, dict, "Creator") || pdf_dict_gets(ctx, dict, "Producer"))
{
- nobj = pdf_new_indirect(doc, i, 0);
- pdf_dict_puts(pdf_trailer(doc), "Info", nobj);
- pdf_drop_obj(nobj);
+ nobj = pdf_new_indirect(ctx, doc, i, 0);
+ pdf_dict_puts(ctx, pdf_trailer(ctx, doc), "Info", nobj);
+ pdf_drop_obj(ctx, nobj);
nobj = NULL;
}
}
- pdf_drop_obj(dict);
+ pdf_drop_obj(ctx, dict);
dict = NULL;
}
/* ensure that strings are not used in their repaired, non-decrypted form */
if (doc->crypt)
- pdf_clear_xref(doc);
+ pdf_clear_xref(ctx, doc);
}
}
fz_catch(ctx)
{
- pdf_drop_obj(dict);
- pdf_drop_obj(nobj);
+ pdf_drop_obj(ctx, dict);
+ pdf_drop_obj(ctx, nobj);
fz_rethrow_message(ctx, "cannot open document");
}
fz_try(ctx)
{
- pdf_read_ocg(doc);
+ pdf_read_ocg(ctx, doc);
}
fz_catch(ctx)
{
@@ -1393,8 +1448,8 @@ pdf_init_document(pdf_document *doc)
fz_try(ctx)
{
char *version_str;
- obj = pdf_dict_getp(pdf_trailer(doc), "Root/Version");
- version_str = pdf_to_name(obj);
+ obj = pdf_dict_getp(ctx, pdf_trailer(ctx, doc), "Root/Version");
+ version_str = pdf_to_name(ctx, obj);
if (*version_str)
{
int version = 10 * (fz_atof(version_str) + 0.05);
@@ -1406,15 +1461,13 @@ pdf_init_document(pdf_document *doc)
}
void
-pdf_close_document(pdf_document *doc)
+pdf_close_document(fz_context *ctx, pdf_document *doc)
{
- fz_context *ctx;
pdf_unsaved_sig *usig;
int i;
if (!doc)
return;
- ctx = doc->ctx;
/* Type3 glyphs in the glyph cache can contain pdf_obj pointers
* that we are about to destroy. Simplest solution is to bin the
@@ -1424,21 +1477,22 @@ pdf_close_document(pdf_document *doc)
if (doc->js)
doc->drop_js(doc->js);
- pdf_free_xref_sections(doc);
+ pdf_drop_xref_sections(ctx, doc);
+ fz_free(ctx, doc->xref_index);
if (doc->focus_obj)
- pdf_drop_obj(doc->focus_obj);
+ pdf_drop_obj(ctx, doc->focus_obj);
if (doc->file)
- fz_close(doc->file);
+ fz_drop_stream(ctx, doc->file);
if (doc->crypt)
- pdf_free_crypt(ctx, doc->crypt);
+ pdf_drop_crypt(ctx, doc->crypt);
- pdf_drop_obj(doc->linear_obj);
+ pdf_drop_obj(ctx, doc->linear_obj);
if (doc->linear_page_refs)
{
for (i=0; i < doc->page_count; i++)
{
- pdf_drop_obj(doc->linear_page_refs[i]);
+ pdf_drop_obj(ctx, doc->linear_page_refs[i]);
}
fz_free(ctx, doc->linear_page_refs);
}
@@ -1450,8 +1504,8 @@ pdf_close_document(pdf_document *doc)
while ((usig = doc->unsaved_sigs) != NULL)
{
doc->unsaved_sigs = usig->next;
- pdf_drop_obj(usig->field);
- pdf_drop_signer(usig->signer);
+ pdf_drop_obj(ctx, usig->field);
+ pdf_drop_signer(ctx, usig->signer);
fz_free(ctx, usig);
}
@@ -1462,24 +1516,24 @@ pdf_close_document(pdf_document *doc)
}
fz_free(ctx, doc->type3_fonts);
- pdf_free_ocg(ctx, doc->ocg);
+ pdf_drop_ocg(ctx, doc->ocg);
fz_empty_store(ctx);
- pdf_lexbuf_fin(&doc->lexbuf.base);
+ pdf_lexbuf_fin(ctx, &doc->lexbuf.base);
fz_free(ctx, doc);
}
void
-pdf_print_xref(pdf_document *doc)
+pdf_print_xref(fz_context *ctx, pdf_document *doc)
{
int i;
- int xref_len = pdf_xref_len(doc);
+ int xref_len = pdf_xref_len(ctx, doc);
printf("xref\n0 %d\n", xref_len);
for (i = 0; i < xref_len; i++)
{
- pdf_xref_entry *entry = pdf_get_xref_entry(doc, i);
+ pdf_xref_entry *entry = pdf_get_xref_entry(ctx, doc, i);
printf("%05d: %010d %05d %c (stm_ofs=%d; stm_buf=%p)\n", i,
entry->ofs,
entry->gen,
@@ -1493,8 +1547,8 @@ pdf_print_xref(pdf_document *doc)
* compressed object streams
*/
-static void
-pdf_load_obj_stm(pdf_document *doc, int num, int gen, pdf_lexbuf *buf)
+static pdf_xref_entry *
+pdf_load_obj_stm(fz_context *ctx, pdf_document *doc, int num, int gen, pdf_lexbuf *buf, int target)
{
fz_stream *stm = NULL;
pdf_obj *objstm = NULL;
@@ -1506,7 +1560,7 @@ pdf_load_obj_stm(pdf_document *doc, int num, int gen, pdf_lexbuf *buf)
int count;
int i;
pdf_token tok;
- fz_context *ctx = doc->ctx;
+ pdf_xref_entry *ret_entry = NULL;
fz_var(numbuf);
fz_var(ofsbuf);
@@ -1515,10 +1569,10 @@ pdf_load_obj_stm(pdf_document *doc, int num, int gen, pdf_lexbuf *buf)
fz_try(ctx)
{
- objstm = pdf_load_object(doc, num, gen);
+ objstm = pdf_load_object(ctx, doc, num, gen);
- count = pdf_to_int(pdf_dict_gets(objstm, "N"));
- first = pdf_to_int(pdf_dict_gets(objstm, "First"));
+ count = pdf_to_int(ctx, pdf_dict_gets(ctx, objstm, "N"));
+ first = pdf_to_int(ctx, pdf_dict_gets(ctx, objstm, "First"));
if (count < 0)
fz_throw(ctx, FZ_ERROR_GENERIC, "negative number of objects in object stream");
@@ -1528,39 +1582,39 @@ pdf_load_obj_stm(pdf_document *doc, int num, int gen, pdf_lexbuf *buf)
numbuf = fz_calloc(ctx, count, sizeof(int));
ofsbuf = fz_calloc(ctx, count, sizeof(int));
- stm = pdf_open_stream(doc, num, gen);
+ stm = pdf_open_stream(ctx, doc, num, gen);
for (i = 0; i < count; i++)
{
- tok = pdf_lex(stm, buf);
+ tok = pdf_lex(ctx, stm, buf);
if (tok != PDF_TOK_INT)
fz_throw(ctx, FZ_ERROR_GENERIC, "corrupt object stream (%d %d R)", num, gen);
numbuf[i] = buf->i;
- tok = pdf_lex(stm, buf);
+ tok = pdf_lex(ctx, stm, buf);
if (tok != PDF_TOK_INT)
fz_throw(ctx, FZ_ERROR_GENERIC, "corrupt object stream (%d %d R)", num, gen);
ofsbuf[i] = buf->i;
}
- fz_seek(stm, first, SEEK_SET);
+ fz_seek(ctx, stm, first, SEEK_SET);
for (i = 0; i < count; i++)
{
- int xref_len = pdf_xref_len(doc);
+ int xref_len = pdf_xref_len(ctx, doc);
pdf_xref_entry *entry;
- fz_seek(stm, first + ofsbuf[i], SEEK_SET);
+ fz_seek(ctx, stm, first + ofsbuf[i], SEEK_SET);
- obj = pdf_parse_stm_obj(doc, stm, buf);
+ obj = pdf_parse_stm_obj(ctx, doc, stm, buf);
if (numbuf[i] <= 0 || numbuf[i] >= xref_len)
{
- pdf_drop_obj(obj);
+ pdf_drop_obj(ctx, obj);
fz_throw(ctx, FZ_ERROR_GENERIC, "object id (%d 0 R) out of range (0..%d)", numbuf[i], xref_len - 1);
}
- entry = pdf_get_xref_entry(doc, numbuf[i]);
+ entry = pdf_get_xref_entry(ctx, doc, numbuf[i]);
- pdf_set_obj_parent(obj, numbuf[i]);
+ pdf_set_obj_parent(ctx, obj, numbuf[i]);
if (entry->type == 'o' && entry->ofs == num)
{
@@ -1570,51 +1624,55 @@ pdf_load_obj_stm(pdf_document *doc, int num, int gen, pdf_lexbuf *buf)
* a pointer to the old one will be left with a
* stale pointer. Instead, we drop the new one
* and trust that the old one is correct. */
- if (entry->obj) {
- if (pdf_objcmp(entry->obj, obj))
+ if (entry->obj)
+ {
+ if (pdf_objcmp(ctx, entry->obj, obj))
fz_warn(ctx, "Encountered new definition for object %d - keeping the original one", numbuf[i]);
- pdf_drop_obj(obj);
- } else
+ pdf_drop_obj(ctx, obj);
+ }
+ else
entry->obj = obj;
+ if (numbuf[i] == target)
+ ret_entry = entry;
}
else
{
- pdf_drop_obj(obj);
+ pdf_drop_obj(ctx, obj);
}
}
}
fz_always(ctx)
{
- fz_close(stm);
+ fz_drop_stream(ctx, stm);
fz_free(ctx, ofsbuf);
fz_free(ctx, numbuf);
- pdf_drop_obj(objstm);
+ pdf_drop_obj(ctx, objstm);
}
fz_catch(ctx)
{
fz_rethrow_message(ctx, "cannot open object stream (%d %d R)", num, gen);
}
+ return ret_entry;
}
/*
* object loading
*/
static int
-pdf_obj_read(pdf_document *doc, int *offset, int *nump, pdf_obj **page)
+pdf_obj_read(fz_context *ctx, pdf_document *doc, int *offset, int *nump, pdf_obj **page)
{
- int num, numofs, gen, genofs, stmofs, tmpofs, tok;
pdf_lexbuf *buf = &doc->lexbuf.base;
- fz_context *ctx = doc->ctx;
+ int num, numofs, gen, genofs, stmofs, tmpofs, tok;
int xref_len;
pdf_xref_entry *entry;
int newtmpofs;
numofs = *offset;
- fz_seek(doc->file, numofs, SEEK_SET);
+ fz_seek(ctx, doc->file, numofs, SEEK_SET);
/* We expect to read 'num' here */
- tok = pdf_lex(doc->file, buf);
- genofs = fz_tell(doc->file);
+ tok = pdf_lex(ctx, doc->file, buf);
+ genofs = fz_tell(ctx, doc->file);
if (tok != PDF_TOK_INT)
{
/* Failed! */
@@ -1625,8 +1683,8 @@ pdf_obj_read(pdf_document *doc, int *offset, int *nump, pdf_obj **page)
*nump = num = buf->i;
/* We expect to read 'gen' here */
- tok = pdf_lex(doc->file, buf);
- tmpofs = fz_tell(doc->file);
+ tok = pdf_lex(ctx, doc->file, buf);
+ tmpofs = fz_tell(ctx, doc->file);
if (tok != PDF_TOK_INT)
{
/* Failed! */
@@ -1639,14 +1697,14 @@ pdf_obj_read(pdf_document *doc, int *offset, int *nump, pdf_obj **page)
/* We expect to read 'obj' here */
do
{
- tmpofs = fz_tell(doc->file);
- tok = pdf_lex(doc->file, buf);
+ tmpofs = fz_tell(ctx, doc->file);
+ tok = pdf_lex(ctx, doc->file, buf);
if (tok == PDF_TOK_OBJ)
break;
if (tok != PDF_TOK_INT)
{
DEBUGMESS((ctx, "skipping unexpected data (tok=%d) at %d", tok, tmpofs));
- *offset = fz_tell(doc->file);
+ *offset = fz_tell(ctx, doc->file);
return tok == PDF_TOK_EOF;
}
DEBUGMESS((ctx, "skipping unexpected int %d at %d", num, numofs));
@@ -1658,7 +1716,7 @@ pdf_obj_read(pdf_document *doc, int *offset, int *nump, pdf_obj **page)
while (1);
/* Now we read the actual object */
- xref_len = pdf_xref_len(doc);
+ xref_len = pdf_xref_len(ctx, doc);
/* When we are reading a progressive file, we typically see:
* File Header
@@ -1676,7 +1734,7 @@ pdf_obj_read(pdf_document *doc, int *offset, int *nump, pdf_obj **page)
* whenever we read an object it should just go into the
* previous xref.
*/
- tok = pdf_repair_obj(doc, buf, &stmofs, NULL, NULL, NULL, page, &newtmpofs);
+ tok = pdf_repair_obj(ctx, doc, buf, &stmofs, NULL, NULL, NULL, page, &newtmpofs);
do /* So we can break out of it */
{
@@ -1689,7 +1747,7 @@ pdf_obj_read(pdf_document *doc, int *offset, int *nump, pdf_obj **page)
{
fz_warn(ctx, "Unexpected non zero generation number in linearized file");
}
- entry = pdf_get_populating_xref_entry(doc, num);
+ entry = pdf_get_populating_xref_entry(ctx, doc, num);
if (entry->type != 0)
{
DEBUGMESS((ctx, "Duplicate object found (%d %d obj)", num, gen));
@@ -1699,10 +1757,10 @@ pdf_obj_read(pdf_document *doc, int *offset, int *nump, pdf_obj **page)
{
DEBUGMESS((ctx, "Successfully read object %d @ %d - and found page %d!", num, numofs, doc->linear_page_num));
if (!entry->obj)
- entry->obj = pdf_keep_obj(*page);
+ entry->obj = pdf_keep_obj(ctx, *page);
if (doc->linear_page_refs[doc->linear_page_num] == NULL)
- doc->linear_page_refs[doc->linear_page_num] = pdf_new_indirect(doc, num, gen);
+ doc->linear_page_refs[doc->linear_page_num] = pdf_new_indirect(ctx, doc, num, gen);
}
else
{
@@ -1719,7 +1777,7 @@ pdf_obj_read(pdf_document *doc, int *offset, int *nump, pdf_obj **page)
if (tok == PDF_TOK_ENDOBJ)
{
- *offset = fz_tell(doc->file);
+ *offset = fz_tell(ctx, doc->file);
}
else
{
@@ -1729,9 +1787,8 @@ pdf_obj_read(pdf_document *doc, int *offset, int *nump, pdf_obj **page)
}
static void
-pdf_load_hinted_page(pdf_document *doc, int pagenum)
+pdf_load_hinted_page(fz_context *ctx, pdf_document *doc, int pagenum)
{
- fz_context *ctx = doc->ctx;
if (!doc->hints_loaded || !doc->linear_page_refs)
return;
@@ -1742,14 +1799,14 @@ pdf_load_hinted_page(pdf_document *doc, int pagenum)
fz_try(ctx)
{
int num = doc->hint_page[pagenum].number;
- pdf_obj *page = pdf_load_object(doc, num, 0);
- if (!strcmp("Page", pdf_to_name(pdf_dict_gets(page, "Type"))))
+ pdf_obj *page = pdf_load_object(ctx, doc, num, 0);
+ if (!strcmp("Page", pdf_to_name(ctx, pdf_dict_gets(ctx, page, "Type"))))
{
/* We have found the page object! */
DEBUGMESS((ctx, "LoadHintedPage pagenum=%d num=%d", pagenum, num));
- doc->linear_page_refs[pagenum] = pdf_new_indirect(doc, num, 0);
+ doc->linear_page_refs[pagenum] = pdf_new_indirect(ctx, doc, num, 0);
}
- pdf_drop_obj(page);
+ pdf_drop_obj(ctx, page);
}
fz_catch(ctx)
{
@@ -1760,12 +1817,11 @@ pdf_load_hinted_page(pdf_document *doc, int pagenum)
}
static int
-read_hinted_object(pdf_document *doc, int num)
+read_hinted_object(fz_context *ctx, pdf_document *doc, int num)
{
/* Try to find the object using our hint table. Find the closest
* object <= the one we want that has a hint and read forward from
* there. */
- fz_context *ctx = doc->ctx;
int expected = num;
int curr_pos;
int start, offset;
@@ -1777,7 +1833,7 @@ read_hinted_object(pdf_document *doc, int num)
if (expected == 0) /* No hints found, just bale */
return 0;
- curr_pos = fz_tell(doc->file);
+ curr_pos = fz_tell(ctx, doc->file);
offset = doc->hint_obj_offsets[expected];
fz_var(expected);
@@ -1791,7 +1847,7 @@ read_hinted_object(pdf_document *doc, int num)
{
start = offset;
DEBUGMESS((ctx, "Searching for object %d @ %d", expected, offset));
- pdf_obj_read(doc, &offset, &found, 0);
+ pdf_obj_read(ctx, doc, &offset, &found, 0);
DEBUGMESS((ctx, "Found object %d - next will be @ %d", found, offset));
if (found <= expected)
{
@@ -1819,7 +1875,7 @@ read_hinted_object(pdf_document *doc, int num)
}
fz_always(ctx)
{
- fz_seek(doc->file, curr_pos, SEEK_SET);
+ fz_seek(ctx, doc->file, curr_pos, SEEK_SET);
}
fz_catch(ctx)
{
@@ -1832,38 +1888,37 @@ read_hinted_object(pdf_document *doc, int num)
return 1;
}
-void
-pdf_cache_object(pdf_document *doc, int num, int gen)
+pdf_xref_entry *
+pdf_cache_object(fz_context *ctx, pdf_document *doc, int num, int gen)
{
pdf_xref_entry *x;
int rnum, rgen, try_repair;
- fz_context *ctx = doc->ctx;
fz_var(try_repair);
- if (num <= 0 || num >= pdf_xref_len(doc))
- fz_throw(ctx, FZ_ERROR_GENERIC, "object out of range (%d %d R); xref size %d", num, gen, pdf_xref_len(doc));
+ if (num <= 0 || num >= pdf_xref_len(ctx, doc))
+ fz_throw(ctx, FZ_ERROR_GENERIC, "object out of range (%d %d R); xref size %d", num, gen, pdf_xref_len(ctx, doc));
object_updated:
try_repair = 0;
rnum = num;
- x = pdf_get_xref_entry(doc, num);
+ x = pdf_get_xref_entry(ctx, doc, num);
- if (x->obj)
- return;
+ if (x->obj != NULL)
+ return x;
if (x->type == 'f')
{
- x->obj = pdf_new_null(doc);
+ x->obj = pdf_new_null(ctx, doc);
}
else if (x->type == 'n')
{
- fz_seek(doc->file, x->ofs, SEEK_SET);
+ fz_seek(ctx, doc->file, x->ofs, SEEK_SET);
fz_try(ctx)
{
- x->obj = pdf_parse_ind_obj(doc, doc->file, &doc->lexbuf.base,
+ x->obj = pdf_parse_ind_obj(ctx, doc, doc->file, &doc->lexbuf.base,
&rnum, &rgen, &x->stm_ofs, &try_repair);
}
fz_catch(ctx)
@@ -1874,7 +1929,7 @@ object_updated:
if (!try_repair && rnum != num)
{
- pdf_drop_obj(x->obj);
+ pdf_drop_obj(ctx, x->obj);
x->obj = NULL;
try_repair = 1;
}
@@ -1883,7 +1938,8 @@ object_updated:
{
fz_try(ctx)
{
- pdf_repair_xref(doc, &doc->lexbuf.base);
+ pdf_repair_xref(ctx, doc);
+ pdf_prime_xref_index(ctx, doc);
}
fz_catch(ctx)
{
@@ -1904,18 +1960,19 @@ object_updated:
{
fz_try(ctx)
{
- pdf_load_obj_stm(doc, x->ofs, 0, &doc->lexbuf.base);
+ x = pdf_load_obj_stm(ctx, doc, x->ofs, 0, &doc->lexbuf.base, num);
}
fz_catch(ctx)
{
fz_rethrow_message(ctx, "cannot load object stream containing object (%d %d R)", num, gen);
}
- x = pdf_get_xref_entry(doc, num);
+ if (x == NULL)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "cannot load object stream containing object (%d %d R)", num, gen);
if (!x->obj)
fz_throw(ctx, FZ_ERROR_GENERIC, "object (%d %d R) was not found in its object stream", num, gen);
}
}
- else if (doc->hint_obj_offsets && read_hinted_object(doc, num))
+ else if (doc->hint_obj_offsets && read_hinted_object(ctx, doc, num))
{
goto object_updated;
}
@@ -1928,54 +1985,52 @@ object_updated:
fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find object in xref (%d %d R)", num, gen);
}
- pdf_set_obj_parent(x->obj, num);
+ pdf_set_obj_parent(ctx, x->obj, num);
+ return x;
}
pdf_obj *
-pdf_load_object(pdf_document *doc, int num, int gen)
+pdf_load_object(fz_context *ctx, pdf_document *doc, int num, int gen)
{
- fz_context *ctx = doc->ctx;
pdf_xref_entry *entry;
fz_try(ctx)
{
- pdf_cache_object(doc, num, gen);
+ entry = pdf_cache_object(ctx, doc, num, gen);
}
fz_catch(ctx)
{
fz_rethrow_message(ctx, "cannot load object (%d %d R) into cache", num, gen);
}
- entry = pdf_get_xref_entry(doc, num);
+ assert(entry->obj != NULL);
- assert(entry->obj);
-
- return pdf_keep_obj(entry->obj);
+ return pdf_keep_obj(ctx, entry->obj);
}
pdf_obj *
-pdf_resolve_indirect(pdf_obj *ref)
+pdf_resolve_indirect(fz_context *ctx, pdf_obj *ref)
{
int sanity = 10;
int num;
int gen;
- fz_context *ctx = NULL; /* Avoid warning for stupid compilers */
- pdf_document *doc;
pdf_xref_entry *entry;
- while (pdf_is_indirect(ref))
+ while (pdf_is_indirect(ctx, ref))
{
+ pdf_document *doc;
+
if (--sanity == 0)
{
fz_warn(ctx, "too many indirections (possible indirection cycle involving %d %d R)", num, gen);
return NULL;
}
- doc = pdf_get_indirect_document(ref);
+
+ doc = pdf_get_indirect_document(ctx, ref);
if (!doc)
return NULL;
- ctx = doc->ctx;
- num = pdf_to_num(ref);
- gen = pdf_to_gen(ref);
+ num = pdf_to_num(ctx, ref);
+ gen = pdf_to_gen(ctx, ref);
if (num <= 0 || gen < 0)
{
@@ -1985,7 +2040,7 @@ pdf_resolve_indirect(pdf_obj *ref)
fz_try(ctx)
{
- pdf_cache_object(doc, num, gen);
+ entry = pdf_cache_object(ctx, doc, num, gen);
}
fz_catch(ctx)
{
@@ -1993,8 +2048,8 @@ pdf_resolve_indirect(pdf_obj *ref)
fz_warn(ctx, "cannot load object (%d %d R) into cache", num, gen);
return NULL;
}
- entry = pdf_get_xref_entry(doc, num);
- if (!entry->obj)
+
+ if (entry->obj == NULL)
return NULL;
ref = entry->obj;
}
@@ -2003,18 +2058,18 @@ pdf_resolve_indirect(pdf_obj *ref)
}
int
-pdf_count_objects(pdf_document *doc)
+pdf_count_objects(fz_context *ctx, pdf_document *doc)
{
- return pdf_xref_len(doc);
+ return pdf_xref_len(ctx, doc);
}
int
-pdf_create_object(pdf_document *doc)
+pdf_create_object(fz_context *ctx, pdf_document *doc)
{
/* TODO: reuse free object slots by properly linking free object chains in the ofs field */
pdf_xref_entry *entry;
- int num = pdf_xref_len(doc);
- entry = pdf_get_incremental_xref_entry(doc, num);
+ int num = pdf_xref_len(ctx, doc);
+ entry = pdf_get_incremental_xref_entry(ctx, doc, num);
entry->type = 'f';
entry->ofs = -1;
entry->gen = 0;
@@ -2025,20 +2080,20 @@ pdf_create_object(pdf_document *doc)
}
void
-pdf_delete_object(pdf_document *doc, int num)
+pdf_delete_object(fz_context *ctx, pdf_document *doc, int num)
{
pdf_xref_entry *x;
- if (num <= 0 || num >= pdf_xref_len(doc))
+ if (num <= 0 || num >= pdf_xref_len(ctx, doc))
{
- fz_warn(doc->ctx, "object out of range (%d 0 R); xref size %d", num, pdf_xref_len(doc));
+ fz_warn(ctx, "object out of range (%d 0 R); xref size %d", num, pdf_xref_len(ctx, doc));
return;
}
- x = pdf_get_incremental_xref_entry(doc, num);
+ x = pdf_get_incremental_xref_entry(ctx, doc, num);
- fz_drop_buffer(doc->ctx, x->stm_buf);
- pdf_drop_obj(x->obj);
+ fz_drop_buffer(ctx, x->stm_buf);
+ pdf_drop_obj(ctx, x->obj);
x->type = 'f';
x->ofs = 0;
@@ -2049,46 +2104,46 @@ pdf_delete_object(pdf_document *doc, int num)
}
void
-pdf_update_object(pdf_document *doc, int num, pdf_obj *newobj)
+pdf_update_object(fz_context *ctx, pdf_document *doc, int num, pdf_obj *newobj)
{
pdf_xref_entry *x;
- if (num <= 0 || num >= pdf_xref_len(doc))
+ if (num <= 0 || num >= pdf_xref_len(ctx, doc))
{
- fz_warn(doc->ctx, "object out of range (%d 0 R); xref size %d", num, pdf_xref_len(doc));
+ fz_warn(ctx, "object out of range (%d 0 R); xref size %d", num, pdf_xref_len(ctx, doc));
return;
}
- x = pdf_get_incremental_xref_entry(doc, num);
+ x = pdf_get_incremental_xref_entry(ctx, doc, num);
- pdf_drop_obj(x->obj);
+ pdf_drop_obj(ctx, x->obj);
x->type = 'n';
x->ofs = 0;
- x->obj = pdf_keep_obj(newobj);
+ x->obj = pdf_keep_obj(ctx, newobj);
- pdf_set_obj_parent(newobj, num);
+ pdf_set_obj_parent(ctx, newobj, num);
}
void
-pdf_update_stream(pdf_document *doc, int num, fz_buffer *newbuf)
+pdf_update_stream(fz_context *ctx, pdf_document *doc, int num, fz_buffer *newbuf)
{
pdf_xref_entry *x;
- if (num <= 0 || num >= pdf_xref_len(doc))
+ if (num <= 0 || num >= pdf_xref_len(ctx, doc))
{
- fz_warn(doc->ctx, "object out of range (%d 0 R); xref size %d", num, pdf_xref_len(doc));
+ fz_warn(ctx, "object out of range (%d 0 R); xref size %d", num, pdf_xref_len(ctx, doc));
return;
}
- x = pdf_get_xref_entry(doc, num);
+ x = pdf_get_xref_entry(ctx, doc, num);
- fz_drop_buffer(doc->ctx, x->stm_buf);
- x->stm_buf = fz_keep_buffer(doc->ctx, newbuf);
+ fz_drop_buffer(ctx, x->stm_buf);
+ x->stm_buf = fz_keep_buffer(ctx, newbuf);
}
int
-pdf_meta(pdf_document *doc, int key, void *ptr, int size)
+pdf_meta(fz_context *ctx, pdf_document *doc, int key, void *ptr, int size)
{
switch (key)
{
@@ -2103,10 +2158,10 @@ pdf_meta(pdf_document *doc, int key, void *ptr, int size)
case FZ_META_CRYPT_INFO:
if (doc->crypt)
sprintf((char *)ptr, "Standard V%d R%d %d-bit %s",
- pdf_crypt_version(doc),
- pdf_crypt_revision(doc),
- pdf_crypt_length(doc),
- pdf_crypt_method(doc));
+ pdf_crypt_version(ctx, doc),
+ pdf_crypt_revision(ctx, doc),
+ pdf_crypt_length(ctx, doc),
+ pdf_crypt_method(ctx, doc));
else
sprintf((char *)ptr, "None");
return FZ_META_OK;
@@ -2130,18 +2185,18 @@ pdf_meta(pdf_document *doc, int key, void *ptr, int size)
default:
return 0;
}
- return pdf_has_permission(doc, i);
+ return pdf_has_permission(ctx, doc, i);
}
case FZ_META_INFO:
{
- pdf_obj *info = pdf_dict_gets(pdf_trailer(doc), "Info");
+ pdf_obj *info = pdf_dict_gets(ctx, pdf_trailer(ctx, doc), "Info");
if (!info)
{
if (ptr)
*(char *)ptr = 0;
return 0;
}
- info = pdf_dict_gets(info, *(char **)ptr);
+ info = pdf_dict_gets(ctx, info, *(char **)ptr);
if (!info)
{
if (ptr)
@@ -2150,9 +2205,9 @@ pdf_meta(pdf_document *doc, int key, void *ptr, int size)
}
if (info && ptr && size)
{
- char *utf8 = pdf_to_utf8(doc, info);
+ char *utf8 = pdf_to_utf8(ctx, doc, info);
fz_strlcpy(ptr, utf8, size);
- fz_free(doc->ctx, utf8);
+ fz_free(ctx, utf8);
}
return 1;
}
@@ -2162,7 +2217,7 @@ pdf_meta(pdf_document *doc, int key, void *ptr, int size)
}
fz_transition *
-pdf_page_presentation(pdf_document *doc, pdf_page *page, float *duration)
+pdf_page_presentation(fz_context *ctx, pdf_page *page, float *duration)
{
*duration = page->duration;
if (!page->transition_present)
@@ -2170,13 +2225,6 @@ pdf_page_presentation(pdf_document *doc, pdf_page *page, float *duration)
return &page->transition;
}
-static void
-pdf_rebind(pdf_document *doc, fz_context *ctx)
-{
- doc->ctx = ctx;
- fz_rebind_stream(doc->file, ctx);
-}
-
/*
Initializers for the fz_document interface.
@@ -2192,28 +2240,18 @@ pdf_new_document(fz_context *ctx, fz_stream *file)
{
pdf_document *doc = fz_malloc_struct(ctx, pdf_document);
+ doc->super.refs = 1;
doc->super.close = (fz_document_close_fn *)pdf_close_document;
doc->super.needs_password = (fz_document_needs_password_fn *)pdf_needs_password;
doc->super.authenticate_password = (fz_document_authenticate_password_fn *)pdf_authenticate_password;
doc->super.load_outline = (fz_document_load_outline_fn *)pdf_load_outline;
doc->super.count_pages = (fz_document_count_pages_fn *)pdf_count_pages;
doc->super.load_page = (fz_document_load_page_fn *)pdf_load_page;
- doc->super.load_links = (fz_document_load_links_fn *)pdf_load_links;
- doc->super.bound_page = (fz_document_bound_page_fn *)pdf_bound_page;
- doc->super.first_annot = (fz_document_first_annot_fn *)pdf_first_annot;
- doc->super.next_annot = (fz_document_next_annot_fn *)pdf_next_annot;
- doc->super.bound_annot = (fz_document_bound_annot_fn *)pdf_bound_annot;
- doc->super.run_page_contents = NULL; /* see pdf_xref_aux.c */
- doc->super.run_annot = NULL; /* see pdf_xref_aux.c */
- doc->super.free_page = (fz_document_free_page_fn *)pdf_free_page;
doc->super.meta = (fz_document_meta_fn *)pdf_meta;
- doc->super.page_presentation = (fz_document_page_presentation_fn *)pdf_page_presentation;
doc->super.write = (fz_document_write_fn *)pdf_write_document;
- doc->super.rebind = (fz_document_rebind_fn *)pdf_rebind;
pdf_lexbuf_init(ctx, &doc->lexbuf.base, PDF_LEXBUF_LARGE);
- doc->file = fz_keep_stream(file);
- doc->ctx = ctx;
+ doc->file = fz_keep_stream(ctx, file);
return doc;
}
@@ -2222,16 +2260,13 @@ pdf_document *
pdf_open_document_no_run_with_stream(fz_context *ctx, fz_stream *file)
{
pdf_document *doc = pdf_new_document(ctx, file);
-
- fz_var(doc);
-
fz_try(ctx)
{
- pdf_init_document(doc);
+ pdf_init_document(ctx, doc);
}
fz_catch(ctx)
{
- pdf_close_document(doc);
+ pdf_close_document(ctx, doc);
fz_rethrow_message(ctx, "cannot load document from stream");
}
return doc;
@@ -2250,26 +2285,25 @@ pdf_open_document_no_run(fz_context *ctx, const char *filename)
{
file = fz_open_file(ctx, filename);
doc = pdf_new_document(ctx, file);
- pdf_init_document(doc);
+ pdf_init_document(ctx, doc);
}
fz_always(ctx)
{
- fz_close(file);
+ fz_drop_stream(ctx, file);
}
fz_catch(ctx)
{
- pdf_close_document(doc);
+ pdf_close_document(ctx, doc);
fz_rethrow_message(ctx, "cannot load document '%s'", filename);
}
return doc;
}
static void
-pdf_load_hints(pdf_document *doc, int objnum, int gennum)
+pdf_load_hints(fz_context *ctx, pdf_document *doc, int objnum, int gennum)
{
fz_stream *stream = NULL;
pdf_obj *dict;
- fz_context *ctx = doc->ctx;
fz_var(stream);
fz_var(dict);
@@ -2286,14 +2320,14 @@ pdf_load_hints(pdf_document *doc, int objnum, int gennum)
int shared_obj_num, shared_obj_offset, shared_obj_count_page1;
int shared_obj_count_total;
int least_shared_group_len, shared_group_len_num_bits;
- int max_object_num = pdf_xref_len(doc);
+ int max_object_num = pdf_xref_len(ctx, doc);
- stream = pdf_open_stream(doc, objnum, gennum);
- dict = pdf_get_xref_entry(doc, objnum)->obj;
- if (dict == NULL || !pdf_is_dict(dict))
+ stream = pdf_open_stream(ctx, doc, objnum, gennum);
+ dict = pdf_get_xref_entry(ctx, doc, objnum)->obj;
+ if (dict == NULL || !pdf_is_dict(ctx, dict))
fz_throw(ctx, FZ_ERROR_GENERIC, "malformed hint object");
- shared_hint_offset = pdf_to_int(pdf_dict_gets(dict, "S"));
+ shared_hint_offset = pdf_to_int(ctx, pdf_dict_gets(ctx, dict, "S"));
/* Malloc the structures (use realloc to cope with the fact we
* may try this several times before enough data is loaded) */
@@ -2304,45 +2338,45 @@ pdf_load_hints(pdf_document *doc, int objnum, int gennum)
doc->hint_obj_offsets_max = max_object_num;
/* Read the page object hints table: Header first */
- least_num_page_objs = fz_read_bits(stream, 32);
+ least_num_page_objs = fz_read_bits(ctx, stream, 32);
/* The following is sometimes a lie, but we read this version,
* as other table values are built from it. In
* pdf_reference17.pdf, this points to 2 objects before the
* first pages page object. */
- doc->hint_page[0].offset = fz_read_bits(stream, 32);
+ doc->hint_page[0].offset = fz_read_bits(ctx, stream, 32);
if (doc->hint_page[0].offset > doc->hint_object_offset)
doc->hint_page[0].offset += doc->hint_object_length;
- page_obj_num_bits = fz_read_bits(stream, 16);
- least_page_len = fz_read_bits(stream, 32);
- page_len_num_bits = fz_read_bits(stream, 16);
- /* least_page_offset = */ (void) fz_read_bits(stream, 32);
- /* page_offset_num_bits = */ (void) fz_read_bits(stream, 16);
- /* least_content_stream_len = */ (void) fz_read_bits(stream, 32);
- /* content_stream_len_num_bits = */ (void) fz_read_bits(stream, 16);
- num_shared_obj_num_bits = fz_read_bits(stream, 16);
- shared_obj_num_bits = fz_read_bits(stream, 16);
- /* numerator_bits = */ (void) fz_read_bits(stream, 16);
- /* denominator_bits = */ (void) fz_read_bits(stream, 16);
+ page_obj_num_bits = fz_read_bits(ctx, stream, 16);
+ least_page_len = fz_read_bits(ctx, stream, 32);
+ page_len_num_bits = fz_read_bits(ctx, stream, 16);
+ /* least_page_offset = */ (void) fz_read_bits(ctx, stream, 32);
+ /* page_offset_num_bits = */ (void) fz_read_bits(ctx, stream, 16);
+ /* least_content_stream_len = */ (void) fz_read_bits(ctx, stream, 32);
+ /* content_stream_len_num_bits = */ (void) fz_read_bits(ctx, stream, 16);
+ num_shared_obj_num_bits = fz_read_bits(ctx, stream, 16);
+ shared_obj_num_bits = fz_read_bits(ctx, stream, 16);
+ /* numerator_bits = */ (void) fz_read_bits(ctx, stream, 16);
+ /* denominator_bits = */ (void) fz_read_bits(ctx, stream, 16);
/* Item 1: Page object numbers */
doc->hint_page[0].number = doc->linear_page1_obj_num;
/* We don't care about the number of objects in the first page */
- (void)fz_read_bits(stream, page_obj_num_bits);
+ (void)fz_read_bits(ctx, stream, page_obj_num_bits);
j = 1;
for (i = 1; i < doc->page_count; i++)
{
- int delta_page_objs = fz_read_bits(stream, page_obj_num_bits);
+ int delta_page_objs = fz_read_bits(ctx, stream, page_obj_num_bits);
doc->hint_page[i].number = j;
j += least_num_page_objs + delta_page_objs;
}
doc->hint_page[i].number = j; /* Not a real page object */
- fz_sync_bits(stream);
+ fz_sync_bits(ctx, stream);
/* Item 2: Page lengths */
j = doc->hint_page[0].offset;
for (i = 0; i < doc->page_count; i++)
{
- int delta_page_len = fz_read_bits(stream, page_len_num_bits);
+ int delta_page_len = fz_read_bits(ctx, stream, page_len_num_bits);
int old = j;
doc->hint_page[i].offset = j;
@@ -2351,39 +2385,39 @@ pdf_load_hints(pdf_document *doc, int objnum, int gennum)
j += doc->hint_object_length;
}
doc->hint_page[i].offset = j;
- fz_sync_bits(stream);
+ fz_sync_bits(ctx, stream);
/* Item 3: Shared references */
shared = 0;
for (i = 0; i < doc->page_count; i++)
{
- int num_shared_objs = fz_read_bits(stream, num_shared_obj_num_bits);
+ int num_shared_objs = fz_read_bits(ctx, stream, num_shared_obj_num_bits);
doc->hint_page[i].index = shared;
shared += num_shared_objs;
}
doc->hint_page[i].index = shared;
doc->hint_shared_ref = fz_resize_array(ctx, doc->hint_shared_ref, shared, sizeof(*doc->hint_shared_ref));
memset(doc->hint_shared_ref, 0, sizeof(*doc->hint_shared_ref) * shared);
- fz_sync_bits(stream);
+ fz_sync_bits(ctx, stream);
/* Item 4: Shared references */
for (i = 0; i < shared; i++)
{
- int ref = fz_read_bits(stream, shared_obj_num_bits);
+ int ref = fz_read_bits(ctx, stream, shared_obj_num_bits);
doc->hint_shared_ref[i] = ref;
}
/* Skip items 5,6,7 as we don't use them */
- fz_seek(stream, shared_hint_offset, SEEK_SET);
+ fz_seek(ctx, stream, shared_hint_offset, SEEK_SET);
/* Read the shared object hints table: Header first */
- shared_obj_num = fz_read_bits(stream, 32);
- shared_obj_offset = fz_read_bits(stream, 32);
+ shared_obj_num = fz_read_bits(ctx, stream, 32);
+ shared_obj_offset = fz_read_bits(ctx, stream, 32);
if (shared_obj_offset > doc->hint_object_offset)
shared_obj_offset += doc->hint_object_length;
- shared_obj_count_page1 = fz_read_bits(stream, 32);
- shared_obj_count_total = fz_read_bits(stream, 32);
- shared_obj_num_bits = fz_read_bits(stream, 16);
- least_shared_group_len = fz_read_bits(stream, 32);
- shared_group_len_num_bits = fz_read_bits(stream, 16);
+ shared_obj_count_page1 = fz_read_bits(ctx, stream, 32);
+ shared_obj_count_total = fz_read_bits(ctx, stream, 32);
+ shared_obj_num_bits = fz_read_bits(ctx, stream, 16);
+ least_shared_group_len = fz_read_bits(ctx, stream, 32);
+ shared_group_len_num_bits = fz_read_bits(ctx, stream, 16);
/* Sanity check the references in Item 4 above to ensure we
* don't access out of range with malicious files. */
@@ -2402,7 +2436,7 @@ pdf_load_hints(pdf_document *doc, int objnum, int gennum)
j = doc->hint_page[0].offset;
for (i = 0; i < shared_obj_count_page1; i++)
{
- int off = fz_read_bits(stream, shared_group_len_num_bits);
+ int off = fz_read_bits(ctx, stream, shared_group_len_num_bits);
int old = j;
doc->hint_shared[i].offset = j;
j += off + least_shared_group_len;
@@ -2415,7 +2449,7 @@ pdf_load_hints(pdf_document *doc, int objnum, int gennum)
j = shared_obj_offset;
for (; i < shared_obj_count_total; i++)
{
- int off = fz_read_bits(stream, shared_group_len_num_bits);
+ int off = fz_read_bits(ctx, stream, shared_group_len_num_bits);
int old = j;
doc->hint_shared[i].offset = j;
j += off + least_shared_group_len;
@@ -2423,34 +2457,34 @@ pdf_load_hints(pdf_document *doc, int objnum, int gennum)
j += doc->hint_object_length;
}
doc->hint_shared[i].offset = j;
- fz_sync_bits(stream);
+ fz_sync_bits(ctx, stream);
/* Item 2: Signature flags: read these just so we can skip */
for (i = 0; i < shared_obj_count_total; i++)
{
- doc->hint_shared[i].number = fz_read_bits(stream, 1);
+ doc->hint_shared[i].number = fz_read_bits(ctx, stream, 1);
}
- fz_sync_bits(stream);
+ fz_sync_bits(ctx, stream);
/* Item 3: Signatures: just skip */
for (i = 0; i < shared_obj_count_total; i++)
{
if (doc->hint_shared[i].number)
{
- (void) fz_read_bits(stream, 128);
+ (void) fz_read_bits(ctx, stream, 128);
}
}
- fz_sync_bits(stream);
+ fz_sync_bits(ctx, stream);
/* Item 4: Shared object object numbers */
j = doc->linear_page1_obj_num; /* FIXME: This is a lie! */
for (i = 0; i < shared_obj_count_page1; i++)
{
doc->hint_shared[i].number = j;
- j += fz_read_bits(stream, shared_obj_num_bits) + 1;
+ j += fz_read_bits(ctx, stream, shared_obj_num_bits) + 1;
}
j = shared_obj_num;
for (; i < shared_obj_count_total; i++)
{
doc->hint_shared[i].number = j;
- j += fz_read_bits(stream, shared_obj_num_bits) + 1;
+ j += fz_read_bits(ctx, stream, shared_obj_num_bits) + 1;
}
doc->hint_shared[i].number = j;
@@ -2466,7 +2500,7 @@ pdf_load_hints(pdf_document *doc, int objnum, int gennum)
}
fz_always(ctx)
{
- fz_close(stream);
+ fz_drop_stream(ctx, stream);
}
fz_catch(ctx)
{
@@ -2482,14 +2516,13 @@ pdf_load_hints(pdf_document *doc, int objnum, int gennum)
}
static void
-pdf_load_hint_object(pdf_document *doc)
+pdf_load_hint_object(fz_context *ctx, pdf_document *doc)
{
- fz_context *ctx = doc->ctx;
pdf_lexbuf *buf = &doc->lexbuf.base;
int curr_pos;
- curr_pos = fz_tell(doc->file);
- fz_seek(doc->file, doc->hint_object_offset, SEEK_SET);
+ curr_pos = fz_tell(ctx, doc->file);
+ fz_seek(ctx, doc->file, doc->hint_object_offset, SEEK_SET);
fz_try(ctx)
{
while (1)
@@ -2497,24 +2530,24 @@ pdf_load_hint_object(pdf_document *doc)
pdf_obj *page = NULL;
int tmpofs, num, gen, tok;
- tok = pdf_lex(doc->file, buf);
+ tok = pdf_lex(ctx, doc->file, buf);
if (tok != PDF_TOK_INT)
break;
num = buf->i;
- tok = pdf_lex(doc->file, buf);
+ tok = pdf_lex(ctx, doc->file, buf);
if (tok != PDF_TOK_INT)
break;
gen = buf->i;
- tok = pdf_lex(doc->file, buf);
+ tok = pdf_lex(ctx, doc->file, buf);
if (tok != PDF_TOK_OBJ)
break;
- (void)pdf_repair_obj(doc, buf, &tmpofs, NULL, NULL, NULL, &page, &tmpofs);
- pdf_load_hints(doc, num, gen);
+ (void)pdf_repair_obj(ctx, doc, buf, &tmpofs, NULL, NULL, NULL, &page, &tmpofs);
+ pdf_load_hints(ctx, doc, num, gen);
}
}
fz_always(ctx)
{
- fz_seek(doc->file, curr_pos, SEEK_SET);
+ fz_seek(ctx, doc->file, curr_pos, SEEK_SET);
}
fz_catch(ctx)
{
@@ -2522,17 +2555,16 @@ pdf_load_hint_object(pdf_document *doc)
}
}
-pdf_obj *pdf_progressive_advance(pdf_document *doc, int pagenum)
+pdf_obj *pdf_progressive_advance(fz_context *ctx, pdf_document *doc, int pagenum)
{
- fz_context *ctx = doc->ctx;
pdf_lexbuf *buf = &doc->lexbuf.base;
int curr_pos;
pdf_obj *page;
- pdf_load_hinted_page(doc, pagenum);
+ pdf_load_hinted_page(ctx, doc, pagenum);
if (pagenum < 0 || pagenum >= doc->page_count)
- fz_throw(doc->ctx, FZ_ERROR_GENERIC, "page load out of range (%d of %d)", pagenum, doc->page_count);
+ fz_throw(ctx, FZ_ERROR_GENERIC, "page load out of range (%d of %d)", pagenum, doc->page_count);
if (doc->linear_pos == doc->file_length)
return doc->linear_page_refs[pagenum];
@@ -2541,11 +2573,11 @@ pdf_obj *pdf_progressive_advance(pdf_document *doc, int pagenum)
if (pagenum > 0 && !doc->hints_loaded && doc->hint_object_offset > 0 && doc->linear_pos >= doc->hint_object_offset)
{
/* Found hint object */
- pdf_load_hint_object(doc);
+ pdf_load_hint_object(ctx, doc);
}
DEBUGMESS((ctx, "continuing to try to advance from %d", doc->linear_pos));
- curr_pos = fz_tell(doc->file);
+ curr_pos = fz_tell(ctx, doc->file);
fz_var(page);
@@ -2556,8 +2588,8 @@ pdf_obj *pdf_progressive_advance(pdf_document *doc, int pagenum)
{
int num;
page = NULL;
- eof = pdf_obj_read(doc, &doc->linear_pos, &num, &page);
- pdf_drop_obj(page);
+ eof = pdf_obj_read(ctx, doc, &doc->linear_pos, &num, &page);
+ pdf_drop_obj(ctx, page);
page = NULL;
}
while (!eof);
@@ -2566,22 +2598,22 @@ pdf_obj *pdf_progressive_advance(pdf_document *doc, int pagenum)
pdf_obj *catalog;
pdf_obj *pages;
doc->linear_pos = doc->file_length;
- pdf_load_xref(doc, buf);
- catalog = pdf_dict_gets(pdf_trailer(doc), "Root");
- pages = pdf_dict_gets(catalog, "Pages");
+ pdf_load_xref(ctx, doc, buf);
+ catalog = pdf_dict_gets(ctx, pdf_trailer(ctx, doc), "Root");
+ pages = pdf_dict_gets(ctx, catalog, "Pages");
- if (!pdf_is_dict(pages))
+ if (!pdf_is_dict(ctx, pages))
fz_throw(ctx, FZ_ERROR_GENERIC, "missing page tree");
break;
}
}
fz_always(ctx)
{
- fz_seek(doc->file, curr_pos, SEEK_SET);
+ fz_seek(ctx, doc->file, curr_pos, SEEK_SET);
}
fz_catch(ctx)
{
- pdf_drop_obj(page);
+ pdf_drop_obj(ctx, page);
if (fz_caught(ctx) == FZ_ERROR_TRYLATER)
{
if (doc->linear_page_refs[pagenum] == NULL)
@@ -2597,7 +2629,7 @@ pdf_obj *pdf_progressive_advance(pdf_document *doc, int pagenum)
return doc->linear_page_refs[pagenum];
}
-pdf_document *pdf_specifics(fz_document *doc)
+pdf_document *pdf_specifics(fz_context *ctx, fz_document *doc)
{
return (pdf_document *)((doc && doc->close == (fz_document_close_fn *)pdf_close_document) ? doc : NULL);
}
@@ -2620,29 +2652,29 @@ pdf_document *pdf_create_document(fz_context *ctx)
doc->file_size = 0;
doc->startxref = 0;
doc->num_xref_sections = 0;
- pdf_get_populating_xref_entry(doc, 0);
+ pdf_get_populating_xref_entry(ctx, doc, 0);
doc->xref_altered = 1;
- trailer = pdf_new_dict(doc, 2);
- pdf_dict_puts_drop(trailer, "Size", pdf_new_int(doc, 3));
- o = root = pdf_new_dict(doc, 2);
- pdf_dict_puts_drop(trailer, "Root", pdf_new_ref(doc, o));
- pdf_drop_obj(o);
+ trailer = pdf_new_dict(ctx, doc, 2);
+ pdf_dict_puts_drop(ctx, trailer, "Size", pdf_new_int(ctx, doc, 3));
+ o = root = pdf_new_dict(ctx, doc, 2);
+ pdf_dict_puts_drop(ctx, trailer, "Root", pdf_new_ref(ctx, doc, o));
+ pdf_drop_obj(ctx, o);
o = NULL;
- pdf_dict_puts_drop(root, "Type", pdf_new_name(doc, "Catalog"));
- o = pages = pdf_new_dict(doc, 3);
- pdf_dict_puts_drop(root, "Pages", pdf_new_ref(doc, o));
- pdf_drop_obj(o);
+ pdf_dict_puts_drop(ctx, root, "Type", pdf_new_name(ctx, doc, "Catalog"));
+ o = pages = pdf_new_dict(ctx, doc, 3);
+ pdf_dict_puts_drop(ctx, root, "Pages", pdf_new_ref(ctx, doc, o));
+ pdf_drop_obj(ctx, o);
o = NULL;
- pdf_dict_puts_drop(pages, "Type", pdf_new_name(doc, "Pages"));
- pdf_dict_puts_drop(pages, "Count", pdf_new_int(doc, 0));
- pdf_dict_puts_drop(pages, "Kids", pdf_new_array(doc, 1));
- pdf_set_populating_xref_trailer(doc, trailer);
- pdf_drop_obj(trailer);
+ pdf_dict_puts_drop(ctx, pages, "Type", pdf_new_name(ctx, doc, "Pages"));
+ pdf_dict_puts_drop(ctx, pages, "Count", pdf_new_int(ctx, doc, 0));
+ pdf_dict_puts_drop(ctx, pages, "Kids", pdf_new_array(ctx, doc, 1));
+ pdf_set_populating_xref_trailer(ctx, doc, trailer);
+ pdf_drop_obj(ctx, trailer);
}
fz_catch(ctx)
{
- pdf_drop_obj(trailer);
- pdf_drop_obj(o);
+ pdf_drop_obj(ctx, trailer);
+ pdf_drop_obj(ctx, o);
fz_rethrow_message(ctx, "Failed to create empty document");
}
return doc;
@@ -2671,7 +2703,7 @@ fz_document_handler pdf_no_run_document_handler =
(fz_document_open_with_stream_fn *)&pdf_open_document_no_run_with_stream
};
-void pdf_mark_xref(pdf_document *doc)
+void pdf_mark_xref(fz_context *ctx, pdf_document *doc)
{
int x, e;
@@ -2694,7 +2726,7 @@ void pdf_mark_xref(pdf_document *doc)
}
}
-void pdf_clear_xref(pdf_document *doc)
+void pdf_clear_xref(fz_context *ctx, pdf_document *doc)
{
int x, e;
@@ -2712,9 +2744,9 @@ void pdf_clear_xref(pdf_document *doc)
* buffer has been updated */
if (entry->obj != NULL && entry->stm_buf == NULL)
{
- if (pdf_obj_refs(entry->obj) == 1)
+ if (pdf_obj_refs(ctx, entry->obj) == 1)
{
- pdf_drop_obj(entry->obj);
+ pdf_drop_obj(ctx, entry->obj);
entry->obj = NULL;
}
}
@@ -2723,7 +2755,7 @@ void pdf_clear_xref(pdf_document *doc)
}
}
-void pdf_clear_xref_to_mark(pdf_document *doc)
+void pdf_clear_xref_to_mark(fz_context *ctx, pdf_document *doc)
{
int x, e;
@@ -2742,9 +2774,9 @@ void pdf_clear_xref_to_mark(pdf_document *doc)
* been updated */
if (entry->obj != NULL && entry->stm_buf == NULL)
{
- if ((entry->flags & PDF_OBJ_FLAG_MARK) == 0 && pdf_obj_refs(entry->obj) == 1)
+ if ((entry->flags & PDF_OBJ_FLAG_MARK) == 0 && pdf_obj_refs(ctx, entry->obj) == 1)
{
- pdf_drop_obj(entry->obj);
+ pdf_drop_obj(ctx, entry->obj);
entry->obj = NULL;
}
}