summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor.andersson@artifex.com>2011-04-05 01:18:03 +0200
committerTor Andersson <tor.andersson@artifex.com>2011-04-05 01:18:03 +0200
commit69875363f1766f95c35c1fe429dd85ac9a19add5 (patch)
tree1204d27eadd066a37075c093befdb1973b2e71ce
parentd2de9cee6036b997e536a0c0384b88b38e523e56 (diff)
downloadmupdf-69875363f1766f95c35c1fe429dd85ac9a19add5.tar.xz
Clean up xps and pdf page access functions.
-rw-r--r--Makefile1
-rw-r--r--apps/pdfapp.c24
-rw-r--r--apps/pdfclean.c12
-rw-r--r--apps/pdfdraw.c12
-rw-r--r--apps/pdfinfo.c10
-rw-r--r--apps/pdfshow.c4
-rw-r--r--apps/xpsdraw.c10
-rw-r--r--pdf/mupdf.h8
-rw-r--r--pdf/pdf_page.c230
-rw-r--r--pdf/pdf_pagetree.c141
-rw-r--r--xps/muxps.h17
-rw-r--r--xps/xps_doc.c16
-rw-r--r--xps/xps_zip.c46
13 files changed, 251 insertions, 280 deletions
diff --git a/Makefile b/Makefile
index 30902f1a..72c9a285 100644
--- a/Makefile
+++ b/Makefile
@@ -154,7 +154,6 @@ MUPDF_SRC := \
pdf/pdf_nametree.c \
pdf/pdf_outline.c \
pdf/pdf_page.c \
- pdf/pdf_pagetree.c \
pdf/pdf_parse.c \
pdf/pdf_pattern.c \
pdf/pdf_repair.c \
diff --git a/apps/pdfapp.c b/apps/pdfapp.c
index 277bdbf0..46459497 100644
--- a/apps/pdfapp.c
+++ b/apps/pdfapp.c
@@ -159,7 +159,7 @@ static void pdfapp_open_pdf(pdfapp_t *app, char *filename, int fd)
if (error)
pdfapp_error(app, fz_rethrow(error, "cannot load page tree"));
- app->pagecount = pdf_get_page_count(app->xref);
+ app->pagecount = pdf_count_pages(app->xref);
}
static void pdfapp_open_xps(pdfapp_t *app, char *filename, int fd)
@@ -168,8 +168,7 @@ static void pdfapp_open_xps(pdfapp_t *app, char *filename, int fd)
close(fd); // TODO: fix this for windows
- app->xps = xps_new_context();
- error = xps_open_file(app->xps, filename);
+ error = xps_open_file(&app->xps, filename);
if (error)
pdfapp_error(app, fz_rethrow(error, "cannot open document: '%s'", filename));
@@ -278,10 +277,8 @@ static void pdfapp_loadpage_pdf(pdfapp_t *app)
pdf_page *page;
fz_error error;
fz_device *mdev;
- fz_obj *obj;
- obj = pdf_get_page_object(app->xref, app->pageno);
- error = pdf_load_page(&page, app->xref, obj);
+ error = pdf_load_page(&page, app->xref, app->pageno - 1);
if (error)
pdfapp_error(app, error);
@@ -310,10 +307,11 @@ static void pdfapp_loadpage_xps(pdfapp_t *app)
{
xps_page *page;
fz_device *mdev;
+ fz_error error;
- page = xps_load_page(app->xps, app->pageno - 1);
- if (!page)
- pdfapp_error(app, fz_rethrow(-1, "cannot load page %d in file '%s'", app->pageno, app->doctitle));
+ error = xps_load_page(&page, app->xps, app->pageno - 1);
+ if (error)
+ pdfapp_error(app, fz_rethrow(error, "cannot load page %d in file '%s'", app->pageno, app->doctitle));
app->page_bbox.x0 = 0;
app->page_bbox.y0 = 0;
@@ -436,9 +434,11 @@ static void pdfapp_gotouri(pdfapp_t *app, fz_obj *uri)
static void pdfapp_gotopage(pdfapp_t *app, fz_obj *obj)
{
- int page;
+ int number;
- page = pdf_find_page_object(app->xref, obj);
+ number = pdf_find_page_number(app->xref, obj);
+ if (number < 0)
+ return;
if (app->histlen + 1 == 256)
{
@@ -446,7 +446,7 @@ static void pdfapp_gotopage(pdfapp_t *app, fz_obj *obj)
app->histlen --;
}
app->hist[app->histlen++] = app->pageno;
- app->pageno = page;
+ app->pageno = number + 1;
pdfapp_showpage(app, 1, 1, 1);
}
diff --git a/apps/pdfclean.c b/apps/pdfclean.c
index 67c7809c..dd85b1a4 100644
--- a/apps/pdfclean.c
+++ b/apps/pdfclean.c
@@ -314,7 +314,7 @@ static void retainpages(int argc, char **argv)
dash = strchr(spec, '-');
if (dash == spec)
- spage = epage = pdf_get_page_count(xref);
+ spage = epage = pdf_count_pages(xref);
else
spage = epage = atoi(spec);
@@ -323,7 +323,7 @@ static void retainpages(int argc, char **argv)
if (strlen(dash) > 1)
epage = atoi(dash + 1);
else
- epage = pdf_get_page_count(xref);
+ epage = pdf_count_pages(xref);
}
if (spage > epage)
@@ -331,13 +331,13 @@ static void retainpages(int argc, char **argv)
if (spage < 1)
spage = 1;
- if (epage > pdf_get_page_count(xref))
- epage = pdf_get_page_count(xref);
+ if (epage > pdf_count_pages(xref))
+ epage = pdf_count_pages(xref);
for (page = spage; page <= epage; page++)
{
- fz_obj *pageobj = pdf_get_page_object(xref, page);
- fz_obj *pageref = pdf_get_page_ref(xref, page);
+ fz_obj *pageobj = xref->page_objs[page-1];
+ fz_obj *pageref = xref->page_refs[page-1];
fz_dict_puts(pageobj, "Parent", parent);
diff --git a/apps/pdfdraw.c b/apps/pdfdraw.c
index f15fdfb4..baaac92c 100644
--- a/apps/pdfdraw.c
+++ b/apps/pdfdraw.c
@@ -87,7 +87,6 @@ static int isrange(char *s)
static void drawpage(pdf_xref *xref, int pagenum)
{
fz_error error;
- fz_obj *pageobj;
pdf_page *page;
fz_display_list *list;
fz_device *dev;
@@ -98,8 +97,7 @@ static void drawpage(pdf_xref *xref, int pagenum)
start = gettime();
}
- pageobj = pdf_get_page_object(xref, pagenum);
- error = pdf_load_page(&page, xref, pageobj);
+ error = pdf_load_page(&page, xref, pagenum - 1);
if (error)
die(fz_rethrow(error, "cannot load page %d in file '%s'", pagenum, filename));
@@ -253,7 +251,7 @@ static void drawrange(pdf_xref *xref, char *range)
dash = strchr(spec, '-');
if (dash == spec)
- spage = epage = pdf_get_page_count(xref);
+ spage = epage = pdf_count_pages(xref);
else
spage = epage = atoi(spec);
@@ -262,11 +260,11 @@ static void drawrange(pdf_xref *xref, char *range)
if (strlen(dash) > 1)
epage = atoi(dash + 1);
else
- epage = pdf_get_page_count(xref);
+ epage = pdf_count_pages(xref);
}
- spage = CLAMP(spage, 1, pdf_get_page_count(xref));
- epage = CLAMP(epage, 1, pdf_get_page_count(xref));
+ spage = CLAMP(spage, 1, pdf_count_pages(xref));
+ epage = CLAMP(epage, 1, pdf_count_pages(xref));
if (spage < epage)
for (page = spage; page <= epage; page++)
diff --git a/apps/pdfinfo.c b/apps/pdfinfo.c
index fcc2cb38..d8948264 100644
--- a/apps/pdfinfo.c
+++ b/apps/pdfinfo.c
@@ -569,8 +569,8 @@ gatherresourceinfo(int page, fz_obj *rsrc)
fz_obj *subrsrc;
int i;
- pageobj = pdf_get_page_object(xref, page);
- pageref = pdf_get_page_ref(xref, page);
+ pageobj = xref->page_objs[page-1];
+ pageref = xref->page_refs[page-1];
if (!pageobj)
die(fz_throw("cannot retrieve info from page %d", page));
@@ -632,8 +632,8 @@ gatherpageinfo(int page)
fz_obj *pageref;
fz_obj *rsrc;
- pageobj = pdf_get_page_object(xref, page);
- pageref = pdf_get_page_ref(xref, page);
+ pageobj = xref->page_objs[page-1];
+ pageref = xref->page_refs[page-1];
if (!pageobj)
die(fz_throw("cannot retrieve info from page %d", page));
@@ -988,7 +988,7 @@ int main(int argc, char **argv)
error = pdf_load_page_tree(xref);
if (error)
die(fz_rethrow(error, "cannot load page tree: %s", filename));
- pagecount = pdf_get_page_count(xref);
+ pagecount = pdf_count_pages(xref);
showglobalinfo();
state = NO_INFO_GATHERED;
diff --git a/apps/pdfshow.c b/apps/pdfshow.c
index 4c834035..5e74042b 100644
--- a/apps/pdfshow.c
+++ b/apps/pdfshow.c
@@ -61,10 +61,10 @@ static void showpagetree(void)
die(fz_rethrow(error, "cannot load page tree"));
}
- count = pdf_get_page_count(xref);
+ count = pdf_count_pages(xref);
for (i = 0; i < count; i++)
{
- ref = pdf_get_page_ref(xref, i + 1);
+ ref = xref->page_refs[i];
printf("page %d = %d %d R\n", i + 1, fz_to_num(ref), fz_to_gen(ref));
}
printf("\n");
diff --git a/apps/xpsdraw.c b/apps/xpsdraw.c
index 41d01c14..29738e6b 100644
--- a/apps/xpsdraw.c
+++ b/apps/xpsdraw.c
@@ -90,15 +90,16 @@ static void drawpage(xps_context *ctx, int pagenum)
fz_display_list *list;
fz_device *dev;
int start;
+ int code;
if (showtime)
{
start = gettime();
}
- page = xps_load_page(ctx, pagenum - 1);
- if (!page)
- die(fz_throw("cannot load page %d in file '%s'", pagenum, filename));
+ code = xps_load_page(&page, ctx, pagenum - 1);
+ if (code)
+ die(fz_rethrow(code, "cannot load page %d in file '%s'", pagenum, filename));
list = NULL;
@@ -333,8 +334,7 @@ int main(int argc, char **argv)
{
filename = argv[fz_optind++];
- ctx = xps_new_context();
- code = xps_open_file(ctx, filename);
+ code = xps_open_file(&ctx, filename);
if (code)
die(fz_rethrow(code, "cannot open document: %s", filename));
diff --git a/pdf/mupdf.h b/pdf/mupdf.h
index 96ac2da3..daee0396 100644
--- a/pdf/mupdf.h
+++ b/pdf/mupdf.h
@@ -522,13 +522,11 @@ struct pdf_page_s
/* pagetree.c */
fz_error pdf_load_page_tree(pdf_xref *xref);
-int pdf_get_page_count(pdf_xref *xref);
-fz_obj *pdf_get_page_object(pdf_xref *xref, int p);
-fz_obj *pdf_get_page_ref(pdf_xref *xref, int p);
-int pdf_find_page_object(pdf_xref *xref, fz_obj *pageobj);
+int pdf_find_page_number(pdf_xref *xref, fz_obj *pageobj);
+int pdf_count_pages(pdf_xref *xref);
/* page.c */
-fz_error pdf_load_page(pdf_page **pagep, pdf_xref *xref, fz_obj *ref);
+fz_error pdf_load_page(pdf_page **pagep, pdf_xref *xref, int number);
void pdf_free_page(pdf_page *page);
/*
diff --git a/pdf/pdf_page.c b/pdf/pdf_page.c
index 685ec3ae..39cae41d 100644
--- a/pdf/pdf_page.c
+++ b/pdf/pdf_page.c
@@ -1,67 +1,123 @@
#include "fitz.h"
#include "mupdf.h"
-/* we need to combine all sub-streams into one for the content stream interpreter */
+struct info
+{
+ fz_obj *resources;
+ fz_obj *mediabox;
+ fz_obj *cropbox;
+ fz_obj *rotate;
+};
+
+int
+pdf_count_pages(pdf_xref *xref)
+{
+ return xref->page_len;
+}
-static fz_error
-pdf_load_page_contents_array(fz_buffer **bigbufp, pdf_xref *xref, fz_obj *list)
+int
+pdf_find_page_number(pdf_xref *xref, fz_obj *page)
{
- fz_error error;
- fz_buffer *big;
- fz_buffer *one;
- int i;
+ int i, num = fz_to_num(page);
+ for (i = 0; i < xref->page_len; i++)
+ if (num == fz_to_num(xref->page_refs[i]))
+ return i;
+ return -1;
+}
- pdf_log_page("multiple content streams: %d\n", fz_array_len(list));
+static void
+pdf_load_page_tree_node(pdf_xref *xref, fz_obj *node, struct info info)
+{
+ fz_obj *dict, *kids, *count;
+ fz_obj *obj, *tmp;
+ int i, n;
- /* TODO: openstream, read, close into big buffer at once */
+ /* prevent infinite recursion */
+ if (fz_dict_gets(node, ".seen"))
+ return;
- big = fz_new_buffer(32 * 1024);
+ kids = fz_dict_gets(node, "Kids");
+ count = fz_dict_gets(node, "Count");
- for (i = 0; i < fz_array_len(list); i++)
+ if (fz_is_array(kids) && fz_is_int(count))
{
- fz_obj *stm = fz_array_get(list, i);
- error = pdf_load_stream(&one, xref, fz_to_num(stm), fz_to_gen(stm));
- if (error)
+ obj = fz_dict_gets(node, "Resources");
+ if (obj)
+ info.resources = obj;
+ obj = fz_dict_gets(node, "MediaBox");
+ if (obj)
+ info.mediabox = obj;
+ obj = fz_dict_gets(node, "CropBox");
+ if (obj)
+ info.cropbox = obj;
+ obj = fz_dict_gets(node, "Rotate");
+ if (obj)
+ info.rotate = obj;
+
+ tmp = fz_new_null();
+ fz_dict_puts(node, ".seen", tmp);
+ fz_drop_obj(tmp);
+
+ n = fz_array_len(kids);
+ for (i = 0; i < n; i++)
{
- fz_drop_buffer(big);
- return fz_rethrow(error, "cannot load content stream part %d/%d (%d %d R)", i + 1, fz_array_len(list), fz_to_num(stm), fz_to_gen(stm));
+ obj = fz_array_get(kids, i);
+ pdf_load_page_tree_node(xref, obj, info);
}
- if (big->len + one->len + 1 > big->cap)
- fz_resize_buffer(big, big->len + one->len + 1);
- memcpy(big->data + big->len, one->data, one->len);
- big->data[big->len + one->len] = ' ';
- big->len += one->len + 1;
-
- fz_drop_buffer(one);
+ fz_dict_dels(node, ".seen");
}
+ else
+ {
+ dict = fz_resolve_indirect(node);
+
+ if (info.resources && !fz_dict_gets(dict, "Resources"))
+ fz_dict_puts(dict, "Resources", info.resources);
+ if (info.mediabox && !fz_dict_gets(dict, "MediaBox"))
+ fz_dict_puts(dict, "MediaBox", info.mediabox);
+ if (info.cropbox && !fz_dict_gets(dict, "CropBox"))
+ fz_dict_puts(dict, "CropBox", info.cropbox);
+ if (info.rotate && !fz_dict_gets(dict, "Rotate"))
+ fz_dict_puts(dict, "Rotate", info.rotate);
+
+ if (xref->page_len == xref->page_cap)
+ {
+ fz_warn("found more pages than expected");
+ xref->page_cap ++;
+ xref->page_refs = fz_realloc(xref->page_refs, xref->page_cap, sizeof(fz_obj*));
+ xref->page_objs = fz_realloc(xref->page_objs, xref->page_cap, sizeof(fz_obj*));
+ }
- *bigbufp = big;
- return fz_okay;
+ xref->page_refs[xref->page_len] = fz_keep_obj(node);
+ xref->page_objs[xref->page_len] = fz_keep_obj(dict);
+ xref->page_len ++;
+ }
}
-static fz_error
-pdf_load_page_contents(fz_buffer **bufp, pdf_xref *xref, fz_obj *obj)
+fz_error
+pdf_load_page_tree(pdf_xref *xref)
{
- fz_error error;
+ struct info info;
+ fz_obj *catalog = fz_dict_gets(xref->trailer, "Root");
+ fz_obj *pages = fz_dict_gets(catalog, "Pages");
+ fz_obj *count = fz_dict_gets(pages, "Count");
- if (fz_is_array(obj))
- {
- error = pdf_load_page_contents_array(bufp, xref, obj);
- if (error)
- return fz_rethrow(error, "cannot load content stream array (%d 0 R)", fz_to_num(obj));
- }
- else if (pdf_is_stream(xref, fz_to_num(obj), fz_to_gen(obj)))
- {
- error = pdf_load_stream(bufp, xref, fz_to_num(obj), fz_to_gen(obj));
- if (error)
- return fz_rethrow(error, "cannot load content stream (%d 0 R)", fz_to_num(obj));
- }
- else
- {
- fz_warn("page contents missing, leaving page blank");
- *bufp = fz_new_buffer(0);
- }
+ if (!fz_is_dict(pages))
+ return fz_throw("missing page tree");
+ if (!fz_is_int(count))
+ return fz_throw("missing page count");
+
+ xref->page_cap = fz_to_int(count);
+ xref->page_len = 0;
+ xref->page_refs = fz_calloc(xref->page_cap, sizeof(fz_obj*));
+ xref->page_objs = fz_calloc(xref->page_cap, sizeof(fz_obj*));
+
+ info.resources = NULL;
+ info.mediabox = NULL;
+ info.cropbox = NULL;
+ info.rotate = NULL;
+
+ pdf_load_page_tree_node(xref, pages, info);
return fz_okay;
}
@@ -149,21 +205,92 @@ found:
return 1;
}
+/* we need to combine all sub-streams into one for the content stream interpreter */
+
+static fz_error
+pdf_load_page_contents_array(fz_buffer **bigbufp, pdf_xref *xref, fz_obj *list)
+{
+ fz_error error;
+ fz_buffer *big;
+ fz_buffer *one;
+ int i;
+
+ pdf_log_page("multiple content streams: %d\n", fz_array_len(list));
+
+ /* TODO: openstream, read, close into big buffer at once */
+
+ big = fz_new_buffer(32 * 1024);
+
+ for (i = 0; i < fz_array_len(list); i++)
+ {
+ fz_obj *stm = fz_array_get(list, i);
+ error = pdf_load_stream(&one, xref, fz_to_num(stm), fz_to_gen(stm));
+ if (error)
+ {
+ fz_drop_buffer(big);
+ return fz_rethrow(error, "cannot load content stream part %d/%d (%d 0 R)",
+ i + 1, fz_array_len(list), fz_to_num(stm));
+ }
+
+ if (big->len + one->len + 1 > big->cap)
+ fz_resize_buffer(big, big->len + one->len + 1);
+ memcpy(big->data + big->len, one->data, one->len);
+ big->data[big->len + one->len] = ' ';
+ big->len += one->len + 1;
+
+ fz_drop_buffer(one);
+ }
+
+ *bigbufp = big;
+ return fz_okay;
+}
+
+static fz_error
+pdf_load_page_contents(fz_buffer **bufp, pdf_xref *xref, fz_obj *obj)
+{
+ fz_error error;
+
+ if (fz_is_array(obj))
+ {
+ error = pdf_load_page_contents_array(bufp, xref, obj);
+ if (error)
+ return fz_rethrow(error, "cannot load content stream array (%d 0 R)", fz_to_num(obj));
+ }
+ else if (pdf_is_stream(xref, fz_to_num(obj), fz_to_gen(obj)))
+ {
+ error = pdf_load_stream(bufp, xref, fz_to_num(obj), fz_to_gen(obj));
+ if (error)
+ return fz_rethrow(error, "cannot load content stream (%d 0 R)", fz_to_num(obj));
+ }
+ else
+ {
+ fz_warn("page contents missing, leaving page blank");
+ *bufp = fz_new_buffer(0);
+ }
+
+ return fz_okay;
+}
+
fz_error
-pdf_load_page(pdf_page **pagep, pdf_xref *xref, fz_obj *dict)
+pdf_load_page(pdf_page **pagep, pdf_xref *xref, int number)
{
fz_error error;
pdf_page *page;
+ fz_obj *dict;
fz_obj *obj;
fz_bbox bbox;
+ if (number < 0 || number >= xref->page_len)
+ return fz_throw("cannot find page %d", number + 1);
+
pdf_log_page("load page {\n");
- // TODO: move this to a more appropriate place
/* Ensure that we have a store for resource objects */
if (!xref->store)
xref->store = pdf_new_store();
+ dict = xref->page_objs[number];
+
page = fz_malloc(sizeof(pdf_page));
page->resources = NULL;
page->contents = NULL;
@@ -175,7 +302,7 @@ pdf_load_page(pdf_page **pagep, pdf_xref *xref, fz_obj *dict)
bbox = fz_round_rect(pdf_to_rect(obj));
if (fz_is_empty_rect(pdf_to_rect(obj)))
{
- fz_warn("cannot find page bounds, guessing page bounds.");
+ fz_warn("cannot find page size for page %d", number + 1);
bbox.x0 = 0;
bbox.y0 = 0;
bbox.x1 = 612;
@@ -195,7 +322,10 @@ pdf_load_page(pdf_page **pagep, pdf_xref *xref, fz_obj *dict)
page->mediabox.y1 = MAX(bbox.y0, bbox.y1);
if (page->mediabox.x1 - page->mediabox.x0 < 1 || page->mediabox.y1 - page->mediabox.y0 < 1)
- return fz_throw("invalid page size");
+ {
+ fz_warn("invalid page size in page %d", number + 1);
+ page->mediabox = fz_unit_rect;
+ }
page->rotate = fz_to_int(fz_dict_gets(dict, "Rotate"));
@@ -218,7 +348,7 @@ pdf_load_page(pdf_page **pagep, pdf_xref *xref, fz_obj *dict)
if (error)
{
pdf_free_page(page);
- return fz_rethrow(error, "cannot load page contents (%d %d R)", fz_to_num(obj), fz_to_gen(obj));
+ return fz_rethrow(error, "cannot load page contents for page %d (%d 0 R)", number + 1, fz_to_num(obj));
}
if (page->resources && pdf_resources_use_blending(page->resources))
diff --git a/pdf/pdf_pagetree.c b/pdf/pdf_pagetree.c
deleted file mode 100644
index 9320bb9c..00000000
--- a/pdf/pdf_pagetree.c
+++ /dev/null
@@ -1,141 +0,0 @@
-#include "fitz.h"
-#include "mupdf.h"
-
-struct info
-{
- fz_obj *resources;
- fz_obj *mediabox;
- fz_obj *cropbox;
- fz_obj *rotate;
-};
-
-int
-pdf_get_page_count(pdf_xref *xref)
-{
- return xref->page_len;
-}
-
-fz_obj *
-pdf_get_page_object(pdf_xref *xref, int number)
-{
- if (number > 0 && number <= xref->page_len)
- return xref->page_objs[number - 1];
- return NULL;
-}
-
-fz_obj *
-pdf_get_page_ref(pdf_xref *xref, int number)
-{
- if (number > 0 && number <= xref->page_len)
- return xref->page_refs[number - 1];
- return NULL;
-}
-
-int
-pdf_find_page_object(pdf_xref *xref, fz_obj *page)
-{
- int num = fz_to_num(page);
- int gen = fz_to_gen(page);
- int i;
- for (i = 0; i < xref->page_len; i++)
- if (num == fz_to_num(xref->page_refs[i]) && gen == fz_to_gen(xref->page_refs[i]))
- return i + 1;
- return 0;
-}
-
-static void
-pdf_load_page_tree_node(pdf_xref *xref, fz_obj *node, struct info info)
-{
- fz_obj *dict, *kids, *count;
- fz_obj *obj, *tmp;
- int i, n;
-
- /* prevent infinite recursion */
- if (fz_dict_gets(node, ".seen"))
- return;
-
- kids = fz_dict_gets(node, "Kids");
- count = fz_dict_gets(node, "Count");
-
- if (fz_is_array(kids) && fz_is_int(count))
- {
- obj = fz_dict_gets(node, "Resources");
- if (obj)
- info.resources = obj;
- obj = fz_dict_gets(node, "MediaBox");
- if (obj)
- info.mediabox = obj;
- obj = fz_dict_gets(node, "CropBox");
- if (obj)
- info.cropbox = obj;
- obj = fz_dict_gets(node, "Rotate");
- if (obj)
- info.rotate = obj;
-
- tmp = fz_new_null();
- fz_dict_puts(node, ".seen", tmp);
- fz_drop_obj(tmp);
-
- n = fz_array_len(kids);
- for (i = 0; i < n; i++)
- {
- obj = fz_array_get(kids, i);
- pdf_load_page_tree_node(xref, obj, info);
- }
-
- fz_dict_dels(node, ".seen");
- }
- else
- {
- dict = fz_resolve_indirect(node);
-
- if (info.resources && !fz_dict_gets(dict, "Resources"))
- fz_dict_puts(dict, "Resources", info.resources);
- if (info.mediabox && !fz_dict_gets(dict, "MediaBox"))
- fz_dict_puts(dict, "MediaBox", info.mediabox);
- if (info.cropbox && !fz_dict_gets(dict, "CropBox"))
- fz_dict_puts(dict, "CropBox", info.cropbox);
- if (info.rotate && !fz_dict_gets(dict, "Rotate"))
- fz_dict_puts(dict, "Rotate", info.rotate);
-
- if (xref->page_len == xref->page_cap)
- {
- fz_warn("found more pages than expected");
- xref->page_cap ++;
- xref->page_refs = fz_realloc(xref->page_refs, xref->page_cap, sizeof(fz_obj*));
- xref->page_objs = fz_realloc(xref->page_objs, xref->page_cap, sizeof(fz_obj*));
- }
-
- xref->page_refs[xref->page_len] = fz_keep_obj(node);
- xref->page_objs[xref->page_len] = fz_keep_obj(dict);
- xref->page_len ++;
- }
-}
-
-fz_error
-pdf_load_page_tree(pdf_xref *xref)
-{
- struct info info;
- fz_obj *catalog = fz_dict_gets(xref->trailer, "Root");
- fz_obj *pages = fz_dict_gets(catalog, "Pages");
- fz_obj *count = fz_dict_gets(pages, "Count");
-
- if (!fz_is_dict(pages))
- return fz_throw("missing page tree");
- if (!fz_is_int(count))
- return fz_throw("missing page count");
-
- xref->page_cap = fz_to_int(count);
- xref->page_len = 0;
- xref->page_refs = fz_calloc(xref->page_cap, sizeof(fz_obj*));
- xref->page_objs = fz_calloc(xref->page_cap, sizeof(fz_obj*));
-
- info.resources = NULL;
- info.mediabox = NULL;
- info.cropbox = NULL;
- info.rotate = NULL;
-
- pdf_load_page_tree_node(xref, pages, info);
-
- return fz_okay;
-}
diff --git a/xps/muxps.h b/xps/muxps.h
index 8a29d674..a6faec67 100644
--- a/xps/muxps.h
+++ b/xps/muxps.h
@@ -105,21 +105,17 @@ void xps_debug_page_list(xps_context *ctx);
void xps_free_page_list(xps_context *ctx);
int xps_count_pages(xps_context *ctx);
-xps_page *xps_load_page(xps_context *ctx, int number);
+int xps_load_page(xps_page **page, xps_context *ctx, int number);
void xps_free_page(xps_context *ctx, xps_page *page);
/*
- * Images.
+ * Images, fonts, and colorspaces.
*/
int xps_decode_jpeg(fz_pixmap **imagep, byte *rbuf, int rlen);
int xps_decode_png(fz_pixmap **imagep, byte *rbuf, int rlen);
int xps_decode_tiff(fz_pixmap **imagep, byte *rbuf, int rlen);
-/*
- * Fonts.
- */
-
typedef struct xps_glyph_metrics_s xps_glyph_metrics;
struct xps_glyph_metrics_s
@@ -136,10 +132,6 @@ void xps_measure_font_glyph(xps_context *ctx, fz_font *font, int gid, xps_glyph_
void xps_debug_path(xps_context *ctx);
-/*
- * Colorspaces and colors.
- */
-
void xps_parse_color(xps_context *ctx, char *base_uri, char *hexstring, fz_colorspace **csp, float *samples);
void xps_set_color(xps_context *ctx, fz_colorspace *colorspace, float *samples);
@@ -240,8 +232,7 @@ struct xps_context_s
fz_device *dev;
};
-xps_context *xps_new_context(void);
-int xps_open_file(xps_context *ctx, char *filename);
-int xps_free_context(xps_context *ctx);
+int xps_open_file(xps_context **ctxp, char *filename);
+void xps_free_context(xps_context *ctx);
#endif
diff --git a/xps/xps_doc.c b/xps/xps_doc.c
index c3255261..5719e7f8 100644
--- a/xps/xps_doc.c
+++ b/xps/xps_doc.c
@@ -305,8 +305,8 @@ xps_load_fixed_page(xps_context *ctx, xps_page *page)
return 0;
}
-xps_page *
-xps_load_page(xps_context *ctx, int number)
+int
+xps_load_page(xps_page **pagep, xps_context *ctx, int number)
{
xps_page *page;
int code;
@@ -319,16 +319,16 @@ xps_load_page(xps_context *ctx, int number)
if (!page->root)
{
code = xps_load_fixed_page(ctx, page);
- if (code) {
- fz_rethrow(code, "cannot load page %d", number + 1);
- return NULL;
- }
+ if (code)
+ return fz_rethrow(code, "cannot load page %d", number + 1);
}
- return page;
+ *pagep = page;
+ return fz_okay;
}
n ++;
}
- return NULL;
+
+ return fz_throw("cannot find page %d", number + 1);
}
void
diff --git a/xps/xps_zip.c b/xps/xps_zip.c
index e1019ae0..ccf82027 100644
--- a/xps/xps_zip.c
+++ b/xps/xps_zip.c
@@ -391,15 +391,25 @@ xps_read_part(xps_context *ctx, char *partname)
}
int
-xps_open_file(xps_context *ctx, char *filename)
+xps_open_file(xps_context **ctxp, char *filename)
{
+ xps_context *ctx;
char buf[2048];
int code;
char *p;
+ ctx = fz_malloc(sizeof(xps_context));
+ memset(ctx, 0, sizeof(xps_context));
+ ctx->font_table = xps_hash_new();
+ ctx->colorspace_table = xps_hash_new();
+ ctx->start_part = NULL;
+
ctx->file = fopen(filename, "rb");
if (!ctx->file)
+ {
+ xps_free_context(ctx);
return fz_throw("cannot open file: '%s'", filename);
+ }
if (strstr(filename, "/_rels/.rels") || strstr(filename, "\\_rels\\.rels"))
{
@@ -414,33 +424,23 @@ xps_open_file(xps_context *ctx, char *filename)
{
code = xps_find_and_read_zip_dir(ctx);
if (code < 0)
+ {
+ xps_free_context(ctx);
return fz_rethrow(code, "cannot read zip central directory");
+ }
}
code = xps_read_page_list(ctx);
if (code)
+ {
+ xps_free_context(ctx);
return fz_rethrow(code, "cannot read page list");
+ }
+ *ctxp = ctx;
return fz_okay;
}
-xps_context *
-xps_new_context(void)
-{
- xps_context *ctx;
-
- ctx = fz_malloc(sizeof(xps_context));
-
- memset(ctx, 0, sizeof(xps_context));
-
- ctx->font_table = xps_hash_new();
- ctx->colorspace_table = xps_hash_new();
-
- ctx->start_part = NULL;
-
- return ctx;
-}
-
static void xps_free_key_func(void *ptr)
{
fz_free(ptr);
@@ -456,7 +456,7 @@ static void xps_free_colorspace_func(void *ptr)
fz_drop_colorspace(ptr);
}
-int
+void
xps_free_context(xps_context *ctx)
{
int i;
@@ -464,19 +464,15 @@ xps_free_context(xps_context *ctx)
if (ctx->file)
fclose(ctx->file);
- if (ctx->start_part)
- fz_free(ctx->start_part);
-
for (i = 0; i < ctx->zip_count; i++)
fz_free(ctx->zip_table[i].name);
fz_free(ctx->zip_table);
xps_hash_free(ctx->font_table, xps_free_key_func, xps_free_font_func);
xps_hash_free(ctx->colorspace_table, xps_free_key_func, xps_free_colorspace_func);
-
xps_free_page_list(ctx);
+ fz_free(ctx->start_part);
+ fz_free(ctx->directory);
fz_free(ctx);
-
- return 0;
}