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

📄 pdf_doctor.c.svn-base

📁 SumatraPDF是一款小型开源的pdf阅读工具。虽然玲珑小巧(只有800多KB)
💻 SVN-BASE
字号:
#include "fitz.h"#include "mupdf.h"/* * Sweep and mark reachable objects * * Don't bother chaining errors for this deep recursion */static fz_error *sweepref(pdf_xref *xref, fz_obj *ref);static fz_error *sweepobj(pdf_xref *xref, fz_obj *obj){	fz_error *error;	int i;	if (fz_isdict(obj))	{		for (i = 0; i < fz_dictlen(obj); i++)		{			error = sweepobj(xref, fz_dictgetval(obj, i));			if (error)				return error; /* too deeply nested for rethrow */		}	}	if (fz_isarray(obj))	{		for (i = 0; i < fz_arraylen(obj); i++)		{			error = sweepobj(xref, fz_arrayget(obj, i));			if (error)				return error; /* too deeply nested for rethrow */		}	}	if (fz_isindirect(obj))		return sweepref(xref, obj);	return fz_okay;}static fz_error *sweepref(pdf_xref *xref, fz_obj *ref){	fz_error *error;	fz_obj *obj;	int oid, gid;	oid = fz_tonum(ref);	gid = fz_tonum(ref);	if (oid < 0 || oid >= xref->len)		return fz_throw("object out of range (%d %d R)", oid, gid);	if (xref->table[oid].mark)		return fz_okay;	xref->table[oid].mark = 1;	error = pdf_loadindirect(&obj, xref, ref);	if (error)		return fz_rethrow(error, "cannot load indirect object");	error = sweepobj(xref, obj);	if (error)	{		fz_dropobj(obj);		return error; /* too deeply nested for rethrow */	}	fz_dropobj(obj);	return fz_okay;}/* * Garbage collect objects not reachable from * the trailer dictionary */fz_error *pdf_garbagecollect(pdf_xref *xref){	fz_error *error;	int i, g;	pdf_logxref("garbage collect {\n");	for (i = 0; i < xref->len; i++)		xref->table[i].mark = 0;	error = sweepobj(xref, xref->trailer);	if (error)		return fz_rethrow(error, "cannot mark used objects");	for (i = 0; i < xref->len; i++)	{		pdf_xrefentry *x = xref->table + i;		g = x->gen;		if (x->type == 'o')			g = 0;		if (!x->mark && x->type != 'f' && x->type != 'd')		{			error = pdf_deleteobject(xref, i, g);			if (error)				return fz_rethrow(error, "cannot delete unmarked object %d", i);		}	}	pdf_logxref("}\n");	return fz_okay;}/* * Transplant (copy) objects and streams from one file to another */struct pair{	int soid, sgen;	int doid, dgen;};static fz_error *remaprefs(fz_obj **newp, fz_obj *old, struct pair *map, int n){	fz_error *error;	int i, o, g;	fz_obj *tmp, *key;	if (fz_isindirect(old))	{		o = fz_tonum(old);		g = fz_togen(old);		for (i = 0; i < n; i++)			if (map[i].soid == o && map[i].sgen == g)			{				error = fz_newindirect(newp, map[i].doid, map[i].dgen);				if (error)					return fz_rethrow(error, "cannot remap indirect reference");			}	}	else if (fz_isarray(old))	{		error = fz_newarray(newp, fz_arraylen(old));		if (error)			return fz_rethrow(error, "cannot remap array");		for (i = 0; i < fz_arraylen(old); i++)		{			tmp = fz_arrayget(old, i);			error = remaprefs(&tmp, tmp, map, n);			if (error)				goto cleanup;			error = fz_arraypush(*newp, tmp);			fz_dropobj(tmp);			if (error)				goto cleanup;		}	}	else if (fz_isdict(old))	{		error = fz_newdict(newp, fz_dictlen(old));		if (error)			return fz_rethrow(error, "cannot remap dictionary");		for (i = 0; i < fz_dictlen(old); i++)		{			key = fz_dictgetkey(old, i);			tmp = fz_dictgetval(old, i);			error = remaprefs(&tmp, tmp, map, n);			if (error)				goto cleanup;			error = fz_dictput(*newp, key, tmp);			fz_dropobj(tmp);			if (error)				goto cleanup;		}	}	else	{		*newp = fz_keepobj(old);	}	return fz_okay;cleanup:	fz_dropobj(*newp);	return fz_rethrow(error, "cannot remap object");}/* * Recursively copy objects from src to dst xref. * Start with root object in src xref. * Put the dst copy of root into newp. */fz_error *pdf_transplant(pdf_xref *dst, pdf_xref *src, fz_obj **newp, fz_obj *root){	fz_error *error;	struct pair *map;	fz_obj *old, *new;	fz_buffer *stm;	int i, n;	pdf_logxref("transplant {\n");	for (i = 0; i < src->len; i++)		src->table[i].mark = 0;	error = sweepobj(src, root);	if (error)		return fz_rethrow(error, "cannot mark used objects");	for (n = 0, i = 0; i < src->len; i++)			if (src->table[i].mark)			n++;	pdf_logxref("marked %d\n", n);	map = fz_malloc(sizeof(struct pair) * n);	if (!map)		return fz_throw("outofmem: remapping table");	for (n = 0, i = 0; i < src->len; i++)		{		if (src->table[i].mark)		{			map[n].soid = i;			map[n].sgen = src->table[i].gen;			if (src->table[i].type == 'o')				map[n].sgen = 0;			error = pdf_allocobject(dst, &map[n].doid, &map[n].dgen);			if (error)				goto cleanup;			n++;		}	}	error = remaprefs(newp, root, map, n);	if (error)		goto cleanup;	for (i = 0; i < n; i++)		{		pdf_logxref("copyfrom %d %d to %d %d\n",				map[i].soid, map[i].sgen,				map[i].doid, map[i].dgen);		error = pdf_loadobject(&old, src, map[i].soid, map[i].sgen);		if (error)			goto cleanup;		if (pdf_isstream(src, map[i].soid, map[i].sgen))		{			error = pdf_loadrawstream(&stm, src, map[i].soid, map[i].sgen);			if (error)				goto cleanup;			pdf_updatestream(dst, map[i].doid, map[i].dgen, stm);			fz_dropbuffer(stm);		}		error = remaprefs(&new, old, map, n);		fz_dropobj(old);		if (error)			goto cleanup;		error = pdf_updateobject(dst, map[i].doid, map[i].dgen, new);		fz_dropobj(new);		if (error)			goto cleanup;	}	pdf_logxref("}\n");	fz_free(map);	return fz_okay;cleanup:	fz_free(map);	return fz_rethrow(error, "cannot transplant objects");}

⌨️ 快捷键说明

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