void pdf_set_annot_vertices(fz_context *ctx, pdf_annot *annot, int n, const float *v) { pdf_document *doc = annot->page->doc; fz_matrix page_ctm, inv_page_ctm; pdf_obj *vertices; fz_point point; int i; check_allowed_subtypes(ctx, annot, PDF_NAME_Vertices, vertices_subtypes); if (n <= 0 || !v) fz_throw(ctx, FZ_ERROR_GENERIC, "invalid number of vertices"); pdf_page_transform(ctx, annot->page, NULL, &page_ctm); fz_invert_matrix(&inv_page_ctm, &page_ctm); vertices = pdf_new_array(ctx, doc, n * 2); for (i = 0; i < n; ++i) { point.x = v[i * 2]; point.y = v[i * 2 + 1]; fz_transform_point(&point, &inv_page_ctm); pdf_array_push_drop(ctx, vertices, pdf_new_real(ctx, doc, point.x)); pdf_array_push_drop(ctx, vertices, pdf_new_real(ctx, doc, point.y)); } pdf_dict_put_drop(ctx, annot->obj, PDF_NAME_Vertices, vertices); annot->changed = 1; }
void pdf_set_annot_ink_list(fz_context *ctx, pdf_annot *annot, int n, const int *count, const float *v) { pdf_document *doc = annot->page->doc; fz_matrix page_ctm, inv_page_ctm; pdf_obj *ink_list, *stroke; fz_point point; int i, k; if (pdf_annot_type(ctx, annot) != PDF_ANNOT_INK) fz_throw(ctx, FZ_ERROR_GENERIC, "cannot set InkList on non-ink annotations"); pdf_page_transform(ctx, annot->page, NULL, &page_ctm); fz_invert_matrix(&inv_page_ctm, &page_ctm); // TODO: update Rect (in update appearance perhaps?) ink_list = pdf_new_array(ctx, doc, n); for (i = 0; i < n; ++i) { stroke = pdf_new_array(ctx, doc, count[i]); for (k = 0; k < count[i]; ++k) { point.x = *v++; point.y = *v++; fz_transform_point(&point, &inv_page_ctm); pdf_array_push_drop(ctx, stroke, pdf_new_real(ctx, doc, point.x)); pdf_array_push_drop(ctx, stroke, pdf_new_real(ctx, doc, point.y)); } pdf_array_push_drop(ctx, ink_list, stroke); } pdf_dict_put_drop(ctx, annot->obj, PDF_NAME_InkList, ink_list); annot->changed = 1; }
void pdf_set_annot_quad_points(fz_context *ctx, pdf_annot *annot, int n, const float *v) { pdf_document *doc = annot->page->doc; fz_matrix page_ctm, inv_page_ctm; pdf_obj *quad_points; fz_point point; int i, k; // TODO: check annot type pdf_page_transform(ctx, annot->page, NULL, &page_ctm); fz_invert_matrix(&inv_page_ctm, &page_ctm); quad_points = pdf_new_array(ctx, doc, n * 8); for (i = 0; i < n; ++i) { for (k = 0; k < 4; ++k) { point.x = v[i * 8 + k * 2 + 0]; point.y = v[i * 8 + k * 2 + 1]; fz_transform_point(&point, &inv_page_ctm); pdf_array_push_drop(ctx, quad_points, pdf_new_real(ctx, doc, point.x)); pdf_array_push_drop(ctx, quad_points, pdf_new_real(ctx, doc, point.y)); } } pdf_dict_put_drop(ctx, annot->obj, PDF_NAME_QuadPoints, quad_points); annot->changed = 1; }
static void intersect_box(fz_context *ctx, pdf_document *doc, pdf_obj *page, pdf_obj *box_name, const fz_rect *mb) { pdf_obj *box = pdf_dict_get(ctx, page, box_name); pdf_obj *newbox; fz_rect old_rect; if (box == NULL) return; old_rect.x0 = pdf_to_real(ctx, pdf_array_get(ctx, box, 0)); old_rect.y0 = pdf_to_real(ctx, pdf_array_get(ctx, box, 1)); old_rect.x1 = pdf_to_real(ctx, pdf_array_get(ctx, box, 2)); old_rect.y1 = pdf_to_real(ctx, pdf_array_get(ctx, box, 3)); if (old_rect.x0 < mb->x0) old_rect.x0 = mb->x0; if (old_rect.y0 < mb->y0) old_rect.y0 = mb->y0; if (old_rect.x1 > mb->x1) old_rect.x1 = mb->x1; if (old_rect.y1 > mb->y1) old_rect.y1 = mb->y1; newbox = pdf_new_array(ctx, doc, 4); pdf_array_push(ctx, newbox, pdf_new_real(ctx, doc, old_rect.x0)); pdf_array_push(ctx, newbox, pdf_new_real(ctx, doc, old_rect.y0)); pdf_array_push(ctx, newbox, pdf_new_real(ctx, doc, old_rect.x1)); pdf_array_push(ctx, newbox, pdf_new_real(ctx, doc, old_rect.y1)); pdf_dict_put(ctx, page, box_name, newbox); }
void pdf_set_annot_ink_list(fz_context *ctx, pdf_annot *annot, int n, const int *count, const float *v) { pdf_document *doc = annot->page->doc; fz_matrix page_ctm, inv_page_ctm; pdf_obj *ink_list, *stroke; fz_point point; int i, k; check_allowed_subtypes(ctx, annot, PDF_NAME_InkList, ink_list_subtypes); pdf_page_transform(ctx, annot->page, NULL, &page_ctm); fz_invert_matrix(&inv_page_ctm, &page_ctm); // TODO: update Rect (in update appearance perhaps?) ink_list = pdf_new_array(ctx, doc, n); for (i = 0; i < n; ++i) { stroke = pdf_new_array(ctx, doc, count[i]); for (k = 0; k < count[i]; ++k) { point.x = *v++; point.y = *v++; fz_transform_point(&point, &inv_page_ctm); pdf_array_push_drop(ctx, stroke, pdf_new_real(ctx, doc, point.x)); pdf_array_push_drop(ctx, stroke, pdf_new_real(ctx, doc, point.y)); } pdf_array_push_drop(ctx, ink_list, stroke); } pdf_dict_put_drop(ctx, annot->obj, PDF_NAME_InkList, ink_list); annot->changed = 1; }
void pdf_set_annot_quad_points(fz_context *ctx, pdf_annot *annot, int n, const float *v) { pdf_document *doc = annot->page->doc; fz_matrix page_ctm, inv_page_ctm; pdf_obj *quad_points; fz_point point; int i, k; check_allowed_subtypes(ctx, annot, PDF_NAME_QuadPoints, quad_point_subtypes); if (n <= 0 || !v) fz_throw(ctx, FZ_ERROR_GENERIC, "invalid number of quadrilaterals"); pdf_page_transform(ctx, annot->page, NULL, &page_ctm); fz_invert_matrix(&inv_page_ctm, &page_ctm); quad_points = pdf_new_array(ctx, doc, n * 8); for (i = 0; i < n; ++i) { for (k = 0; k < 4; ++k) { point.x = v[i * 8 + k * 2 + 0]; point.y = v[i * 8 + k * 2 + 1]; fz_transform_point(&point, &inv_page_ctm); pdf_array_push_drop(ctx, quad_points, pdf_new_real(ctx, doc, point.x)); pdf_array_push_drop(ctx, quad_points, pdf_new_real(ctx, doc, point.y)); } } pdf_dict_put_drop(ctx, annot->obj, PDF_NAME_QuadPoints, quad_points); annot->changed = 1; }
static void pdf_set_annot_color_imp(fz_context *ctx, pdf_annot *annot, pdf_obj *key, int n, const float color[4]) { pdf_document *doc = annot->page->doc; pdf_obj *obj = pdf_new_array(ctx, doc, 4); switch (n) { default: case 0: break; case 1: pdf_array_push_drop(ctx, obj, pdf_new_real(ctx, doc, color[0])); break; case 3: pdf_array_push_drop(ctx, obj, pdf_new_real(ctx, doc, color[0])); pdf_array_push_drop(ctx, obj, pdf_new_real(ctx, doc, color[1])); pdf_array_push_drop(ctx, obj, pdf_new_real(ctx, doc, color[2])); break; case 4: pdf_array_push_drop(ctx, obj, pdf_new_real(ctx, doc, color[0])); pdf_array_push_drop(ctx, obj, pdf_new_real(ctx, doc, color[1])); pdf_array_push_drop(ctx, obj, pdf_new_real(ctx, doc, color[2])); pdf_array_push_drop(ctx, obj, pdf_new_real(ctx, doc, color[3])); break; } pdf_dict_put_drop(ctx, annot->obj, key, obj); annot->changed = 1; }
void pdf_set_annot_vertex(fz_context *ctx, pdf_annot *annot, int i, fz_point p) { fz_matrix page_ctm, inv_page_ctm; pdf_obj *vertices; check_allowed_subtypes(ctx, annot, PDF_NAME(Vertices), vertices_subtypes); pdf_page_transform(ctx, annot->page, NULL, &page_ctm); fz_invert_matrix(&inv_page_ctm, &page_ctm); fz_transform_point(&p, &inv_page_ctm); vertices = pdf_dict_get(ctx, annot->obj, PDF_NAME(Vertices)); pdf_array_put_drop(ctx, vertices, i * 2 + 0, pdf_new_real(ctx, p.x)); pdf_array_put_drop(ctx, vertices, i * 2 + 1, pdf_new_real(ctx, p.y)); }
static pdf_obj *start_new_destpage(fz_context *ctx,double width_pts,double height_pts) { pdf_obj *pageobj; pdf_obj *mbox; pageobj=pdf_new_dict(ctx,2); pdf_dict_puts(pageobj,"Type",pdf_new_name(ctx,"Page")); mbox=pdf_new_array(ctx,4); pdf_array_push(mbox,pdf_new_real(ctx,0.)); pdf_array_push(mbox,pdf_new_real(ctx,0.)); pdf_array_push(mbox,pdf_new_real(ctx,width_pts)); pdf_array_push(mbox,pdf_new_real(ctx,height_pts)); pdf_dict_puts(pageobj,"MediaBox",mbox); return(pageobj); }
pdf_obj * pdf_parse_stm_obj(pdf_document *doc, fz_stream *file, pdf_lexbuf *buf) { pdf_token tok; fz_context *ctx = file->ctx; tok = pdf_lex(file, buf); switch (tok) { case PDF_TOK_OPEN_ARRAY: return pdf_parse_array(doc, file, buf); case PDF_TOK_OPEN_DICT: return pdf_parse_dict(doc, file, buf); case PDF_TOK_NAME: return pdf_new_name(doc, buf->scratch); break; case PDF_TOK_REAL: return pdf_new_real(doc, buf->f); break; case PDF_TOK_STRING: return pdf_new_string(doc, buf->scratch, buf->len); break; case PDF_TOK_TRUE: return pdf_new_bool(doc, 1); break; case PDF_TOK_FALSE: return pdf_new_bool(doc, 0); break; case PDF_TOK_NULL: return pdf_new_null(doc); break; case PDF_TOK_INT: return pdf_new_int(doc, buf->i); break; default: fz_throw(ctx, FZ_ERROR_GENERIC, "unknown token in object stream"); } return NULL; /* Stupid MSVC */ }
pdf_obj * pdfout_data_scalar_to_pdf_real (fz_context *ctx, pdf_document *doc, pdfout_data *scalar) { char *s = scalar_get_string (ctx, scalar); float f = pdfout_strtof (ctx, s); return pdf_new_real (ctx, doc, f); }
static void pdf_dev_alpha(fz_context *ctx, pdf_device *pdev, float alpha, int stroke) { int i; pdf_document *doc = pdev->doc; gstate *gs = CURRENT_GSTATE(pdev); /* If the alpha is unchanged, nothing to do */ if (gs->alpha[stroke] == alpha) return; /* Have we sent such an alpha before? */ for (i = 0; i < pdev->num_alphas; i++) if (pdev->alphas[i].alpha == alpha && pdev->alphas[i].stroke == stroke) break; if (i == pdev->num_alphas) { pdf_obj *o; pdf_obj *ref = NULL; fz_var(ref); /* No. Need to make a new one */ if (pdev->num_alphas == pdev->max_alphas) { int newmax = pdev->max_alphas * 2; if (newmax == 0) newmax = 4; pdev->alphas = fz_resize_array(ctx, pdev->alphas, newmax, sizeof(*pdev->alphas)); pdev->max_alphas = newmax; } pdev->alphas[i].alpha = alpha; pdev->alphas[i].stroke = stroke; o = pdf_new_dict(ctx, doc, 1); fz_try(ctx) { char text[32]; pdf_dict_put_drop(ctx, o, (stroke ? PDF_NAME_CA : PDF_NAME_ca), pdf_new_real(ctx, doc, alpha)); ref = pdf_add_object(ctx, doc, o); fz_snprintf(text, sizeof(text), "ExtGState/Alp%d", i); pdf_dict_putp(ctx, pdev->resources, text, ref); } fz_always(ctx) { pdf_drop_obj(ctx, o); pdf_drop_obj(ctx, ref); } fz_catch(ctx) { fz_rethrow(ctx); } pdev->num_alphas++; }
pdf_obj *pdf_new_rect(fz_context *ctx, pdf_document *doc, const fz_rect *rect) { pdf_obj *arr = NULL; pdf_obj *item = NULL; fz_var(arr); fz_var(item); fz_try(ctx) { arr = pdf_new_array(ctx, doc, 4); item = pdf_new_real(ctx, doc, rect->x0); pdf_array_push(ctx, arr, item); pdf_drop_obj(ctx, item); item = NULL; item = pdf_new_real(ctx, doc, rect->y0); pdf_array_push(ctx, arr, item); pdf_drop_obj(ctx, item); item = NULL; item = pdf_new_real(ctx, doc, rect->x1); pdf_array_push(ctx, arr, item); pdf_drop_obj(ctx, item); item = NULL; item = pdf_new_real(ctx, doc, rect->y1); pdf_array_push(ctx, arr, item); pdf_drop_obj(ctx, item); item = NULL; } fz_catch(ctx) { pdf_drop_obj(ctx, item); pdf_drop_obj(ctx, arr); fz_rethrow(ctx); } return arr; }
pdf_obj *pdf_new_rect(fz_context *ctx, fz_rect rect) { pdf_obj *arr = NULL; pdf_obj *item = NULL; fz_var(arr); fz_var(item); fz_try(ctx) { arr = pdf_new_array(ctx, 4); item = pdf_new_real(ctx, rect.x0); pdf_array_push(arr, item); pdf_drop_obj(item); item = NULL; item = pdf_new_real(ctx, rect.y0); pdf_array_push(arr, item); pdf_drop_obj(item); item = NULL; item = pdf_new_real(ctx, rect.x1); pdf_array_push(arr, item); pdf_drop_obj(item); item = NULL; item = pdf_new_real(ctx, rect.y1); pdf_array_push(arr, item); pdf_drop_obj(item); item = NULL; } fz_catch(ctx) { pdf_drop_obj(item); pdf_drop_obj(arr); fz_rethrow(ctx); } return arr; }
void pdf_set_annot_border(fz_context *ctx, pdf_annot *annot, float w) { pdf_document *doc = annot->page->doc; pdf_obj *border = pdf_dict_get(ctx, annot->obj, PDF_NAME_Border); if (pdf_is_array(ctx, border)) pdf_array_put_drop(ctx, border, 2, pdf_new_real(ctx, doc, w)); else { border = pdf_new_array(ctx, doc, 3); pdf_array_push_drop(ctx, border, pdf_new_real(ctx, doc, 0)); pdf_array_push_drop(ctx, border, pdf_new_real(ctx, doc, 0)); pdf_array_push_drop(ctx, border, pdf_new_real(ctx, doc, w)); pdf_dict_put_drop(ctx, annot->obj, PDF_NAME_Border, border); } /* Remove border style and effect dictionaries so they won't interfere. */ pdf_dict_del(ctx, annot->obj, PDF_NAME_BS); pdf_dict_del(ctx, annot->obj, PDF_NAME_BE); annot->changed = 1; }
void pdf_set_markup_annot_quadpoints(fz_context *ctx, pdf_document *doc, pdf_annot *annot, fz_point *qp, int n) { fz_matrix ctm; pdf_obj *arr = pdf_new_array(ctx, doc, n*2); int i; fz_invert_matrix(&ctm, &annot->page->ctm); pdf_dict_put_drop(ctx, annot->obj, PDF_NAME_QuadPoints, arr); for (i = 0; i < n; i++) { fz_point pt = qp[i]; pdf_obj *r; fz_transform_point(&pt, &ctm); r = pdf_new_real(ctx, doc, pt.x); pdf_array_push_drop(ctx, arr, r); r = pdf_new_real(ctx, doc, pt.y); pdf_array_push_drop(ctx, arr, r); } }
static void pdf_set_annot_color_imp(fz_context *ctx, pdf_annot *annot, pdf_obj *key, int n, const float color[4], pdf_obj **allowed) { pdf_document *doc = annot->page->doc; pdf_obj *arr; if (allowed) check_allowed_subtypes(ctx, annot, key, allowed); if (n != 0 && n != 1 && n != 3 && n != 4) fz_throw(ctx, FZ_ERROR_GENERIC, "color must be 0, 1, 3 or 4 components"); if (!color) fz_throw(ctx, FZ_ERROR_GENERIC, "no color given"); arr = pdf_new_array(ctx, doc, n); fz_try(ctx) { switch (n) { case 1: pdf_array_insert_drop(ctx, arr, pdf_new_real(ctx, doc, color[0]), 0); break; case 3: pdf_array_insert_drop(ctx, arr, pdf_new_real(ctx, doc, color[0]), 0); pdf_array_insert_drop(ctx, arr, pdf_new_real(ctx, doc, color[1]), 1); pdf_array_insert_drop(ctx, arr, pdf_new_real(ctx, doc, color[2]), 2); break; case 4: pdf_array_insert_drop(ctx, arr, pdf_new_real(ctx, doc, color[0]), 0); pdf_array_insert_drop(ctx, arr, pdf_new_real(ctx, doc, color[1]), 1); pdf_array_insert_drop(ctx, arr, pdf_new_real(ctx, doc, color[2]), 2); pdf_array_insert_drop(ctx, arr, pdf_new_real(ctx, doc, color[3]), 3); break; } } fz_catch(ctx) { pdf_drop_obj(ctx, arr); fz_rethrow(ctx); } pdf_dict_put_drop(ctx, annot->obj, key, arr); annot->changed = 1; }
pdf_obj * pdf_parse_stm_obj(pdf_document *xref, fz_stream *file, pdf_lexbuf *buf) { int tok; fz_context *ctx = file->ctx; tok = pdf_lex(file, buf); /* RJW: "cannot parse token in object stream") */ switch (tok) { case PDF_TOK_OPEN_ARRAY: return pdf_parse_array(xref, file, buf); /* RJW: "cannot parse object stream" */ case PDF_TOK_OPEN_DICT: return pdf_parse_dict(xref, file, buf); /* RJW: "cannot parse object stream" */ case PDF_TOK_NAME: return fz_new_name(ctx, buf->scratch); break; case PDF_TOK_REAL: return pdf_new_real(ctx, buf->f); break; case PDF_TOK_STRING: return pdf_new_string(ctx, buf->scratch, buf->len); break; case PDF_TOK_TRUE: return pdf_new_bool(ctx, 1); break; case PDF_TOK_FALSE: return pdf_new_bool(ctx, 0); break; case PDF_TOK_NULL: return pdf_new_null(ctx); break; case PDF_TOK_INT: return pdf_new_int(ctx, buf->i); break; default: fz_throw(ctx, "unknown token in object stream"); } return NULL; /* Stupid MSVC */ }
pdf_obj *pdf_new_matrix(fz_context *ctx, fz_matrix mtx) { pdf_obj *arr = NULL; pdf_obj *item = NULL; fz_var(arr); fz_var(item); fz_try(ctx) { arr = pdf_new_array(ctx, 6); item = pdf_new_real(ctx, mtx.a); pdf_array_push(arr, item); pdf_drop_obj(item); item = NULL; item = pdf_new_real(ctx, mtx.b); pdf_array_push(arr, item); pdf_drop_obj(item); item = NULL; item = pdf_new_real(ctx, mtx.c); pdf_array_push(arr, item); pdf_drop_obj(item); item = NULL; item = pdf_new_real(ctx, mtx.d); pdf_array_push(arr, item); pdf_drop_obj(item); item = NULL; item = pdf_new_real(ctx, mtx.e); pdf_array_push(arr, item); pdf_drop_obj(item); item = NULL; item = pdf_new_real(ctx, mtx.f); pdf_array_push(arr, item); pdf_drop_obj(item); item = NULL; } fz_catch(ctx) { pdf_drop_obj(item); pdf_drop_obj(arr); fz_rethrow(ctx); } return arr; }
pdf_obj *pdf_new_matrix(fz_context *ctx, pdf_document *doc, const fz_matrix *mtx) { pdf_obj *arr = NULL; pdf_obj *item = NULL; fz_var(arr); fz_var(item); fz_try(ctx) { arr = pdf_new_array(ctx, doc, 6); item = pdf_new_real(ctx, doc, mtx->a); pdf_array_push(ctx, arr, item); pdf_drop_obj(ctx, item); item = NULL; item = pdf_new_real(ctx, doc, mtx->b); pdf_array_push(ctx, arr, item); pdf_drop_obj(ctx, item); item = NULL; item = pdf_new_real(ctx, doc, mtx->c); pdf_array_push(ctx, arr, item); pdf_drop_obj(ctx, item); item = NULL; item = pdf_new_real(ctx, doc, mtx->d); pdf_array_push(ctx, arr, item); pdf_drop_obj(ctx, item); item = NULL; item = pdf_new_real(ctx, doc, mtx->e); pdf_array_push(ctx, arr, item); pdf_drop_obj(ctx, item); item = NULL; item = pdf_new_real(ctx, doc, mtx->f); pdf_array_push(ctx, arr, item); pdf_drop_obj(ctx, item); item = NULL; } fz_catch(ctx) { pdf_drop_obj(ctx, item); pdf_drop_obj(ctx, arr); fz_rethrow(ctx); } return arr; }
pdf_obj * pdf_parse_array(pdf_document *xref, fz_stream *file, pdf_lexbuf *buf) { pdf_obj *ary = NULL; pdf_obj *obj = NULL; int a = 0, b = 0, n = 0; int tok; fz_context *ctx = file->ctx; pdf_obj *op; fz_var(obj); ary = pdf_new_array(ctx, 4); fz_try(ctx) { while (1) { tok = pdf_lex(file, buf); if (tok != PDF_TOK_INT && tok != PDF_TOK_R) { if (n > 0) { obj = pdf_new_int(ctx, a); pdf_array_push(ary, obj); pdf_drop_obj(obj); obj = NULL; } if (n > 1) { obj = pdf_new_int(ctx, b); pdf_array_push(ary, obj); pdf_drop_obj(obj); obj = NULL; } n = 0; } if (tok == PDF_TOK_INT && n == 2) { obj = pdf_new_int(ctx, a); pdf_array_push(ary, obj); pdf_drop_obj(obj); obj = NULL; a = b; n --; } switch (tok) { case PDF_TOK_CLOSE_ARRAY: op = ary; goto end; case PDF_TOK_INT: if (n == 0) a = buf->i; if (n == 1) b = buf->i; n ++; break; case PDF_TOK_R: if (n != 2) fz_throw(ctx, "cannot parse indirect reference in array"); obj = pdf_new_indirect(ctx, a, b, xref); pdf_array_push(ary, obj); pdf_drop_obj(obj); obj = NULL; n = 0; break; case PDF_TOK_OPEN_ARRAY: obj = pdf_parse_array(xref, file, buf); pdf_array_push(ary, obj); pdf_drop_obj(obj); obj = NULL; break; case PDF_TOK_OPEN_DICT: obj = pdf_parse_dict(xref, file, buf); pdf_array_push(ary, obj); pdf_drop_obj(obj); obj = NULL; break; case PDF_TOK_NAME: obj = fz_new_name(ctx, buf->scratch); pdf_array_push(ary, obj); pdf_drop_obj(obj); obj = NULL; break; case PDF_TOK_REAL: obj = pdf_new_real(ctx, buf->f); pdf_array_push(ary, obj); pdf_drop_obj(obj); obj = NULL; break; case PDF_TOK_STRING: obj = pdf_new_string(ctx, buf->scratch, buf->len); pdf_array_push(ary, obj); pdf_drop_obj(obj); obj = NULL; break; case PDF_TOK_TRUE: obj = pdf_new_bool(ctx, 1); pdf_array_push(ary, obj); pdf_drop_obj(obj); obj = NULL; break; case PDF_TOK_FALSE: obj = pdf_new_bool(ctx, 0); pdf_array_push(ary, obj); pdf_drop_obj(obj); obj = NULL; break; case PDF_TOK_NULL: obj = pdf_new_null(ctx); pdf_array_push(ary, obj); pdf_drop_obj(obj); obj = NULL; break; default: fz_throw(ctx, "cannot parse token in array"); } } end: {} } fz_catch(ctx) { pdf_drop_obj(obj); pdf_drop_obj(ary); fz_throw(ctx, "cannot parse array"); } return op; }
pdf_obj * pdf_parse_dict(pdf_document *xref, fz_stream *file, pdf_lexbuf *buf) { pdf_obj *dict; pdf_obj *key = NULL; pdf_obj *val = NULL; int tok; int a, b; fz_context *ctx = file->ctx; dict = pdf_new_dict(ctx, 8); fz_var(key); fz_var(val); fz_try(ctx) { while (1) { tok = pdf_lex(file, buf); skip: if (tok == PDF_TOK_CLOSE_DICT) break; /* for BI .. ID .. EI in content streams */ if (tok == PDF_TOK_KEYWORD && !strcmp(buf->scratch, "ID")) break; if (tok != PDF_TOK_NAME) fz_throw(ctx, "invalid key in dict"); key = fz_new_name(ctx, buf->scratch); tok = pdf_lex(file, buf); switch (tok) { case PDF_TOK_OPEN_ARRAY: /* cf. http://code.google.com/p/sumatrapdf/issues/detail?id=1643 */ fz_try(ctx) { val = pdf_parse_array(xref, file, buf); } fz_catch(ctx) { fz_warn(ctx, "ignoring broken array for '%s'", pdf_to_name(key)); pdf_drop_obj(key); val = key = NULL; do tok = pdf_lex(file, buf); while (tok != PDF_TOK_CLOSE_DICT && tok != PDF_TOK_CLOSE_ARRAY && tok != PDF_TOK_EOF && tok != PDF_TOK_OPEN_ARRAY && tok != PDF_TOK_OPEN_DICT); if (tok == PDF_TOK_CLOSE_DICT) goto skip; if (tok == PDF_TOK_CLOSE_ARRAY) continue; fz_throw(ctx, "cannot make sense of broken array after all"); } break; case PDF_TOK_OPEN_DICT: val = pdf_parse_dict(xref, file, buf); break; case PDF_TOK_NAME: val = fz_new_name(ctx, buf->scratch); break; case PDF_TOK_REAL: val = pdf_new_real(ctx, buf->f); break; case PDF_TOK_STRING: val = pdf_new_string(ctx, buf->scratch, buf->len); break; case PDF_TOK_TRUE: val = pdf_new_bool(ctx, 1); break; case PDF_TOK_FALSE: val = pdf_new_bool(ctx, 0); break; case PDF_TOK_NULL: val = pdf_new_null(ctx); break; case PDF_TOK_INT: /* 64-bit to allow for numbers > INT_MAX and overflow */ a = buf->i; tok = pdf_lex(file, buf); if (tok == PDF_TOK_CLOSE_DICT || tok == PDF_TOK_NAME || (tok == PDF_TOK_KEYWORD && !strcmp(buf->scratch, "ID"))) { val = pdf_new_int(ctx, a); fz_dict_put(dict, key, val); pdf_drop_obj(val); val = NULL; pdf_drop_obj(key); key = NULL; goto skip; } if (tok == PDF_TOK_INT) { b = buf->i; tok = pdf_lex(file, buf); if (tok == PDF_TOK_R) { val = pdf_new_indirect(ctx, a, b, xref); break; } } fz_throw(ctx, "invalid indirect reference in dict"); default: fz_throw(ctx, "unknown token in dict"); } fz_dict_put(dict, key, val); pdf_drop_obj(val); val = NULL; pdf_drop_obj(key); key = NULL; } } fz_catch(ctx) { pdf_drop_obj(dict); pdf_drop_obj(key); pdf_drop_obj(val); fz_throw(ctx, "cannot parse dict"); } return dict; }
static void wmupdf_convert_single_page_to_form(pdf_document *xref,fz_context *ctx,int pageno) { pdf_obj *array,*srcpageobj,*srcpagecontents; int i,len,streamlen,pageref,pagegen,compressed; double bbox_array[4]; double matrix[6]; /* New source page, so get the source page objects */ srcpageobj = xref->page_objs[pageno-1]; pageref=pdf_to_num(xref->page_refs[pageno-1]); pagegen=pdf_to_gen(xref->page_refs[pageno-1]); wmupdf_page_bbox(srcpageobj,bbox_array); for (i=0;i<6;i++) matrix[i]=0.; matrix[0]=matrix[3]=1.; srcpagecontents=pdf_dict_gets(srcpageobj,"Contents"); /* Concatenate all indirect streams from source page directly into it. */ // printf("Adding streams to source page %d (pageref=%d, pagegen=%d)...\n",pageno,pageref,pagegen); streamlen=0; if (pdf_is_array(srcpagecontents)) { int k; for (k=0;k<pdf_array_len(srcpagecontents);k++) { pdf_obj *obj; obj=pdf_array_get(srcpagecontents,k); if (pdf_is_indirect(obj)) pdf_resolve_indirect(obj); streamlen=add_to_srcpage_stream(xref,ctx,pageref,pagegen,obj); } } else { if (pdf_is_indirect(srcpagecontents)) pdf_resolve_indirect(srcpagecontents); streamlen=add_to_srcpage_stream(xref,ctx,pageref,pagegen,srcpagecontents); } compressed=stream_deflate(xref,ctx,pageref,pagegen,&streamlen); srcpageobj = xref->page_objs[pageno-1]; pageref=pdf_to_num(xref->page_refs[pageno-1]); len=pdf_dict_len(srcpageobj); for (i=0;i<len;i++) { pdf_obj *key; /* *value */ key=pdf_dict_get_key(srcpageobj,i); /* if (pdf_is_name(key)) printf("key[%d] = name = %s\n",i,pdf_to_name(key)); else printf("key[%d] = ??\n",i); */ /* value=pdf_dict_get_val(srcpageobj,i); */ /* Keep same resources */ if (!pdf_is_name(key)) continue; if (pdf_is_name(key) && !stricmp("Resources",pdf_to_name(key))) continue; /* Drop dictionary entry otherwise */ // printf("Deleting key %s.\n",pdf_to_name(key)); pdf_dict_del(srcpageobj,key); i=-1; len=pdf_dict_len(srcpageobj); } pdf_dict_puts(srcpageobj,"Type",pdf_new_name(ctx,"XObject")); pdf_dict_puts(srcpageobj,"Subtype",pdf_new_name(ctx,"Form")); pdf_dict_puts(srcpageobj,"FormType",pdf_new_int(ctx,1)); if (compressed) pdf_dict_puts(srcpageobj,"Filter",pdf_new_name(ctx,"FlateDecode")); pdf_dict_puts(srcpageobj,"Length",pdf_new_int(ctx,streamlen)); array=pdf_new_array(ctx,4); for (i=0;i<4;i++) pdf_array_push(array,pdf_new_real(ctx,bbox_array[i])); pdf_dict_puts(srcpageobj,"BBox",array); array=pdf_new_array(ctx,6); for (i=0;i<6;i++) pdf_array_push(array,pdf_new_real(ctx,matrix[i])); pdf_dict_puts(srcpageobj,"Matrix",array); /* (It's no longer a "page"--it's a Form-type XObject) */ /* I don't think this call should be made since it will call fz_drop_object on srcpageobj */ /* pdf_update_object(xref,pageref,srcpageobj); */ }
pdf_obj * pdf_parse_dict(pdf_document *doc, fz_stream *file, pdf_lexbuf *buf) { pdf_obj *dict; pdf_obj *key = NULL; pdf_obj *val = NULL; pdf_token tok; int a, b; fz_context *ctx = file->ctx; dict = pdf_new_dict(doc, 8); fz_var(key); fz_var(val); fz_try(ctx) { while (1) { tok = pdf_lex(file, buf); skip: if (tok == PDF_TOK_CLOSE_DICT) break; /* for BI .. ID .. EI in content streams */ if (tok == PDF_TOK_KEYWORD && !strcmp(buf->scratch, "ID")) break; if (tok != PDF_TOK_NAME) fz_throw(ctx, FZ_ERROR_GENERIC, "invalid key in dict"); key = pdf_new_name(doc, buf->scratch); tok = pdf_lex(file, buf); switch (tok) { case PDF_TOK_OPEN_ARRAY: val = pdf_parse_array(doc, file, buf); break; case PDF_TOK_OPEN_DICT: val = pdf_parse_dict(doc, file, buf); break; case PDF_TOK_NAME: val = pdf_new_name(doc, buf->scratch); break; case PDF_TOK_REAL: val = pdf_new_real(doc, buf->f); break; case PDF_TOK_STRING: val = pdf_new_string(doc, buf->scratch, buf->len); break; case PDF_TOK_TRUE: val = pdf_new_bool(doc, 1); break; case PDF_TOK_FALSE: val = pdf_new_bool(doc, 0); break; case PDF_TOK_NULL: val = pdf_new_null(doc); break; case PDF_TOK_INT: /* 64-bit to allow for numbers > INT_MAX and overflow */ a = buf->i; tok = pdf_lex(file, buf); if (tok == PDF_TOK_CLOSE_DICT || tok == PDF_TOK_NAME || (tok == PDF_TOK_KEYWORD && !strcmp(buf->scratch, "ID"))) { val = pdf_new_int(doc, a); pdf_dict_put(dict, key, val); pdf_drop_obj(val); val = NULL; pdf_drop_obj(key); key = NULL; goto skip; } if (tok == PDF_TOK_INT) { b = buf->i; tok = pdf_lex(file, buf); if (tok == PDF_TOK_R) { val = pdf_new_indirect(doc, a, b); break; } } fz_throw(ctx, FZ_ERROR_GENERIC, "invalid indirect reference in dict"); default: fz_throw(ctx, FZ_ERROR_GENERIC, "unknown token in dict"); } pdf_dict_put(dict, key, val); pdf_drop_obj(val); val = NULL; pdf_drop_obj(key); key = NULL; } } fz_catch(ctx) { pdf_drop_obj(dict); pdf_drop_obj(key); pdf_drop_obj(val); fz_rethrow_message(ctx, "cannot parse dict"); } return dict; }
static void decimatepages(pdf_document *xref) { pdf_obj *oldroot, *root, *pages, *kids, *parent; fz_context *ctx = xref->ctx; int num_pages = pdf_count_pages(xref); int page, kidcount; /* Keep only pages/type and (reduced) dest entries to avoid * references to unretained pages */ oldroot = pdf_dict_gets(pdf_trailer(xref), "Root"); pages = pdf_dict_gets(oldroot, "Pages"); root = pdf_new_dict(ctx, 2); pdf_dict_puts(root, "Type", pdf_dict_gets(oldroot, "Type")); pdf_dict_puts(root, "Pages", pdf_dict_gets(oldroot, "Pages")); pdf_update_object(xref, pdf_to_num(oldroot), root); pdf_drop_obj(root); /* Create a new kids array with only the pages we want to keep */ parent = pdf_new_indirect(ctx, pdf_to_num(pages), pdf_to_gen(pages), xref); kids = pdf_new_array(ctx, 1); kidcount = 0; for (page=0; page < num_pages; page++) { pdf_page *page_details = pdf_load_page(xref, page); int xf = x_factor, yf = y_factor; int x, y; float w = page_details->mediabox.x1 - page_details->mediabox.x0; float h = page_details->mediabox.y1 - page_details->mediabox.y0; if (xf == 0 && yf == 0) { /* Nothing specified, so split along the long edge */ if (w > h) xf = 2, yf = 1; else xf = 1, yf = 2; } else if (xf == 0) xf = 1; else if (yf == 0) yf = 1; for (y = yf-1; y >= 0; y--) { for (x = 0; x < xf; x++) { pdf_obj *newpageobj, *newpageref, *newmediabox; fz_rect mb; int num; newpageobj = pdf_copy_dict(ctx, xref->page_objs[page]); num = pdf_create_object(xref); pdf_update_object(xref, num, newpageobj); newpageref = pdf_new_indirect(ctx, num, 0, xref); newmediabox = pdf_new_array(ctx, 4); mb.x0 = page_details->mediabox.x0 + (w/xf)*x; if (x == xf-1) mb.x1 = page_details->mediabox.x1; else mb.x1 = page_details->mediabox.x0 + (w/xf)*(x+1); mb.y0 = page_details->mediabox.y0 + (h/yf)*y; if (y == yf-1) mb.y1 = page_details->mediabox.y1; else mb.y1 = page_details->mediabox.y0 + (h/yf)*(y+1); pdf_array_push(newmediabox, pdf_new_real(ctx, mb.x0)); pdf_array_push(newmediabox, pdf_new_real(ctx, mb.y0)); pdf_array_push(newmediabox, pdf_new_real(ctx, mb.x1)); pdf_array_push(newmediabox, pdf_new_real(ctx, mb.y1)); pdf_dict_puts(newpageobj, "Parent", parent); pdf_dict_puts(newpageobj, "MediaBox", newmediabox); /* Store page object in new kids array */ pdf_array_push(kids, newpageref); kidcount++; } } } pdf_drop_obj(parent); /* Update page count and kids array */ pdf_dict_puts(pages, "Count", pdf_new_int(ctx, kidcount)); pdf_dict_puts(pages, "Kids", kids); pdf_drop_obj(kids); }
static void decimatepages(fz_context *ctx, pdf_document *doc) { pdf_obj *oldroot, *root, *pages, *kids, *parent; int num_pages = pdf_count_pages(ctx, doc); int page, kidcount; oldroot = pdf_dict_get(ctx, pdf_trailer(ctx, doc), PDF_NAME_Root); pages = pdf_dict_get(ctx, oldroot, PDF_NAME_Pages); root = pdf_new_dict(ctx, doc, 2); pdf_dict_put(ctx, root, PDF_NAME_Type, pdf_dict_get(ctx, oldroot, PDF_NAME_Type)); pdf_dict_put(ctx, root, PDF_NAME_Pages, pdf_dict_get(ctx, oldroot, PDF_NAME_Pages)); pdf_update_object(ctx, doc, pdf_to_num(ctx, oldroot), root); pdf_drop_obj(ctx, root); /* Create a new kids array with our new pages in */ parent = pdf_new_indirect(ctx, doc, pdf_to_num(ctx, pages), pdf_to_gen(ctx, pages)); kids = pdf_new_array(ctx, doc, 1); kidcount = 0; for (page=0; page < num_pages; page++) { pdf_page *page_details = pdf_load_page(ctx, doc, page); int xf = x_factor, yf = y_factor; int x, y; float w = page_details->mediabox.x1 - page_details->mediabox.x0; float h = page_details->mediabox.y1 - page_details->mediabox.y0; if (xf == 0 && yf == 0) { /* Nothing specified, so split along the long edge */ if (w > h) xf = 2, yf = 1; else xf = 1, yf = 2; } else if (xf == 0) xf = 1; else if (yf == 0) yf = 1; for (y = yf-1; y >= 0; y--) { for (x = 0; x < xf; x++) { pdf_obj *newpageobj, *newpageref, *newmediabox; fz_rect mb; int num; newpageobj = pdf_copy_dict(ctx, pdf_lookup_page_obj(ctx, doc, page)); num = pdf_create_object(ctx, doc); pdf_update_object(ctx, doc, num, newpageobj); newpageref = pdf_new_indirect(ctx, doc, num, 0); newmediabox = pdf_new_array(ctx, doc, 4); mb.x0 = page_details->mediabox.x0 + (w/xf)*x; if (x == xf-1) mb.x1 = page_details->mediabox.x1; else mb.x1 = page_details->mediabox.x0 + (w/xf)*(x+1); mb.y0 = page_details->mediabox.y0 + (h/yf)*y; if (y == yf-1) mb.y1 = page_details->mediabox.y1; else mb.y1 = page_details->mediabox.y0 + (h/yf)*(y+1); pdf_array_push(ctx, newmediabox, pdf_new_real(ctx, doc, mb.x0)); pdf_array_push(ctx, newmediabox, pdf_new_real(ctx, doc, mb.y0)); pdf_array_push(ctx, newmediabox, pdf_new_real(ctx, doc, mb.x1)); pdf_array_push(ctx, newmediabox, pdf_new_real(ctx, doc, mb.y1)); pdf_dict_put(ctx, newpageobj, PDF_NAME_Parent, parent); pdf_dict_put(ctx, newpageobj, PDF_NAME_MediaBox, newmediabox); /* Store page object in new kids array */ pdf_array_push(ctx, kids, newpageref); kidcount++; } } } pdf_drop_obj(ctx, parent); /* Update page count and kids array */ pdf_dict_put(ctx, pages, PDF_NAME_Count, pdf_new_int(ctx, doc, kidcount)); pdf_dict_put(ctx, pages, PDF_NAME_Kids, kids); pdf_drop_obj(ctx, kids); }
void pdf_set_ink_annot_list(fz_context *ctx, pdf_document *doc, pdf_annot *annot, fz_point *pts, int *counts, int ncount, float color[3], float thickness) { fz_matrix ctm; pdf_obj *list = pdf_new_array(ctx, doc, ncount); pdf_obj *bs, *col; fz_rect rect; int i, k = 0; fz_invert_matrix(&ctm, &annot->page->ctm); pdf_dict_put_drop(ctx, annot->obj, PDF_NAME_InkList, list); for (i = 0; i < ncount; i++) { int j; pdf_obj *arc = pdf_new_array(ctx, doc, counts[i]); pdf_array_push_drop(ctx, list, arc); for (j = 0; j < counts[i]; j++) { fz_point pt = pts[k]; fz_transform_point(&pt, &ctm); if (i == 0 && j == 0) { rect.x0 = rect.x1 = pt.x; rect.y0 = rect.y1 = pt.y; } else { fz_include_point_in_rect(&rect, &pt); } pdf_array_push_drop(ctx, arc, pdf_new_real(ctx, doc, pt.x)); pdf_array_push_drop(ctx, arc, pdf_new_real(ctx, doc, pt.y)); k++; } } /* Expand the rectangle by thickness all around. We cannot use fz_expand_rect because the rectangle might be empty in the single point case */ if (k > 0) { rect.x0 -= thickness; rect.y0 -= thickness; rect.x1 += thickness; rect.y1 += thickness; } pdf_dict_put_drop(ctx, annot->obj, PDF_NAME_Rect, pdf_new_rect(ctx, doc, &rect)); update_rect(ctx, annot); bs = pdf_new_dict(ctx, doc, 1); pdf_dict_put_drop(ctx, annot->obj, PDF_NAME_BS, bs); pdf_dict_put_drop(ctx, bs, PDF_NAME_W, pdf_new_real(ctx, doc, thickness)); col = pdf_new_array(ctx, doc, 3); pdf_dict_put_drop(ctx, annot->obj, PDF_NAME_C, col); for (i = 0; i < 3; i++) pdf_array_push_drop(ctx, col, pdf_new_real(ctx, doc, color[i])); }
pdf_obj * pdf_parse_ind_obj(pdf_document *xref, fz_stream *file, pdf_lexbuf *buf, int *onum, int *ogen, int *ostmofs) { pdf_obj *obj = NULL; int num = 0, gen = 0, stm_ofs; int tok; int a, b; fz_context *ctx = file->ctx; fz_var(obj); tok = pdf_lex(file, buf); /* RJW: cannot parse indirect object (%d %d R)", num, gen */ if (tok != PDF_TOK_INT) fz_throw(ctx, "expected object number (%d %d R)", num, gen); num = buf->i; tok = pdf_lex(file, buf); /* RJW: "cannot parse indirect object (%d %d R)", num, gen */ if (tok != PDF_TOK_INT) fz_throw(ctx, "expected generation number (%d %d R)", num, gen); gen = buf->i; tok = pdf_lex(file, buf); /* RJW: "cannot parse indirect object (%d %d R)", num, gen */ if (tok != PDF_TOK_OBJ) fz_throw(ctx, "expected 'obj' keyword (%d %d R)", num, gen); tok = pdf_lex(file, buf); /* RJW: "cannot parse indirect object (%d %d R)", num, gen */ switch (tok) { case PDF_TOK_OPEN_ARRAY: obj = pdf_parse_array(xref, file, buf); /* RJW: "cannot parse indirect object (%d %d R)", num, gen */ break; case PDF_TOK_OPEN_DICT: obj = pdf_parse_dict(xref, file, buf); /* RJW: "cannot parse indirect object (%d %d R)", num, gen */ break; case PDF_TOK_NAME: obj = fz_new_name(ctx, buf->scratch); break; case PDF_TOK_REAL: obj = pdf_new_real(ctx, buf->f); break; case PDF_TOK_STRING: obj = pdf_new_string(ctx, buf->scratch, buf->len); break; case PDF_TOK_TRUE: obj = pdf_new_bool(ctx, 1); break; case PDF_TOK_FALSE: obj = pdf_new_bool(ctx, 0); break; case PDF_TOK_NULL: obj = pdf_new_null(ctx); break; case PDF_TOK_INT: a = buf->i; tok = pdf_lex(file, buf); /* "cannot parse indirect object (%d %d R)", num, gen */ if (tok == PDF_TOK_STREAM || tok == PDF_TOK_ENDOBJ) { obj = pdf_new_int(ctx, a); goto skip; } if (tok == PDF_TOK_INT) { b = buf->i; tok = pdf_lex(file, buf); /* RJW: "cannot parse indirect object (%d %d R)", num, gen); */ if (tok == PDF_TOK_R) { obj = pdf_new_indirect(ctx, a, b, xref); break; } } fz_throw(ctx, "expected 'R' keyword (%d %d R)", num, gen); case PDF_TOK_ENDOBJ: obj = pdf_new_null(ctx); goto skip; default: fz_throw(ctx, "syntax error in object (%d %d R)", num, gen); } fz_try(ctx) { tok = pdf_lex(file, buf); } fz_catch(ctx) { pdf_drop_obj(obj); fz_throw(ctx, "cannot parse indirect object (%d %d R)", num, gen); } skip: if (tok == PDF_TOK_STREAM) { int c = fz_read_byte(file); while (c == ' ') c = fz_read_byte(file); if (c == '\r') { c = fz_peek_byte(file); if (c != '\n') fz_warn(ctx, "line feed missing after stream begin marker (%d %d R)", num, gen); else fz_read_byte(file); } stm_ofs = fz_tell(file); } else if (tok == PDF_TOK_ENDOBJ) { stm_ofs = 0; } else { fz_warn(ctx, "expected 'endobj' or 'stream' keyword (%d %d R)", num, gen); stm_ofs = 0; } if (onum) *onum = num; if (ogen) *ogen = gen; if (ostmofs) *ostmofs = stm_ofs; return obj; }
pdf_obj * pdf_parse_ind_obj(fz_context *ctx, pdf_document *doc, fz_stream *file, pdf_lexbuf *buf, int *onum, int *ogen, fz_off_t *ostmofs, int *try_repair) { pdf_obj *obj = NULL; int num = 0, gen = 0; fz_off_t stm_ofs; pdf_token tok; fz_off_t a, b; fz_var(obj); tok = pdf_lex(ctx, file, buf); if (tok != PDF_TOK_INT) { if (try_repair) *try_repair = 1; fz_throw(ctx, FZ_ERROR_GENERIC, "expected object number"); } num = buf->i; tok = pdf_lex(ctx, file, buf); if (tok != PDF_TOK_INT) { if (try_repair) *try_repair = 1; fz_throw(ctx, FZ_ERROR_GENERIC, "expected generation number (%d ? obj)", num); } gen = buf->i; tok = pdf_lex(ctx, file, buf); if (tok != PDF_TOK_OBJ) { if (try_repair) *try_repair = 1; fz_throw(ctx, FZ_ERROR_GENERIC, "expected 'obj' keyword (%d %d ?)", num, gen); } tok = pdf_lex(ctx, file, buf); switch (tok) { case PDF_TOK_OPEN_ARRAY: obj = pdf_parse_array(ctx, doc, file, buf); break; case PDF_TOK_OPEN_DICT: obj = pdf_parse_dict(ctx, doc, file, buf); break; case PDF_TOK_NAME: obj = pdf_new_name(ctx, doc, buf->scratch); break; case PDF_TOK_REAL: obj = pdf_new_real(ctx, doc, buf->f); break; case PDF_TOK_STRING: obj = pdf_new_string(ctx, doc, buf->scratch, buf->len); break; case PDF_TOK_TRUE: obj = pdf_new_bool(ctx, doc, 1); break; case PDF_TOK_FALSE: obj = pdf_new_bool(ctx, doc, 0); break; case PDF_TOK_NULL: obj = pdf_new_null(ctx, doc); break; case PDF_TOK_INT: a = buf->i; tok = pdf_lex(ctx, file, buf); if (tok == PDF_TOK_STREAM || tok == PDF_TOK_ENDOBJ) { obj = pdf_new_int_offset(ctx, doc, a); goto skip; } if (tok == PDF_TOK_INT) { b = buf->i; tok = pdf_lex(ctx, file, buf); if (tok == PDF_TOK_R) { obj = pdf_new_indirect(ctx, doc, a, b); break; } } fz_throw(ctx, FZ_ERROR_GENERIC, "expected 'R' keyword (%d %d R)", num, gen); case PDF_TOK_ENDOBJ: obj = pdf_new_null(ctx, doc); goto skip; default: fz_throw(ctx, FZ_ERROR_GENERIC, "syntax error in object (%d %d R)", num, gen); } fz_try(ctx) { tok = pdf_lex(ctx, file, buf); } fz_catch(ctx) { pdf_drop_obj(ctx, obj); fz_rethrow(ctx); } skip: if (tok == PDF_TOK_STREAM) { int c = fz_read_byte(ctx, file); while (c == ' ') c = fz_read_byte(ctx, file); if (c == '\r') { c = fz_peek_byte(ctx, file); if (c != '\n') fz_warn(ctx, "line feed missing after stream begin marker (%d %d R)", num, gen); else fz_read_byte(ctx, file); } stm_ofs = fz_tell(ctx, file); } else if (tok == PDF_TOK_ENDOBJ) { stm_ofs = 0; } else { fz_warn(ctx, "expected 'endobj' or 'stream' keyword (%d %d R)", num, gen); stm_ofs = 0; } if (onum) *onum = num; if (ogen) *ogen = gen; if (ostmofs) *ostmofs = stm_ofs; return obj; }