Пример #1
0
static void sweepref(fz_obj *obj)
{
	int num = fz_tonum(obj);
	int gen = fz_togen(obj);

	if (num < 0 || num >= xref->len)
		return;
	if (uselist[num])
		return;

	uselist[num] = 1;

	/* Bake in /Length in stream objects */
	if (pdf_isstream(xref, num, gen))
	{
		fz_obj *len = fz_dictgets(obj, "Length");
		if (fz_isindirect(len))
		{
			uselist[fz_tonum(len)] = 0;
			len = fz_resolveindirect(len);
			fz_dictputs(obj, "Length", len);
		}
	}

	sweepobj(fz_resolveindirect(obj));
}
Пример #2
0
static void removeduplicateobjs(void)
{
	int num, other;

	for (num = 1; num < xref->len; num++)
	{
		/* Only compare an object to objects preceeding it */
		for (other = 1; other < num; other++)
		{
			fz_obj *a, *b;

			if (num == other || !uselist[num] || !uselist[other])
				continue;

			/*
			 * Comparing stream objects data contents would take too long.
			 *
			 * pdf_isstream calls pdf_cacheobject and ensures
			 * that the xref table has the objects loaded.
			 */
			if (pdf_isstream(xref, num, 0) || pdf_isstream(xref, other, 0))
				continue;

			a = xref->table[num].obj;
			b = xref->table[other].obj;

			a = fz_resolveindirect(a);
			b = fz_resolveindirect(b);

			if (fz_objcmp(a, b))
				continue;

			/* Keep the lowest numbered object */
			renumbermap[num] = MIN(num, other);
			renumbermap[other] = MIN(num, other);
			uselist[MAX(num, other)] = 0;

			/* One duplicate was found, do not look for another */
			break;
		}
	}
}
Пример #3
0
static void
printglobalinfo(void)
{
	printf("\nPDF-%d.%d\n", xref->version / 10, xref->version % 10);

	if (info->u.info.obj)
	{
		printf("Info object (%d %d R):\n", fz_tonum(info->ref), fz_togen(info->ref));
		fz_debugobj(fz_resolveindirect(info->u.info.obj));
	}

	if (cryptinfo->u.crypt.obj)
	{
		printf("\nEncryption object (%d %d R):\n", fz_tonum(cryptinfo->ref), fz_togen(cryptinfo->ref));
		fz_debugobj(cryptinfo->u.crypt.obj);
	}

	printf("\nPages: %d\n\n", pagecount);
}
Пример #4
0
static fz_error
loadiccbased(fz_colorspace **csp, pdf_xref *xref, fz_obj *ref)
{
	fz_obj *dict;
	int n;

	pdf_logrsrc("load ICCBased\n");

	dict = fz_resolveindirect(ref);

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

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

	return fz_throw("syntaxerror: ICCBased must have 1, 3 or 4 components");
}
Пример #5
0
Epdf_Document* epdf_document_new(const char* filename)
{
    Epdf_Document* doc;
    fz_error error;

    doc = (Epdf_Document*)malloc(sizeof(Epdf_Document));
    if(!doc)
        return NULL;

    doc->xref = NULL;
    doc->outline = NULL;
    doc->rast = NULL;
    doc->pagecount = 0;
    doc->zoom = 1.0;
    doc->rotate = 0;
    doc->locked = false;

    error = fz_newrenderer(&doc->rast, pdf_devicergb, 0, 1024 * 512);
    if(error)
        return pdfdoc_error(doc);

    fz_obj* obj;

    // Open PDF and load xref table

    doc->xref = pdf_newxref();
    if(!doc->xref)
        return pdfdoc_error(doc);

    error = pdf_loadxref(doc->xref, (char*)filename);
    if(error)
    {
        fz_catch(error, "trying to repair");
        fprintf(stderr, "There was a problem with file \"%s\".\nIt may be corrupted or generated by faulty software.\nTrying to repair the file.\n", filename);
        error = pdf_repairxref(doc->xref, (char*)filename);
        if(error)
            return pdfdoc_error(doc);
    }

    error = pdf_decryptxref(doc->xref);
    if(error)
        pdfdoc_error(doc);

    // Handle encrypted PDF files

    if(pdf_needspassword(doc->xref))
        doc->locked = true;

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

    obj = fz_dictgets(doc->xref->trailer, (char*)"Root");
    doc->xref->root = fz_resolveindirect(obj);
    if(!doc->xref->root)
    {
        fz_throw("syntaxerror: missing Root object");
        pdfdoc_error(doc);
    }
    fz_keepobj(doc->xref->root);

    obj = fz_dictgets(doc->xref->trailer, "Info");
    doc->xref->info = fz_resolveindirect(obj);
    if(!doc->xref->info)
        fprintf(stderr, "Could not load PDF meta information.\n");
    if(doc->xref->info)
        fz_keepobj(doc->xref->info);

    doc->outline = pdf_loadoutline(doc->xref);

    doc->filename = strdup(filename);
    if(doc->xref->info)
    {
        obj = fz_dictgets(doc->xref->info, "Title");
        if(obj)
            doc->doctitle = pdf_toutf8(obj);
    }

    /*
     * Start at first page
     */

    doc->pagecount = pdf_getpagecount(doc->xref);

    if(doc->zoom < 0.1)
        doc->zoom = 0.1;
    if(doc->zoom > 3.0)
        doc->zoom = 3.0;

    return doc;
}
Пример #6
0
void pdfmoz_open(pdfmoz_t *moz, char *filename)
{
    SCROLLINFO si;
    fz_error error;
    fz_obj *obj;
    fz_irect bbox;
    int rot;
    int i;

    strcpy(moz->error, "");

    error = fz_newrenderer(&moz->rast, pdf_devicergb, 0, 1024 * 512);
    if (error)
	pdfmoz_error(moz, error);

    /*
     * Open PDF and load xref table
     */

    moz->filename = filename;

    moz->xref = pdf_newxref();
    error = pdf_loadxref(moz->xref, filename);
    if (error)
    {
	error = pdf_repairxref(moz->xref, filename);
	if (error)
	    pdfmoz_error(moz, error);
    }

    /*
     * Handle encrypted PDF files
     */

    error = pdf_decryptxref(moz->xref);
    if (error)
	pdfmoz_error(moz, error);

    if (pdf_needspassword(moz->xref))
    {
	pdfmoz_warn(moz, "PDF file is encrypted and needs a password.");
    }

    moz->pagecount = pdf_getpagecount(moz->xref);
    moz->pages = fz_malloc(sizeof(page_t) * moz->pagecount);

    for (i = 0; i < moz->pagecount; i++)
    {
	fz_obj *pageobj;
	pageobj = pdf_getpageobject(moz->xref, i);
	moz->pages[i].obj = fz_keepobj(pageobj);
	moz->pages[i].page = nil;
	moz->pages[i].image = nil;

	obj = fz_dictgets(moz->pages[i].obj, "CropBox");
	if (!obj)
	    obj = fz_dictgets(moz->pages[i].obj, "MediaBox");
	bbox = fz_roundrect(pdf_torect(obj));
	moz->pages[i].w = bbox.x1 - bbox.x0;
	moz->pages[i].h = bbox.y1 - bbox.y0;

	rot = fz_toint(fz_dictgets(moz->pages[i].obj, "Rotate"));
	if ((rot / 90) % 2)
	{
	    int t = moz->pages[i].w;
	    moz->pages[i].w = moz->pages[i].h;
	    moz->pages[i].h = t;
	}

	moz->pages[i].px = 1 + PAD;
    }

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

    obj = fz_dictgets(moz->xref->trailer, "Root");
    moz->xref->root = fz_resolveindirect(obj);
    if (!moz->xref->root)
	pdfmoz_error(moz, fz_throw("syntaxerror: missing Root object"));
    if (moz->xref->root)
	fz_keepobj(moz->xref->root);

    obj = fz_dictgets(moz->xref->trailer, "Info");
    moz->xref->info = fz_resolveindirect(obj);
    if (moz->xref->info)
	fz_keepobj(moz->xref->info);

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

    /*
     * Start at first page
     */

    si.cbSize = sizeof(si);
    si.fMask = SIF_POS | SIF_RANGE; // XXX | SIF_PAGE;
    si.nPos = 0;
    si.nMin = 0;
    si.nMax = 1;
    si.nPage = 1;
    SetScrollInfo(moz->hwnd, SB_VERT, &si, TRUE);

    moz->scrollpage = 0;
    moz->scrollyofs = 0;

    InvalidateRect(moz->hwnd, NULL, FALSE);
}
/*
 * Load CMap stream in PDF file
 */
