예제 #1
0
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;
}
예제 #2
0
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;
}
예제 #3
0
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;
}
예제 #4
0
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);
}
예제 #5
0
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;
}
예제 #6
0
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;
}
예제 #7
0
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;
}
예제 #8
0
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));
}
예제 #9
0
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);
    }
예제 #10
0
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 */
}
예제 #11
0
파일: data.c 프로젝트: amba/pdfout
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);
}
예제 #12
0
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++;
	}
예제 #13
0
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;
}
예제 #14
0
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;
}
예제 #15
0
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;
}
예제 #16
0
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);
	}
}
예제 #17
0
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;
}
예제 #18
0
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 */
}
예제 #19
0
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;
}
예제 #20
0
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;
}
예제 #21
0
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;
}
예제 #22
0
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;
}
예제 #23
0
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); */
    }
예제 #24
0
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;
}
예제 #25
0
파일: pdfposter.c 프로젝트: andyhan/mupdf
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);
}
예제 #26
0
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);
}
예제 #27
0
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]));
}
예제 #28
0
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;
}
예제 #29
0
파일: pdf-parse.c 프로젝트: Enzime/mupdf
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;
}