static fz_error *
loadiccbased(fz_colorspace **csp, pdf_xref *xref, fz_obj *ref)
{
	fz_error *error;
	fz_obj *dict;
	int n;

	pdf_logrsrc("load ICCBased\n");

	error = pdf_loadindirect(&dict, xref, ref);
	if (error)
		return error;

	n = fz_toint(fz_dictgets(dict, "N"));

	fz_dropobj(dict);

	switch (n)
	{
	case 1: *csp = pdf_devicegray; return nil;
	case 3: *csp = pdf_devicergb; return nil;
	case 4: *csp = pdf_devicecmyk; return nil;
	}

	return fz_throw("syntaxerror: ICCBased must have 1, 3 or 4 components");
}
示例#2
0
int
openPdfFile(
    soPdfFile* pdfFile
    )
{
    fz_error    *error;
    fz_obj      *obj;

    //
    // open pdf and load xref table
    error = pdf_newxref(&pdfFile->xref);
    if (error)
        return soPdfError(error);

    error = pdf_loadxref(pdfFile->xref, pdfFile->fileName);
    if (error)
        return soPdfError(error);

    //
    // Handle encrypted file
    error = pdf_decryptxref(pdfFile->xref);
    if (error)
        return soPdfError(error);

    if (pdfFile->xref->crypt)
    {
        int ret = pdf_setpassword(pdfFile->xref->crypt, 
            pdfFile->password);
        if (! ret)
            return soPdfError(fz_throw("invalid password"));
    }

    //
    // load the page tree and other objects
    error = pdf_loadpagetree(&pdfFile->pageTree, pdfFile->xref);
    if (error)
        return soPdfError(error);

    //
    // load meta information
    obj = fz_dictgets(pdfFile->xref->trailer, "Root");
    if (! obj)
        return soPdfError(fz_throw("mising root object"));

    error = pdf_loadindirect(&pdfFile->xref->root, pdfFile->xref, obj);
    if (error)
        return soPdfError(error);


    obj = fz_dictgets(pdfFile->xref->trailer, "Info");
    if (obj)
    {
        error = pdf_loadindirect(&pdfFile->xref->info, pdfFile->xref, obj);
        if (error)
            return soPdfError(error);
    }

    error = pdf_loadnametrees(pdfFile->xref);
    if (error)
        return soPdfError(error);

    error = pdf_loadoutline(&pdfFile->outline, pdfFile->xref);
    if (error)
        return soPdfError(error);

    return 0;
}
示例#3
0
fz_error *
pdf_loadpagetree(pdf_pagetree **pp, pdf_xref *xref)
{
	fz_error *error;
	struct stuff inherit;
	pdf_pagetree *p = nil;
	fz_obj *catalog = nil;
	fz_obj *pages = nil;
	fz_obj *trailer;
	fz_obj *ref;
	fz_obj *treeref;
	int count;
	int pagenum = 1;

	inherit.resources = nil;
	inherit.mediabox = nil;
	inherit.cropbox = nil;
	inherit.rotate = nil;

	trailer = xref->trailer;

	ref = fz_dictgets(trailer, "Root");
	error = pdf_loadindirect(&catalog, xref, ref);
	if (error) { error = fz_rethrow(error, "cannot load Root object"); goto cleanup; }

	treeref = fz_dictgets(catalog, "Pages");
	error = pdf_loadindirect(&pages, xref, treeref);
	if (error) { error = fz_rethrow(error, "cannot load Pages object"); goto cleanup; }

	ref = fz_dictgets(pages, "Count");
	count = fz_toint(ref);

	p = fz_malloc(sizeof(pdf_pagetree));
	if (!p) { error = fz_throw("outofmem: page tree struct"); goto cleanup; }

	pdf_logpage("load pagetree %d pages, %d %d (%p) {\n", count, treeref->u.r.oid, treeref->u.r.gid, p);

	p->pref = nil;
	p->pobj = nil;
	p->count = count;
	p->cursor = 0;

	p->pref = fz_malloc(sizeof(fz_obj*) * count);
	if (!p->pref) { error = fz_throw("outofmem: page tree reference array"); goto cleanup; }

	p->pobj = fz_malloc(sizeof(fz_obj*) * count);
	if (!p->pobj) { error = fz_throw("outofmem: page tree object array"); goto cleanup; }

	error = loadpagetree(xref, p, inherit, pages, treeref, &pagenum);
	if (error) { error = fz_rethrow(error, "cannot load pagetree"); goto cleanup; }

	fz_dropobj(pages);
	fz_dropobj(catalog);

	pdf_logpage("}\n", count);

	*pp = p;
	return fz_okay;

cleanup:
	if (pages) fz_dropobj(pages);
	if (catalog) fz_dropobj(catalog);
	if (p) {
		fz_free(p->pref);
		fz_free(p->pobj);
		fz_free(p);
	}
	return error; /* already rethrown */
}
示例#4
0
static fz_error *
loadpagetree(pdf_xref *xref, pdf_pagetree *pages,
		struct stuff inherit, fz_obj *obj, fz_obj *ref, int *pagenum)
{
	fz_error *error;
	fz_obj *type;
	fz_obj *kids;
	fz_obj *kref, *kobj;
	fz_obj *inh;
	int i;

	type = fz_dictgets(obj, "Type");

	if (strcmp(fz_toname(type), "Page") == 0)
	{
		pdf_logpage("page %d, %d %d\n", *pagenum, ref->u.r.oid, ref->u.r.gid);
		(*pagenum)++;

		if (inherit.resources && !fz_dictgets(obj, "Resources"))
		{
			pdf_logpage("inherit resources (%d)\n", pages->cursor);
			error = fz_dictputs(obj, "Resources", inherit.resources);
			if (error) return fz_rethrow(error, "cannot inherit page tree resources");
		}

		if (inherit.mediabox && !fz_dictgets(obj, "MediaBox"))
		{
			pdf_logpage("inherit mediabox (%d)\n", pages->cursor);
			error = fz_dictputs(obj, "MediaBox", inherit.mediabox);
			if (error) return fz_rethrow(error, "cannot inherit page tree mediabox");
		}

		if (inherit.cropbox && !fz_dictgets(obj, "CropBox"))
		{
			pdf_logpage("inherit cropbox (%d)\n", pages->cursor);
			error = fz_dictputs(obj, "CropBox", inherit.cropbox);
			if (error) return fz_rethrow(error, "cannot inherit page tree cropbox");
		}

		if (inherit.rotate && !fz_dictgets(obj, "Rotate"))
		{
			pdf_logpage("inherit rotate (%d)\n", pages->cursor);
			error = fz_dictputs(obj, "Rotate", inherit.rotate);
			if (error) return fz_rethrow(error, "cannot inherit page tree rotate");
		}

		pages->pref[pages->cursor] = fz_keepobj(ref);
		pages->pobj[pages->cursor] = fz_keepobj(obj);
		pages->cursor ++;
	}

	else if (strcmp(fz_toname(type), "Pages") == 0)
	{
		inh = fz_dictgets(obj, "Resources");
		if (inh) inherit.resources = inh;

		inh = fz_dictgets(obj, "MediaBox");
		if (inh) inherit.mediabox = inh;

		inh = fz_dictgets(obj, "CropBox");
		if (inh) inherit.cropbox = inh;

		inh = fz_dictgets(obj, "Rotate");
		if (inh) inherit.rotate = inh;

		kids = fz_dictgets(obj, "Kids");
		error = pdf_resolve(&kids, xref);
		if (error)
			return fz_rethrow(error, "cannot resolve /Kids");

		pdf_logpage("subtree %d pages, %d %d {\n",
				fz_arraylen(kids), ref->u.r.oid, ref->u.r.gid);

		for (i = 0; i < fz_arraylen(kids); i++)
		{
			kref = fz_arrayget(kids, i);

			error = pdf_loadindirect(&kobj, xref, kref);
			if (error) { fz_dropobj(kids); return fz_rethrow(error, "cannot load kid"); }

			if (kobj == obj)
			{
				/* prevent infinite recursion possible in maliciously crafted PDFs */
				fz_dropobj(kids);
				return fz_throw("corrupted pdf file");
			}

			error = loadpagetree(xref, pages, inherit, kobj, kref, pagenum);
			fz_dropobj(kobj);
			if (error) { fz_dropobj(kids); return fz_rethrow(error, "cannot load subtree"); }
		}

		fz_dropobj(kids);

		pdf_logpage("}\n");
	}

	else
		return fz_throw("pagetree node has unexpected type %s", fz_toname(type));

	return fz_okay;
}
示例#5
0
void opensrc(char *filename, char *password, int loadpages)
{
	fz_error *error;
	fz_obj *obj;

	closesrc();

	srcname = filename;

	error = pdf_newxref(&src);
	if (error)
		die(error);

	error = pdf_loadxref(src, filename);
	if (error)
	{
		fz_printerror(error);
		fz_droperror(error);
		fz_warn("trying to repair");
		error = pdf_repairxref(src, filename);
		if (error)
			die(error);
	}

	error = pdf_decryptxref(src);
	if (error)
		die(error);

	if (src->crypt)
	{
		int okay = pdf_setpassword(src->crypt, password);
		if (!okay)
			die(fz_throw("invalid password"));
	}

	if (loadpages)
	{
		error = pdf_loadpagetree(&srcpages, src);
		if (error)
			die(error);
	}

	/* TODO: move into mupdf lib, see pdfapp_open in pdfapp.c */
	obj = fz_dictgets(src->trailer, "Root");
	if (!obj)
		die(error);

	error = pdf_loadindirect(&src->root, src, obj);
	if (error)
		die(error);

	obj = fz_dictgets(src->trailer, "Info");
	if (obj)
	{
		error = pdf_loadindirect(&src->info, src, obj);
		if (error)
			die(error);
	}

	error = pdf_loadnametrees(src);
	if (error)
		die(error);

	error = pdf_loadoutline(&srcoutline, src);
	if (error)
		die(error);
}
示例#6
0
void pdfapp_open(pdfapp_t *app, char *filename)
{
	fz_error *error;
	fz_obj *obj;
	char *password = "";

	/*
	 * Open PDF and load xref table
	 */

	app->filename = filename;

	error = pdf_newxref(&app->xref);
	if (error)
		pdfapp_error(app, error);

	error = pdf_loadxref(app->xref, filename);
	if (error)
	{
		if (!strncmp(error->msg, "ioerror", 7))
			pdfapp_error(app, error);
		pdfapp_warn(app,
			"There was a problem with file \"%s\".\n"
			"It may be corrupted, or generated by broken software.\n\n"
			"%s\n\nTrying to continue anyway...",
				filename, error->msg);
		error = pdf_repairxref(app->xref, filename);
		if (error)
			pdfapp_error(app, error);
	}

	/*
	 * Handle encrypted PDF files
	 */

	error = pdf_decryptxref(app->xref);
	if (error)
		pdfapp_error(app, error);

	if (app->xref->crypt)
	{
		error = pdf_setpassword(app->xref->crypt, password);
		while (error)
		{
			fz_droperror(error);
			password = winpassword(app, filename);
			if (!password)
				exit(1);
			error = pdf_setpassword(app->xref->crypt, password);
			if (error)
				pdfapp_warn(app, "Invalid password.");
		}
	}

	/*
	 * Load page tree
	 */

	error = pdf_loadpagetree(&app->pages, app->xref);
	if (error)
		pdfapp_error(app, error);

	/*
	 * Load meta information
	 * TODO: move this into mupdf library
	 */

	obj = fz_dictgets(app->xref->trailer, "Root");
	if (!obj)
		pdfapp_error(app, fz_throw("syntaxerror: missing Root object"));

	error = pdf_loadindirect(&app->xref->root, app->xref, obj);
	if (error)
		pdfapp_error(app, error);

	obj = fz_dictgets(app->xref->trailer, "Info");
	if (obj)
	{
		error = pdf_loadindirect(&app->xref->info, app->xref, obj);
		if (error)
			pdfapp_error(app, error);
	}

	error = pdf_loadnametrees(app->xref);
	if (error)
		pdfapp_error(app, error);

	error = pdf_loadoutline(&app->outline, app->xref);
	if (error)
		pdfapp_error(app, error);

	app->doctitle = filename;
	if (strrchr(app->doctitle, '\\'))
		app->doctitle = strrchr(app->doctitle, '\\') + 1;
	if (strrchr(app->doctitle, '/'))
		app->doctitle = strrchr(app->doctitle, '/') + 1;
	if (app->xref->info)
	{
		obj = fz_dictgets(app->xref->info, "Title");
		if (obj)
		{
			error = pdf_toutf8(&app->doctitle, obj);
			if (error)
				pdfapp_error(app, error);
		}
	}

	/*
	 * Start at first page
	 */

	app->shrinkwrap = 1;
	if (app->pageno < 1)
		app->pageno = 1;
	if (app->zoom <= 0.0)
		app->zoom = 1.0;
	app->rotate = 0;
	app->panx = 0;
	app->pany = 0;

	pdfapp_showpage(app, 1, 1);
}
示例#7
0
static PDFContext* pdfOpen(char *filename) {
	PDFContext* ctx = new PDFContext();
	memset(ctx, 0, sizeof(PDFContext));
	fz_error *error;
	fz_obj *obj;

	error = fz_newrenderer(&ctx->rast, pdf_devicergb, 0, 1024 * 512);
	if (error) {
		printf("err0: %s\n", error->msg);
		delete ctx;
		return 0;
	}

	/*
	* Open PDF and load xref table
	*/
	error = pdf_newxref(&ctx->xref);
	if (error) {
		printf("err1: %s\n", error->msg);
		delete ctx;
		return 0;
	}

	error = pdf_loadxref(ctx->xref, filename);
	if (error) {
		printf("err2: %s\n", error->msg);
		if (!strncmp(error->msg, "ioerror", 7)) {
			delete ctx;
			return 0;
		}
		printf("There was a problem with file \"%s\".\n"
			"It may be corrupted, or generated by broken software.\n\n"
			"%s\n\nTrying to continue anyway...\n", filename, error->msg);
		error = pdf_repairxref(ctx->xref, filename);
		if (error) {
			printf("err3: %s\n", error->msg);
			delete ctx;
			return 0;
		}
	}

	/*
	* Handle encrypted PDF files
	*/

	error = pdf_decryptxref(ctx->xref);
	if (error) {
		printf("err4: %s\n", error->msg);
		delete ctx;
		return 0;
	}

	/*if (ctx->xref->crypt) {
		//printf("err5: %s\n", error->msg);
		printf("err5\n", error->msg);
		delete ctx;
		return 0;
	}*/

	if (ctx->xref->crypt) {
		error = pdf_setpassword(ctx->xref->crypt, "");
		if (error) {
			printf("err5: encrypted file (tried empty password): %s\n", error->msg);
			delete ctx;
			return 0;
			/*
			fz_droperror(error);
			password = winpassword(app, filename);
			if (!password)
				exit(1);
			error = pdf_setpassword(app->xref->crypt, password);
			if (error)
				pdfapp_warn(app, "Invalid password.");
			*/
		}
	}

	/*
	* Load page tree
	*/
	error = pdf_loadpagetree(&ctx->pages, ctx->xref);
	if (error) {
		printf("err6: %s\n", error->msg);
		delete ctx;
		return 0;
	}

	/*
	* Load meta information
	* TODO: move this into mupdf library
	*/
	obj = fz_dictgets(ctx->xref->trailer, "Root");
	if (!obj) {
		printf("err7: %s\n", error->msg);
		//pdfapp_error(app, fz_throw("syntaxerror: missing Root object"));
		delete ctx;
		return 0;
	}

	error = pdf_loadindirect(&ctx->xref->root, ctx->xref, obj);
	if (error) {
		printf("err8: %s\n", error->msg);
		delete ctx;
		return 0;
	}

	obj = fz_dictgets(ctx->xref->trailer, "Info");
	if (obj) {

		error = pdf_loadindirect(&ctx->xref->info, ctx->xref, obj);

		if (error) {
			printf("err10: %s\n", error->msg);
			delete ctx;
			return 0;
		}
	}

	error = pdf_loadnametrees(ctx->xref);
	// non-critical error, we can live without the outline
	if (error) {
		printf("warn11 - no outline: %s\n", error->msg);
	} else {
		error = pdf_loadoutline(&ctx->outline, ctx->xref);
		if (error) {
			printf("warn12 - no outline: %s\n", error->msg);
		}
	}
/*
	char* ptitle = filename;
	if (strrchr(app->doctitle, '\\'))
		pt = strrchr(app->doctitle, '\\') + 1;
	if (strrchr(app->doctitle, '/'))
		app->doctitle = strrchr(app->doctitle, '/') + 1;
	if (app->xref->info) {
		obj = fz_dictgets(app->xref->info, "Title");
		if (obj) {
			error = pdf_toutf8(&app->doctitle, obj);
			if (error) {
				delete ctx;
				return 0;
			}
		}
	}
*/
	/*
	* Start at first page
	*/
/*
	app->shrinkwrap = 1;
	if (app->pageno < 1)
		app->pageno = 1;
	if (app->zoom <= 0.0)
		app->zoom = 1.0;
	app->rotate = 0;
	app->panx = 0;
	app->pany = 0;

	pdfapp_showpage(app, 1, 1);
*/

	ctx->pageno = 1;
	ctx->zoom = 1.0f;
	ctx->zoomLevel = 4;
	ctx->rotate = 0.0f;
	ctx->rotateLevel = 0;
	return ctx;
}
示例#8
0
/* TODO error cleanup */
fz_error *
pdf_loadimage(pdf_image **imgp, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
{
	fz_error *error;
	pdf_image *img;
	pdf_image *mask;
	int ismask;
	fz_obj *obj;
	fz_obj *sub;
	int i;

	int w, h, bpc;
	int n = 0;
	int a = 0;
	int usecolorkey = 0;
	fz_colorspace *cs = nil;
	pdf_indexed *indexed = nil;
	int stride;
#ifndef PSP
	printf("LI\n");
#endif
	if ((*imgp = pdf_finditem(xref->store, PDF_KIMAGE, ref)))
	{
		fz_keepimage((fz_image*)*imgp);
		return nil;
	}

	img = fz_malloc(sizeof(pdf_image));
	if (!img)
		return fz_outofmem;

	img->super.refs = 0;

	pdf_logimage("load image %d %d (%p) {\n", fz_tonum(ref), fz_togen(ref), img);

	/*
	 * Dimensions, BPC and ColorSpace
	 */

	w = fz_toint(fz_dictgets(dict, "Width"));
	h = fz_toint(fz_dictgets(dict, "Height"));
	bpc = fz_toint(fz_dictgets(dict, "BitsPerComponent"));

	pdf_logimage("size %dx%d %d\n", w, h, bpc);

	cs = nil;
	obj = fz_dictgets(dict, "ColorSpace");
	if (obj)
	{
		cs = pdf_finditem(xref->store, PDF_KCOLORSPACE, obj);
		if (cs)
			fz_keepcolorspace(cs);
		else
		{
			error = pdf_resolve(&obj, xref);
			if (error)
				return error;

			error = pdf_loadcolorspace(&cs, xref, obj);
			if (error)
				return error;

			fz_dropobj(obj);
		}

		if (!strcmp(cs->name, "Indexed"))
		{
			pdf_logimage("indexed\n");
			indexed = (pdf_indexed*)cs;
			cs = indexed->base;
		}
		n = cs->n;
		a = 0;

		pdf_logimage("colorspace %s\n", cs->name);
	}

	/*
	 * ImageMask, Mask and SoftMask
	 */

	mask = nil;

	ismask = fz_tobool(fz_dictgets(dict, "ImageMask"));
	if (ismask)
	{
		pdf_logimage("is mask\n");
		bpc = 1;
		n = 0;
		a = 1;
	}

	obj = fz_dictgets(dict, "SMask");
	if (fz_isindirect(obj))
	{
		pdf_logimage("has soft mask\n");

		error = pdf_loadindirect(&sub, xref, obj);
		if (error)
			return error;

		error = pdf_loadimage(&mask, xref, sub, obj);
		if (error)
			return error;

		if (mask->super.cs != pdf_devicegray)
			return fz_throw("syntaxerror: SMask must be DeviceGray");

		mask->super.cs = 0;
		mask->super.n = 0;
		mask->super.a = 1;

		fz_dropobj(sub);
	}

	obj = fz_dictgets(dict, "Mask");
	if (fz_isindirect(obj))
	{
		error = pdf_loadindirect(&sub, xref, obj);
		if (error)
			return error;
		if (fz_isarray(sub))
		{
			usecolorkey = 1;
			loadcolorkey(img->colorkey, bpc, indexed != nil, sub);
		}
		else
		{
			pdf_logimage("has mask\n");
			error = pdf_loadimage(&mask, xref, sub, obj);
			if (error)
				return error;
		}
		fz_dropobj(sub);
	}
	else if (fz_isarray(obj))
	{
		usecolorkey = 1;
		loadcolorkey(img->colorkey, bpc, indexed != nil, obj);
	}

	/*
	 * Decode
	 */

	obj = fz_dictgets(dict, "Decode");
	if (fz_isarray(obj))
	{
		pdf_logimage("decode array\n");
		if (indexed)
			for (i = 0; i < 2; i++)
				img->decode[i] = fz_toreal(fz_arrayget(obj, i));
		else
			for (i = 0; i < (n + a) * 2; i++)
				img->decode[i] = fz_toreal(fz_arrayget(obj, i));
	}
	else
	{
		if (indexed)
			for (i = 0; i < 2; i++)
				img->decode[i] = i & 1 ? (1 << bpc) - 1 : 0;
		else
			for (i = 0; i < (n + a) * 2; i++)
				img->decode[i] = i & 1;
	}

	/*
	 * Load samples
	 */

	if (indexed)
		stride = (w * bpc + 7) / 8;
	else
		stride = (w * (n + a) * bpc + 7) / 8;

	// ccm
	// do not load images larger than 2MB uncompressed
	int early_reject = 0;
	if (h * stride <= 2*1024*1024) {
		error = pdf_loadstream(&img->samples, xref, fz_tonum(ref), fz_togen(ref));
		if (error)
		{
			/* TODO: colorspace? */
			fz_free(img);
			return error;
		}
	
		if (img->samples->wp - img->samples->bp < stride * h)
		{
			/* TODO: colorspace? */
			fz_dropbuffer(img->samples);
			fz_free(img);
			return fz_throw("syntaxerror: truncated image data");
		}
	
		/* 0 means opaque and 1 means transparent, so we invert to get alpha */
		if (ismask)
		{
			unsigned char *p;
			for (p = img->samples->bp; p < img->samples->ep; p++)
				*p = ~*p;
		}
	} else {
#ifndef PSP
		printf("LI - %p - early reject\n", img);
#endif
		img->samples = nil;
		early_reject = 1;
	}

	/*
	 * Create image object
	 */

	img->super.loadtile = pdf_loadtile;
	img->super.drop = pdf_dropimage;
	img->super.cs = cs;
	img->super.w = w;
	img->super.h = h;
	img->super.n = n;
	img->super.a = a;
	img->indexed = indexed;
	img->stride = stride;
	img->bpc = bpc;
	img->mask = (fz_image*)mask;
	img->usecolorkey = usecolorkey;
	if (img->mask)
		fz_keepimage(img->mask);

	// ccm
	#if 1
	int bs = 0;
	if (img->samples)
		bs = (int)(img->samples->wp) - (int)(img->samples->rp);
	if (early_reject || (image_buffers_size + bs >= image_buffers_size_max)) {
#ifndef PSP
		printf("LI - %p - optimized out\n", img);
#endif
		if (img->samples)
			fz_dropbuffer(img->samples);
		if (img->mask)
			fz_dropimage(img->mask);
		fz_newbuffer(&img->samples, 8);
		img->super.w = 1;
		img->super.h = 1;
		img->super.n = 3;
		img->super.a = 0;
		img->super.refs = 0;
		unsigned char *p;
		for (p = img->samples->bp; p < img->samples->ep; p++)
			*p = 0x7f;
		img->indexed = 0;
		img->stride = (1 * (3 + 0) * 8 + 7) / 8; //(w * (n + a) * bpc + 7) / 8;
		img->super.cs = cs;
		img->super.loadtile = fakeImageTile;
		img->bpc = 8;
		img->mask = NULL;
		img->usecolorkey = 0;
	} else {
		image_buffers_size += bs;
	}
	#endif

	pdf_logimage("}\n");

	error = pdf_storeitem(xref->store, PDF_KIMAGE, ref, img);
	if (error)
	{
		fz_dropimage((fz_image*)img);
		return error;
	}

	*imgp = img;
	return nil;
}