fz_error
pdf_loadembeddedcmap(pdf_cmap **cmapp, pdf_xref *xref, fz_obj *stmref)
{
    fz_error error = fz_okay;
    fz_obj *stmobj;
    fz_stream *file = nil;
    pdf_cmap *cmap = nil;
    pdf_cmap *usecmap;
    fz_obj *wmode;
    fz_obj *obj;

    if ((*cmapp = pdf_finditem(xref->store, PDF_KCMAP, stmref)))
    {
	pdf_keepcmap(*cmapp);
	return fz_okay;
    }

    pdf_logfont("load embedded cmap (%d %d R) {\n", fz_tonum(stmref), fz_togen(stmref));

    stmobj = fz_resolveindirect(stmref);

    error = pdf_openstream(&file, xref, fz_tonum(stmref), fz_togen(stmref));
    if (error)
    {
	error = fz_rethrow(error, "cannot open cmap stream");
	goto cleanup;
    }

    error = pdf_parsecmap(&cmap, file);
    if (error)
    {
	error = fz_rethrow(error, "cannot parse cmap stream");
	goto cleanup;
    }

    fz_dropstream(file);

    wmode = fz_dictgets(stmobj, "WMode");
    if (fz_isint(wmode))
    {
	pdf_logfont("wmode %d\n", wmode);
	pdf_setwmode(cmap, fz_toint(wmode));
    }

    obj = fz_dictgets(stmobj, "UseCMap");
    if (fz_isname(obj))
    {
	pdf_logfont("usecmap /%s\n", fz_toname(obj));
	error = pdf_loadsystemcmap(&usecmap, fz_toname(obj));
	if (error)
	{
	    error = fz_rethrow(error, "cannot load system usecmap '%s'", fz_toname(obj));
	    goto cleanup;
	}
	pdf_setusecmap(cmap, usecmap);
	pdf_dropcmap(usecmap);
    }
    else if (fz_isindirect(obj))
    {
	pdf_logfont("usecmap (%d %d R)\n", fz_tonum(obj), fz_togen(obj));
	error = pdf_loadembeddedcmap(&usecmap, xref, obj);
	if (error)
	{
	    error = fz_rethrow(error, "cannot load embedded usecmap");
	    goto cleanup;
	}
	pdf_setusecmap(cmap, usecmap);
	pdf_dropcmap(usecmap);
    }

    pdf_logfont("}\n");

    error = pdf_storeitem(xref->store, PDF_KCMAP, stmref, cmap);
    if (error)
    {
	error = fz_rethrow(error, "cannot store cmap resource");
	goto cleanup;
    }

    *cmapp = cmap;
    return fz_okay;

cleanup:
    if (file)
	fz_dropstream(file);
    if (cmap)
	pdf_dropcmap(cmap);
    return error; /* already rethrown */
}
Пример #8
0
void
pdf_loadpagetreenode(pdf_xref *xref, fz_obj *node, struct info info)
{
	fz_obj *dict, *kids, *count;
	fz_obj *obj, *tmp;
	int i, n;

	/* prevent infinite recursion */
	if (fz_dictgets(node, ".seen"))
		return;

	kids = fz_dictgets(node, "Kids");
	count = fz_dictgets(node, "Count");

	if (fz_isarray(kids) && fz_isint(count))
	{
		obj = fz_dictgets(node, "Resources");
		if (obj)
			info.resources = obj;
		obj = fz_dictgets(node, "MediaBox");
		if (obj)
			info.mediabox = obj;
		obj = fz_dictgets(node, "CropBox");
		if (obj)
			info.cropbox = obj;
		obj = fz_dictgets(node, "Rotate");
		if (obj)
			info.rotate = obj;

		tmp = fz_newnull();
		fz_dictputs(node, ".seen", tmp);
		fz_dropobj(tmp);

		n = fz_arraylen(kids);
		for (i = 0; i < n; i++)
		{
			obj = fz_arrayget(kids, i);
			pdf_loadpagetreenode(xref, obj, info);
		}

		fz_dictdels(node, ".seen");
	}
	else
	{
		dict = fz_resolveindirect(node);

		if (info.resources && !fz_dictgets(dict, "Resources"))
			fz_dictputs(dict, "Resources", info.resources);
		if (info.mediabox && !fz_dictgets(dict, "MediaBox"))
			fz_dictputs(dict, "MediaBox", info.mediabox);
		if (info.cropbox && !fz_dictgets(dict, "CropBox"))
			fz_dictputs(dict, "CropBox", info.cropbox);
		if (info.rotate && !fz_dictgets(dict, "Rotate"))
			fz_dictputs(dict, "Rotate", info.rotate);

		if (xref->pagelen == xref->pagecap)
		{
			fz_warn("found more pages than expected");
			xref->pagecap ++;
			xref->pagerefs = fz_realloc(xref->pagerefs, sizeof(fz_obj*) * xref->pagecap);
			xref->pageobjs = fz_realloc(xref->pageobjs, sizeof(fz_obj*) * xref->pagecap);
		}

		xref->pagerefs[xref->pagelen] = fz_keepobj(node);
		xref->pageobjs[xref->pagelen] = fz_keepobj(dict);
		xref->pagelen ++;
	}
}
Пример #9
0
void pdfapp_open(pdfapp_t *app, char *filename)
{
#if 0
	fz_error error;
	fz_obj *obj;
	char *password = "";
#else
	fz_error error;
	fz_stream *file;
	char *password = "";
	fz_obj *obj;
	fz_obj *info;

	int fd;
	fd = open(filename, O_BINARY | O_RDONLY, 0666);
	if (fd < 0)
		fprintf(stderr, "error, file %s does not exist\n", filename);
#endif

	/*
	 * Open PDF and load xref table
	 */

	app->filename = filename;

#if 0
	app->xref = pdf_newxref();
	error = pdf_loadxref(app->xref, filename);
	if (error)
	{
		fz_catch(error, "trying to air");
		error = pdf_repairxref(app->xref, filename);
		if (error)
			pdfapp_error(app, error);
	}

	error = pdf_decryptxref(app->xref);
	if (error)
		pdfapp_error(app, error);
#else
	file = fz_open_fd(fd);
	error = pdf_open_xref_with_stream(&app->xref, file, NULL);
	if (error)
		pdfapp_error(app, fz_rethrow(error, "cannot open document '%s'", filename));
	fz_close(file);
#endif

	/*
	 * Handle encrypted PDF files
	 */

	if (pdf_needs_password(app->xref))
	{
		int okay = pdf_authenticate_password(app->xref, password);
		while (!okay)
		{	
		        //password = winpassword(app, filename);
			if (!password)
				exit(1);
			okay = pdf_authenticate_password(app->xref, password);
			if (!okay)
				pdfapp_warn(app, "Invalid password.");
		}
	}

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

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

	obj = fz_dictgets(app->xref->trailer, "Info");
	app->xref->info = fz_resolveindirect(obj);
	if (!app->xref->info)
		pdfapp_warn(app, "Could not load PDF meta information.");
	if (app->xref->info)
		fz_keepobj(app->xref->info);

	/*app->outline = pdf_loadoutline(app->xref);*/

	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)
		{
			app->doctitle = pdf_toutf8(obj);
		}
	}
#else
	app->outline = pdf_load_outline(app->xref);

	app->doctitle = filename;
	if (strrchr(app->doctitle, '\\'))
		app->doctitle = strrchr(app->doctitle, '\\') + 1;
	if (strrchr(app->doctitle, '/'))
		app->doctitle = strrchr(app->doctitle, '/') + 1;
	info = fz_dict_gets(app->xref->trailer, "Info");
	if (info)
	{
		obj = fz_dict_gets(info, "Title");
		if (obj)
			app->doctitle = pdf_to_utf8(obj);
	}
#endif

	/*
	 * Start at first page
	 */

#if 0
	app->pagecount = pdf_getpagecount(app->xref);
#else
	error = pdf_load_page_tree(app->xref);
	if (error)
		pdfapp_error(app, fz_rethrow(error, "cannot load page tree"));

	app->pagecount = pdf_count_pages(app->xref);
#endif
	
	app->rotate = 0;
	
}