⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pdf_xref.c.svn-base

📁 SumatraPDF是一款小型开源的pdf阅读工具。虽然玲珑小巧(只有800多KB)
💻 SVN-BASE
字号:
#include "fitz.h"#include "mupdf.h"/* * create xref structure. * needs to be initialized by initxref, openxref or repairxref. */fz_error *pdf_newxref(pdf_xref **xrefp){	pdf_xref *xref;	xref = fz_malloc(sizeof(pdf_xref));	if (!xref)		return fz_throw("outofmem: xref struct");	memset(xref, 0, sizeof(pdf_xref));	pdf_logxref("newxref %p\n", xref);	xref->file = nil;	xref->version = 13;	xref->startxref = 0;	xref->crypt = nil;	xref->trailer = nil;	xref->root = nil;	xref->info = nil;	xref->dests = nil;	xref->store = nil;	xref->cap = 0;	xref->len = 0;	xref->table = nil;	xref->store = nil;	/* you need to create this if you want to render */	*xrefp = xref;	return fz_okay;}voidpdf_closexref(pdf_xref *xref){	pdf_logxref("closexref %p\n", xref);	/* don't touch the pdf_store module ... we don't want that dependency here */	if (xref->store)		fz_warn("someone forgot to empty the store before freeing xref!");	if (xref->table)	{		pdf_flushxref(xref, 1);		fz_free(xref->table);	}	if (xref->file)		fz_dropstream(xref->file);	if (xref->trailer)		fz_dropobj(xref->trailer);	if (xref->root)		fz_dropobj(xref->root);	if (xref->info)		fz_dropobj(xref->info);	if (xref->dests)		fz_dropobj(xref->dests);	if (xref->crypt)		pdf_dropcrypt(xref->crypt);	fz_free(xref);}fz_error *pdf_initxref(pdf_xref *xref){	xref->table = fz_malloc(sizeof(pdf_xrefentry) * 128);	if (!xref->table)		return fz_throw("outofmem: xref table");	xref->cap = 128;	xref->len = 1;	xref->crypt = nil;	xref->table[0].type = 'f';	xref->table[0].mark = 0;	xref->table[0].ofs = 0;	xref->table[0].gen = 65535;	xref->table[0].stmbuf = nil;	xref->table[0].stmofs = 0;	xref->table[0].obj = nil;	return fz_okay;}voidpdf_flushxref(pdf_xref *xref, int force){	int i;	pdf_logxref("flushxref %p (%d)\n", xref, force);	for (i = 0; i < xref->len; i++)	{		if (force)		{			if (xref->table[i].stmbuf)			{				fz_dropbuffer(xref->table[i].stmbuf);				xref->table[i].stmbuf = nil;			}			if (xref->table[i].obj)			{				fz_dropobj(xref->table[i].obj);				xref->table[i].obj = nil;			}		}		else		{			if (xref->table[i].stmbuf && xref->table[i].stmbuf->refs == 1)			{				fz_dropbuffer(xref->table[i].stmbuf);				xref->table[i].stmbuf = nil;			}			if (xref->table[i].obj && xref->table[i].obj->refs == 1)			{				fz_dropobj(xref->table[i].obj);				xref->table[i].obj = nil;			}		}	}}voidpdf_debugxref(pdf_xref *xref){	int i;	printf("xref\n0 %d\n", xref->len);	for (i = 0; i < xref->len; i++)	{		printf("%010d %05d %c | %d %c%c\n",				xref->table[i].ofs,				xref->table[i].gen,				xref->table[i].type,				xref->table[i].obj ? xref->table[i].obj->refs : 0,				xref->table[i].stmofs ? 'f' : '-',				xref->table[i].stmbuf ? 'b' : '-');	}}/* ICKY! */fz_error *pdf_decryptxref(pdf_xref *xref){	fz_error *error;	fz_obj *encrypt;	fz_obj *id;	encrypt = fz_dictgets(xref->trailer, "Encrypt");	id = fz_dictgets(xref->trailer, "ID");	if (encrypt && id)	{		error = pdf_resolve(&encrypt, xref);		if (error)			return fz_rethrow(error, "cannot resolve /Encrypt object");		if (fz_isnull(encrypt))		{			fz_dropobj(encrypt);			return fz_okay;		}		error = pdf_resolve(&id, xref);		if (error)		{			fz_dropobj(encrypt);			return fz_rethrow(error, "cannot resolve /ID object");		}		error = pdf_newdecrypt(&xref->crypt, encrypt, id);		fz_dropobj(encrypt);		fz_dropobj(id);		if (error)			return fz_rethrow(error, "cannot create decrypter");	}	return fz_okay;}/* * mutate objects */static int findprev(pdf_xref *xref, int oid){	int prev;	for (prev = oid - 1; prev >= 0; prev--)		if (xref->table[prev].type == 'f' || xref->table[prev].type == 'd')			return prev;	return 0;}static int findnext(pdf_xref *xref, int oid){	int next;	for (next = oid + 1; next < xref->len; next++)		if (xref->table[next].type == 'f' || xref->table[next].type == 'd')			return next;	return 0;}fz_error *pdf_allocobject(pdf_xref *xref, int *oidp, int *genp){	pdf_xrefentry *x;	int prev, next;	int oid = 0;	pdf_logxref("allocobj");	while (1)	{		x = xref->table + oid;		if (x->type == 'f' || x->type == 'd')		{			if (x->gen < 65535)			{				*oidp = oid;				*genp = x->gen;				pdf_logxref(" reuse %d %d\n", *oidp, *genp);				x->type = 'a';				x->ofs = 0;				prev = findprev(xref, oid);				next = findnext(xref, oid);				xref->table[prev].type = 'd';				xref->table[prev].ofs = next;				return fz_okay;			}		}		oid = x->ofs;		if (oid == 0)			break;	}	if (xref->len + 1 >= xref->cap)	{		int newcap = xref->cap + 256;		pdf_xrefentry *newtable;		newtable = fz_realloc(xref->table, sizeof(pdf_xrefentry) * newcap);		if (!newtable)			return fz_throw("outofmem: xref table resize");		xref->table = newtable;		xref->cap = newcap;	}	oid = xref->len ++;	xref->table[oid].type = 'a';	xref->table[oid].mark = 0;	xref->table[oid].ofs = 0;	xref->table[oid].gen = 0;	xref->table[oid].stmbuf = nil;	xref->table[oid].stmofs = 0;	xref->table[oid].obj = nil;	*oidp = oid;	*genp = 0;	pdf_logxref(" %d %d\n", *oidp, *genp);	prev = findprev(xref, oid);	next = findnext(xref, oid);	xref->table[prev].type = 'd';	xref->table[prev].ofs = next;	return fz_okay;}fz_error *pdf_deleteobject(pdf_xref *xref, int oid, int gen){	pdf_xrefentry *x;	int prev;	if (oid < 0 || oid >= xref->len)		return fz_throw("assert: object out of range (%d %d R)", oid, gen);	pdf_logxref("deleteobj %d %d\n", oid, gen);	x = xref->table + oid;	x->type = 'd';	x->ofs = findnext(xref, oid);	x->gen ++;	if (x->stmbuf)		fz_dropbuffer(x->stmbuf);	x->stmbuf = nil;	if (x->obj)		fz_dropobj(x->obj);	x->obj = nil;	prev = findprev(xref, oid);	xref->table[prev].type = 'd';	xref->table[prev].ofs = oid;	return fz_okay;}fz_error *pdf_updateobject(pdf_xref *xref, int oid, int gen, fz_obj *obj){	pdf_xrefentry *x;	if (oid < 0 || oid >= xref->len)		return fz_throw("assert: object out of range (%d %d R)", oid, gen);	pdf_logxref("updateobj %d %d (%p)\n", oid, gen, obj);	x = xref->table + oid;	if (x->obj)		fz_dropobj(x->obj);	x->obj = fz_keepobj(obj);	if (x->type == 'f' || x->type == 'd')	{		int prev = findprev(xref, oid);		int next = findnext(xref, oid);		xref->table[prev].type = 'd';		xref->table[prev].ofs = next;	}	x->type = 'a';	return fz_okay;}fz_error *pdf_updatestream(pdf_xref *xref, int oid, int gen, fz_buffer *stm){	pdf_xrefentry *x;	if (oid < 0 || oid >= xref->len)		return fz_throw("assert: object out of range (%d %d R)", oid, gen);	pdf_logxref("updatestm %d %d (%p)\n", oid, gen, stm);	x = xref->table + oid;	if (x->stmbuf)		fz_dropbuffer(x->stmbuf);	x->stmbuf = fz_keepbuffer(stm);	return fz_okay;}/* * object loading */fz_error *pdf_cacheobject(pdf_xref *xref, int oid, int gen){	char buf[65536];	/* yeowch! */	fz_error *error;	pdf_xrefentry *x;	int roid, rgen;	if (oid < 0 || oid >= xref->len)		return fz_throw("object out of range (%d %d R)", oid, gen);	x = &xref->table[oid];	if (x->obj)		return fz_okay;	if (x->type == 'f' || x->type == 'd')	{		error = fz_newnull(&x->obj);		if (error)			return fz_rethrow(error, "cannot create null for empty object slot");		return fz_okay;	}	if (x->type == 'n')	{		error = fz_seek(xref->file, x->ofs, 0);		if (error)			return fz_rethrow(error, "cannot seek to object (%d %d R) offset %d", oid, gen, x->ofs);		error = pdf_parseindobj(&x->obj, xref->file, buf, sizeof buf, &roid, &rgen, &x->stmofs);		if (error)			return fz_rethrow(error, "cannot parse object (%d %d R)", oid, gen);		if (roid != oid || rgen != gen)			return fz_throw("found object (%d %d R) instead of (%d %d R)", roid, rgen, oid, gen);		if (xref->crypt)			pdf_cryptobj(xref->crypt, x->obj, oid, gen);	}	else if (x->type == 'o')	{		if (!x->obj)		{			error = pdf_loadobjstm(xref, x->ofs, 0, buf, sizeof buf);			if (error)				return fz_rethrow(error, "cannot load object stream containing object (%d %d R)", oid, gen);		}	}	return fz_okay;}fz_error *pdf_loadobject(fz_obj **objp, pdf_xref *xref, int oid, int gen){	fz_error *error;	error = pdf_cacheobject(xref, oid, gen);	if (error)		return fz_rethrow(error, "cannot load object (%d %d R) into cache", oid, gen);	*objp = fz_keepobj(xref->table[oid].obj);	return fz_okay;}fz_error *pdf_loadindirect(fz_obj **objp, pdf_xref *xref, fz_obj *ref){	fz_error *error;	if (ref == nil)		return fz_throw("assert: dereference null indirect reference");	error = pdf_loadobject(objp, xref, fz_tonum(ref), fz_togen(ref));	if (error)		return fz_rethrow(error, "cannot load indirect object (%d %d R)", fz_tonum(ref), fz_togen(ref));	return fz_okay;}fz_error *pdf_resolve(fz_obj **objp, pdf_xref *xref){	fz_error *error;	if (fz_isindirect(*objp))	{		error = pdf_loadindirect(objp, xref, *objp);		if (error)			return fz_rethrow(error, "cannot load indirect object (%d %d R)", fz_tonum(*objp), fz_togen(*objp));		return fz_okay;	}	fz_keepobj(*objp);	return fz_okay;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -