コード例 #1
0
ファイル: pdfclean.c プロジェクト: paradigm/paraPDF
static void expandstream(fz_obj *obj, int num, int gen)
{
	fz_error error;
	fz_buffer *buf, *tmp;
	fz_obj *newlen;

	error = pdf_loadstream(&buf, xref, num, gen);
	if (error)
		die(error);

	fz_dictdels(obj, "Filter");
	fz_dictdels(obj, "DecodeParms");

	if (doascii && isbinarystream(buf))
	{
		tmp = hexbuf(buf->data, buf->len);
		fz_dropbuffer(buf);
		buf = tmp;

		addhexfilter(obj);
	}

	newlen = fz_newint(buf->len);
	fz_dictputs(obj, "Length", newlen);
	fz_dropobj(newlen);

	fprintf(out, "%d %d obj\n", num, gen);
	fz_fprintobj(out, obj, !doexpand);
	fprintf(out, "stream\n");
	fwrite(buf->data, 1, buf->len, out);
	fprintf(out, "endstream\nendobj\n\n");

	fz_dropbuffer(buf);
}
コード例 #2
0
ファイル: pdf_fontfile.c プロジェクト: lgchmomo/mupdf
fz_error *
pdf_loadembeddedfont(pdf_font *font, pdf_xref *xref, fz_obj *stmref)
{
	fz_error *error;
	int fterr;
	FT_Face face;
	fz_buffer *buf;

	error = initfontlibs();
	if (error)
		return fz_rethrow(error, "cannot init font libraries");

	pdf_logfont("load embedded font\n");

	error = pdf_loadstream(&buf, xref, fz_tonum(stmref), fz_togen(stmref));
	if (error)
		return fz_rethrow(error, "cannot load font stream");

	fterr = FT_New_Memory_Face(ftlib, buf->rp, buf->wp - buf->rp, 0, &face);
	if (fterr)
	{
		fz_dropbuffer(buf);
		return fz_throw("freetype: cannot load embedded font: %s", ft_errstr(fterr));
	}

	font->ftface = face;
	font->fontdata = buf;

	return fz_okay;
}
コード例 #3
0
fz_error *
pdf_loadembeddedfont(pdf_font *font, pdf_xref *xref, fz_obj *stmref)
{
	fz_error *error;
	int fterr;
	FT_Face face;
	fz_buffer *buf;

	error = initfontlibs();
	if (error)
		return error;

	pdf_logfont("load embedded font\n");

	error = pdf_loadstream(&buf, xref, fz_tonum(stmref), fz_togen(stmref));
	if (error)
		return error;

	fterr = FT_New_Memory_Face(ftlib, buf->rp, buf->wp - buf->rp, 0, &face);

	if (fterr) {
		fz_free(buf);
		return fz_throw("freetype could not load embedded font: %s", pdf_fterrorstring(fterr));
	}

	font->ftface = face;
	font->fontdata = buf;

	return nil;
}
コード例 #4
0
ファイル: pdf_page.c プロジェクト: paradigm/paraPDF
static fz_error
pdf_loadpagecontents(fz_buffer **bufp, pdf_xref *xref, fz_obj *obj)
{
	fz_error error;

	if (fz_isarray(obj))
	{
		error = pdf_loadpagecontentsarray(bufp, xref, obj);
		if (error)
			return fz_rethrow(error, "cannot load content stream array (%d 0 R)", fz_tonum(obj));
	}
	else if (pdf_isstream(xref, fz_tonum(obj), fz_togen(obj)))
	{
		error = pdf_loadstream(bufp, xref, fz_tonum(obj), fz_togen(obj));
		if (error)
			return fz_rethrow(error, "cannot load content stream (%d 0 R)", fz_tonum(obj));
	}
	else
	{
		fz_warn("page contents missing, leaving page blank");
		*bufp = fz_newbuffer(0);
	}

	return fz_okay;
}
コード例 #5
0
ファイル: pdf_fontfile.c プロジェクト: AlaaMS/droidreader
fz_error
pdf_loadembeddedfont(pdf_fontdesc *fontdesc, pdf_xref *xref, fz_obj *stmref)
{
	fz_error error;
	fz_buffer *buf;

	pdf_logfont("load embedded font\n");

	error = pdf_loadstream(&buf, xref, fz_tonum(stmref), fz_togen(stmref));
	if (error)
		return fz_rethrow(error, "cannot load font stream (%d %d R)", fz_tonum(stmref), fz_togen(stmref));

	error = fz_newfontfrombuffer(&fontdesc->font, buf->data, buf->len, 0);
	if (error)
	{
		fz_dropbuffer(buf);
		return fz_rethrow(error, "cannot load embedded font (%d %d R)", fz_tonum(stmref), fz_togen(stmref));
	}

	/* save the buffer so we can free it later */
	fontdesc->font->ftdata = buf->data;
	fontdesc->font->ftsize = buf->len;
	fz_free(buf); /* only free the fz_buffer struct, not the contained data */

	fontdesc->isembedded = 1;

	return fz_okay;
}
コード例 #6
0
ファイル: SamplePdfTool.cpp プロジェクト: iroot/sopdf
void
cleanexpand(void)
{
	fz_error *error;
	fz_obj *stmobj;
	fz_buffer *buf;
	fz_obj *stmlen;
	int i, gen;

	for (i = 0; i < src->len; i++)
	{
		if (src->table[i].type == 'n')
		{
			gen = src->table[i].gen;

			if (pdf_isstream(src, i, gen))
			{
				error = pdf_loadobject(&stmobj, src, i, gen);
				if (error) die(error);

				error = pdf_loadstream(&buf, src, i, gen);
				if (error) die(error);

				fz_dictdels(stmobj, "Filter");
				fz_dictdels(stmobj, "DecodeParms");

				error = fz_newint(&stmlen, buf->wp - buf->rp);
				if (error) die(error);
				error = fz_dictputs(stmobj, "Length", stmlen);
				if (error) die(error);
				fz_dropobj(stmlen);

				pdf_updateobject(src, i, gen, stmobj);
				pdf_updatestream(src, i, gen, buf);

				fz_dropobj(stmobj);
			}
		}
	}
}
コード例 #7
0
ファイル: pdf_page.c プロジェクト: paradigm/paraPDF
static fz_error
pdf_loadpagecontentsarray(fz_buffer **bigbufp, pdf_xref *xref, fz_obj *list)
{
	fz_error error;
	fz_buffer *big;
	fz_buffer *one;
	int i;

	pdf_logpage("multiple content streams: %d\n", fz_arraylen(list));

	/* TODO: openstream, read, close into big buffer at once */

	big = fz_newbuffer(32 * 1024);

	for (i = 0; i < fz_arraylen(list); i++)
	{
		fz_obj *stm = fz_arrayget(list, i);
		error = pdf_loadstream(&one, xref, fz_tonum(stm), fz_togen(stm));
		if (error)
		{
			fz_dropbuffer(big);
			return fz_rethrow(error, "cannot load content stream part %d/%d (%d %d R)", i + 1, fz_arraylen(list), fz_tonum(stm), fz_togen(stm));
		}

		if (big->len + one->len + 1 > big->cap)
			fz_resizebuffer(big, big->len + one->len + 1);
		memcpy(big->data + big->len, one->data, one->len);
		big->data[big->len + one->len] = ' ';
		big->len += one->len + 1;

		fz_dropbuffer(one);
	}

	*bigbufp = big;
	return fz_okay;
}
コード例 #8
0
ファイル: pdf_font.c プロジェクト: MaChao5/pdfviewer-win32
static fz_error
loadcidfont(pdf_fontdesc **fontdescp, pdf_xref *xref, fz_obj *dict, fz_obj *encoding, fz_obj *tounicode)
{
	fz_error error;
	fz_obj *widths;
	fz_obj *descriptor;
	pdf_fontdesc *fontdesc;
	FT_Face face;
	fz_bbox bbox;
	int kind;
	char collection[256];
	char *basefont;
	int i, k, fterr;
	fz_obj *obj;
	int dw;

	/* Get font name and CID collection */

	basefont = fz_toname(fz_dictgets(dict, "BaseFont"));

	{
		fz_obj *cidinfo;
		char tmpstr[64];
		int tmplen;

		cidinfo = fz_dictgets(dict, "CIDSystemInfo");
		if (!cidinfo)
			return fz_throw("cid font is missing info");

		obj = fz_dictgets(cidinfo, "Registry");
		tmplen = MIN(sizeof tmpstr - 1, fz_tostrlen(obj));
		memcpy(tmpstr, fz_tostrbuf(obj), tmplen);
		tmpstr[tmplen] = '\0';
		fz_strlcpy(collection, tmpstr, sizeof collection);

		fz_strlcat(collection, "-", sizeof collection);

		obj = fz_dictgets(cidinfo, "Ordering");
		tmplen = MIN(sizeof tmpstr - 1, fz_tostrlen(obj));
		memcpy(tmpstr, fz_tostrbuf(obj), tmplen);
		tmpstr[tmplen] = '\0';
		fz_strlcat(collection, tmpstr, sizeof collection);
	}

	/* Load font file */

	fontdesc = pdf_newfontdesc();

	pdf_logfont("load cid font (%d %d R) ptr=%p {\n", fz_tonum(dict), fz_togen(dict), fontdesc);
	pdf_logfont("basefont %s\n", basefont);
	pdf_logfont("collection %s\n", collection);

	descriptor = fz_dictgets(dict, "FontDescriptor");
	if (descriptor)
		error = pdf_loadfontdescriptor(fontdesc, xref, descriptor, collection, basefont);
	else
		error = fz_throw("syntaxerror: missing font descriptor");
	if (error)
		goto cleanup;

	face = fontdesc->font->ftface;
	kind = ftkind(face);

	bbox.x0 = (face->bbox.xMin * 1000) / face->units_per_EM;
	bbox.y0 = (face->bbox.yMin * 1000) / face->units_per_EM;
	bbox.x1 = (face->bbox.xMax * 1000) / face->units_per_EM;
	bbox.y1 = (face->bbox.yMax * 1000) / face->units_per_EM;

	pdf_logfont("ft bbox [%d %d %d %d]\n", bbox.x0, bbox.y0, bbox.x1, bbox.y1);

	if (bbox.x0 == bbox.x1)
		fz_setfontbbox(fontdesc->font, -1000, -1000, 2000, 2000);
	else
		fz_setfontbbox(fontdesc->font, bbox.x0, bbox.y0, bbox.x1, bbox.y1);

	/* Encoding */

	error = fz_okay;
	if (fz_isname(encoding))
	{
		pdf_logfont("encoding /%s\n", fz_toname(encoding));
		if (!strcmp(fz_toname(encoding), "Identity-H"))
			fontdesc->encoding = pdf_newidentitycmap(0, 2);
		else if (!strcmp(fz_toname(encoding), "Identity-V"))
			fontdesc->encoding = pdf_newidentitycmap(1, 2);
		else
			error = pdf_loadsystemcmap(&fontdesc->encoding, fz_toname(encoding));
	}
	else if (fz_isindirect(encoding))
	{
		pdf_logfont("encoding %d %d R\n", fz_tonum(encoding), fz_togen(encoding));
		error = pdf_loadembeddedcmap(&fontdesc->encoding, xref, encoding);
	}
	else
	{
		error = fz_throw("syntaxerror: font missing encoding");
	}
	if (error)
		goto cleanup;

	pdf_setfontwmode(fontdesc, pdf_getwmode(fontdesc->encoding));
	pdf_logfont("wmode %d\n", pdf_getwmode(fontdesc->encoding));

	if (kind == TRUETYPE)
	{
		fz_obj *cidtogidmap;

		cidtogidmap = fz_dictgets(dict, "CIDToGIDMap");
		if (fz_isindirect(cidtogidmap))
		{
			fz_buffer *buf;

			pdf_logfont("cidtogidmap stream\n");

			error = pdf_loadstream(&buf, xref, fz_tonum(cidtogidmap), fz_togen(cidtogidmap));
			if (error)
				goto cleanup;

			fontdesc->ncidtogid = (buf->len) / 2;
			fontdesc->cidtogid = fz_malloc(fontdesc->ncidtogid * sizeof(unsigned short));
			for (i = 0; i < fontdesc->ncidtogid; i++)
				fontdesc->cidtogid[i] = (buf->data[i * 2] << 8) + buf->data[i * 2 + 1];

			fz_dropbuffer(buf);
		}

		/* if truetype font is external, cidtogidmap should not be identity */
		/* so we map from cid to unicode and then map that through the (3 1) */
		/* unicode cmap to get a glyph id */
		else if (fontdesc->font->ftsubstitute)
		{
			pdf_logfont("emulate ttf cidfont\n");

			fterr = FT_Select_Charmap(face, ft_encoding_unicode);
			if (fterr)
			{
				error = fz_throw("fonterror: no unicode cmap when emulating CID font: %s", ft_errorstring(fterr));
				goto cleanup;
			}

			if (!strcmp(collection, "Adobe-CNS1"))
				error = pdf_loadsystemcmap(&fontdesc->tottfcmap, "Adobe-CNS1-UCS2");
			else if (!strcmp(collection, "Adobe-GB1"))
				error = pdf_loadsystemcmap(&fontdesc->tottfcmap, "Adobe-GB1-UCS2");
			else if (!strcmp(collection, "Adobe-Japan1"))
				error = pdf_loadsystemcmap(&fontdesc->tottfcmap, "Adobe-Japan1-UCS2");
			else if (!strcmp(collection, "Adobe-Japan2"))
				error = pdf_loadsystemcmap(&fontdesc->tottfcmap, "Adobe-Japan2-UCS2");
			else if (!strcmp(collection, "Adobe-Korea1"))
				error = pdf_loadsystemcmap(&fontdesc->tottfcmap, "Adobe-Korea1-UCS2");
			else
				error = fz_okay;

			if (error)
			{
				error = fz_rethrow(error, "cannot load system cmap %s", collection);
				goto cleanup;
			}
		}
	}

	error = pdf_loadtounicode(fontdesc, xref, nil, collection, tounicode);
	if (error)
		goto cleanup;

	/* Horizontal */

	dw = 1000;
	obj = fz_dictgets(dict, "DW");
	if (obj)
		dw = fz_toint(obj);
	pdf_setdefaulthmtx(fontdesc, dw);

	widths = fz_dictgets(dict, "W");
	if (widths)
	{
		int c0, c1, w;

		for (i = 0; i < fz_arraylen(widths); )
		{
			c0 = fz_toint(fz_arrayget(widths, i));
			obj = fz_arrayget(widths, i + 1);
			if (fz_isarray(obj))
			{
				for (k = 0; k < fz_arraylen(obj); k++)
				{
					w = fz_toint(fz_arrayget(obj, k));
					pdf_addhmtx(fontdesc, c0 + k, c0 + k, w);
				}
				i += 2;
			}
			else
			{
				c1 = fz_toint(obj);
				w = fz_toint(fz_arrayget(widths, i + 2));
				pdf_addhmtx(fontdesc, c0, c1, w);
				i += 3;
			}
		}
	}

	pdf_endhmtx(fontdesc);

	/* Vertical */

	if (pdf_getwmode(fontdesc->encoding) == 1)
	{
		int dw2y = 880;
		int dw2w = -1000;

		obj = fz_dictgets(dict, "DW2");
		if (obj)
		{
			dw2y = fz_toint(fz_arrayget(obj, 0));
			dw2w = fz_toint(fz_arrayget(obj, 1));
		}

		pdf_setdefaultvmtx(fontdesc, dw2y, dw2w);

		widths = fz_dictgets(dict, "W2");
		if (widths)
		{
			int c0, c1, w, x, y;

			for (i = 0; i < fz_arraylen(widths); )
			{
				c0 = fz_toint(fz_arrayget(widths, i));
				obj = fz_arrayget(widths, i + 1);
				if (fz_isarray(obj))
				{
					for (k = 0; k < fz_arraylen(obj); k += 3)
					{
						w = fz_toint(fz_arrayget(obj, k + 0));
						x = fz_toint(fz_arrayget(obj, k + 1));
						y = fz_toint(fz_arrayget(obj, k + 2));
						pdf_addvmtx(fontdesc, c0 + k, c0 + k, x, y, w);
					}
					i += 2;
				}
				else
				{
					c1 = fz_toint(obj);
					w = fz_toint(fz_arrayget(widths, i + 2));
					x = fz_toint(fz_arrayget(widths, i + 3));
					y = fz_toint(fz_arrayget(widths, i + 4));
					pdf_addvmtx(fontdesc, c0, c1, x, y, w);
					i += 5;
				}
			}
		}

		pdf_endvmtx(fontdesc);
	}

	pdf_logfont("}\n");

	*fontdescp = fontdesc;
	return fz_okay;

cleanup:
	pdf_dropfont(fontdesc);
	return fz_rethrow(error, "cannot load cid font (%d %d R)", fz_tonum(dict), fz_togen(dict));
}
コード例 #9
0
ファイル: pdf_colorspace.c プロジェクト: fkhan/mupdf_fareed
static fz_error
loadindexed(fz_colorspace **csp, pdf_xref *xref, fz_obj *array)
{
	fz_error error;
	pdf_indexed *cs;
	fz_obj *baseobj = fz_arrayget(array, 1);
	fz_obj *highobj = fz_arrayget(array, 2);
	fz_obj *lookup = fz_arrayget(array, 3);
	fz_colorspace *base;
	int n;

	pdf_logrsrc("load Indexed {\n");

	error = pdf_loadcolorspace(&base, xref, baseobj);
	if (error)
		return fz_rethrow(error, "cannot load base colorspace");

	pdf_logrsrc("base %s\n", base->name);

	cs = fz_malloc(sizeof(pdf_indexed));

	initcs((fz_colorspace*)cs, "Indexed", 1, nil, nil, freeindexed);

	cs->base = fz_keepcolorspace(base);
	cs->high = fz_toint(highobj);

	fz_dropcolorspace(base);

	n = base->n * (cs->high + 1);
	cs->lookup = fz_malloc(n);

	if (fz_isstring(lookup) && fz_tostrlen(lookup) == n)
	{
		unsigned char *buf;
		int i;

		pdf_logrsrc("string lookup\n");

		buf = (unsigned char *) fz_tostrbuf(lookup);
		for (i = 0; i < n; i++)
			cs->lookup[i] = buf[i];
	}
	else if (fz_isindirect(lookup))
	{
		fz_buffer *buf;
		int i;

		pdf_logrsrc("stream lookup\n");

		error = pdf_loadstream(&buf, xref, fz_tonum(lookup), fz_togen(lookup));
		if (error)
		{
			fz_dropcolorspace((fz_colorspace*)cs);
			return fz_rethrow(error, "cannot load colorpsace lookup table");
		}

		for (i = 0; i < n && i < (buf->wp - buf->rp); i++)
			cs->lookup[i] = buf->rp[i];

		fz_dropbuffer(buf);
	}
	else
		return fz_throw("cannot parse colorspace lookup table");

	pdf_logrsrc("}\n");

	*csp = (fz_colorspace*)cs;
	return fz_okay;
}
コード例 #10
0
static fz_error *
loadindexed(fz_colorspace **csp, pdf_xref *xref, fz_obj *array)
{
	fz_error *error;
	pdf_indexed *cs;
	fz_obj *baseobj = fz_arrayget(array, 1);
	fz_obj *highobj = fz_arrayget(array, 2);
	fz_obj *lookup = fz_arrayget(array, 3);
	fz_colorspace *base;
	int n;

	pdf_logrsrc("load Indexed {\n");

	error = pdf_resolve(&baseobj, xref);
	if (error)
		return error;
	error = pdf_loadcolorspace(&base, xref, baseobj);
	fz_dropobj(baseobj);
	if (error)
		return error;

	pdf_logrsrc("base %s\n", base->name);

	cs = fz_malloc(sizeof(pdf_indexed));
	if (!cs)
	{
		fz_dropcolorspace(base);
		return fz_outofmem;
	}

	initcs((fz_colorspace*)cs, "Indexed", 1, nil, nil, dropindexed);

	cs->base = base;
	cs->high = fz_toint(highobj);

	n = base->n * (cs->high + 1);

	cs->lookup = fz_malloc(n);
	if (!cs->lookup)
	{
		fz_dropcolorspace((fz_colorspace*)cs);
		return fz_outofmem;
	}

	if (fz_isstring(lookup) && fz_tostrlen(lookup) == n)
	{
		unsigned char *buf;
		int i;

		pdf_logrsrc("string lookup\n");

		buf = fz_tostrbuf(lookup);
		for (i = 0; i < n; i++)
			cs->lookup[i] = buf[i];
	}

	if (fz_isindirect(lookup))
	{
		fz_buffer *buf;
		int i;

		pdf_logrsrc("stream lookup\n");

		error = pdf_loadstream(&buf, xref, fz_tonum(lookup), fz_togen(lookup));
		if (error)
		{
			fz_dropcolorspace((fz_colorspace*)cs);
			return error;
		}

		for (i = 0; i < n && i < (buf->wp - buf->rp); i++)
			cs->lookup[i] = buf->rp[i];

		fz_dropbuffer(buf);
	}

	pdf_logrsrc("}\n");

	*csp = (fz_colorspace*)cs;
	return nil;
}
コード例 #11
0
fz_error *
pdf_loadtype4shade(fz_shade *shade, pdf_xref *xref, fz_obj *shading, fz_obj *ref)
{
	fz_error *error;
	fz_obj *obj;
	int bpcoord;
	int bpcomp;
	int bpflag;
	int ncomp;
	float x0, x1, y0, y1;
	float c0[FZ_MAXCOLORS];
	float c1[FZ_MAXCOLORS];
	int i, z;
	int bitspervertex;
	int bytepervertex;
	fz_buffer *buf;
	int n;
	int j;
	float cval[16];

	int flag;
	unsigned int t;
	float x, y;

	error = nil;

	ncomp = shade->cs->n;
	bpcoord = fz_toint(fz_dictgets(shading, "BitsPerCoordinate"));
	bpcomp = fz_toint(fz_dictgets(shading, "BitsPerComponent"));
	bpflag = fz_toint(fz_dictgets(shading, "BitsPerFlag"));

	obj = fz_dictgets(shading, "Decode");
	if (fz_isarray(obj))
	{
		pdf_logshade("decode array\n");
		x0 = fz_toreal(fz_arrayget(obj, 0));
		x1 = fz_toreal(fz_arrayget(obj, 1));
		y0 = fz_toreal(fz_arrayget(obj, 2));
		y1 = fz_toreal(fz_arrayget(obj, 3));
		for (i=0; i < fz_arraylen(obj) / 2; ++i) {
			c0[i] = fz_toreal(fz_arrayget(obj, i*2+4));
			c1[i] = fz_toreal(fz_arrayget(obj, i*2+5));
		}
	}
	else {
		error = fz_throw("syntaxerror: No Decode key in Type 4 Shade");
		goto cleanup;
	}

	obj = fz_dictgets(shading, "Function");
	if (obj) {
		ncomp = 1;
		pdf_loadshadefunction(shade, xref, shading, c0[0], c1[0]);
	}

	bitspervertex = bpflag + bpcoord * 2 + bpcomp * ncomp;	
	bytepervertex = (bitspervertex+7) / 8;

	error = pdf_loadstream(&buf, xref, fz_tonum(ref), fz_togen(ref));
	if (error) goto cleanup;

	shade->usefunction = 0;


	n = 2 + shade->cs->n;
	j = 0;
	for (z = 0; z < (buf->ep - buf->bp) / bytepervertex; ++z)
	{
		flag = *buf->rp++;

		t = *buf->rp++;
		t = (t << 8) + *buf->rp++;
		t = (t << 8) + *buf->rp++;
		x = x0 + (t * (x1 - x0) / (pow(2, 24) - 1));

		t = *buf->rp++;
		t = (t << 8) + *buf->rp++;
		t = (t << 8) + *buf->rp++;
		y = y0 + (t * (y1 - y0) / (pow(2, 24) - 1));

		for (i=0; i < ncomp; ++i) {
			t = *buf->rp++;
			t = (t << 8) + *buf->rp++;
		}

		if (flag == 0) {
			j += n;
		}
		if (flag == 1 || flag == 2) {
			j += 3 * n;
		}
	}
	buf->rp = buf->bp;

	shade->mesh = (float*) malloc(sizeof(float) * j);
	/* 8, 24, 16 only */
	j = 0;
	for (z = 0; z < (buf->ep - buf->bp) / bytepervertex; ++z)
	{
		flag = *buf->rp++;

		t = *buf->rp++;
		t = (t << 8) + *buf->rp++;
		t = (t << 8) + *buf->rp++;
		x = x0 + (t * (x1 - x0) / (pow(2, 24) - 1));

		t = *buf->rp++;
		t = (t << 8) + *buf->rp++;
		t = (t << 8) + *buf->rp++;
		y = y0 + (t * (y1 - y0) / (pow(2, 24) - 1));

		for (i=0; i < ncomp; ++i) {
			t = *buf->rp++;
			t = (t << 8) + *buf->rp++;
			cval[i] = t / (double)(pow(2, 16) - 1);
		}

		if (flag == 0) {
			shade->mesh[j++] = x;
			shade->mesh[j++] = y;
			for (i=0; i < ncomp; ++i) {
				shade->mesh[j++] = cval[i];
			}
		}
		if (flag == 1) {
			memcpy(&(shade->mesh[j]), &(shade->mesh[j - 2 * n]), n * sizeof(float));
			memcpy(&(shade->mesh[j + 1 * n]), &(shade->mesh[j - 1 * n]), n * sizeof(float));
			j+= 2 * n;
			shade->mesh[j++] = x;
			shade->mesh[j++] = y;
			for (i=0; i < ncomp; ++i) {
				shade->mesh[j++] = cval[i];
			}
		}
		if (flag == 2) {
			memcpy(&(shade->mesh[j]), &(shade->mesh[j - 3 * n]), n * sizeof(float));
			memcpy(&(shade->mesh[j + 1 * n]), &(shade->mesh[j - 1 * n]), n * sizeof(float));
			j+= 2 * n;
			shade->mesh[j++] = x;
			shade->mesh[j++] = y;
			for (i=0; i < ncomp; ++i) {
				shade->mesh[j++] = cval[i];
			}
		}
	}
	shade->meshlen = j / n / 3;

	fz_dropbuffer(buf);

cleanup:

	return nil;
}
コード例 #12
0
ファイル: pdf_image.c プロジェクト: paradigm/paraPDF
static fz_error
pdf_loadjpximage(fz_pixmap **imgp, pdf_xref *xref, fz_obj *dict)
{
	fz_error error;
	fz_buffer *buf;
	fz_pixmap *img;
	fz_obj *obj;

	pdf_logimage("jpeg2000\n");

	error = pdf_loadstream(&buf, xref, fz_tonum(dict), fz_togen(dict));
	if (error)
		return fz_rethrow(error, "cannot load jpx image data");

	error = fz_loadjpximage(&img, buf->data, buf->len);
	if (error)
	{
		fz_dropbuffer(buf);
		return fz_rethrow(error, "cannot load jpx image");
	}

	fz_dropbuffer(buf);

	obj = fz_dictgetsa(dict, "SMask", "Mask");
	if (fz_isdict(obj))
	{
		error = pdf_loadimageimp(&img->mask, xref, nil, obj, nil, 1);
		if (error)
		{
			fz_droppixmap(img);
			return fz_rethrow(error, "cannot load image mask/softmask");
		}
	}

	obj = fz_dictgets(dict, "ColorSpace");
	if (obj)
	{
		fz_colorspace *original = img->colorspace;
		img->colorspace = nil;

		error = pdf_loadcolorspace(&img->colorspace, xref, obj);
		if (error)
		{
			fz_dropcolorspace(original);
			return fz_rethrow(error, "cannot load image colorspace");
		}

		if (original->n != img->colorspace->n)
		{
			fz_warn("jpeg-2000 colorspace (%s) does not match promised colorspace (%s)", original->name, img->colorspace->name);
			fz_dropcolorspace(img->colorspace);
			img->colorspace = original;
		}
		else
			fz_dropcolorspace(original);

		if (!strcmp(img->colorspace->name, "Indexed"))
		{
			fz_pixmap *conv;
			conv = pdf_expandindexedpixmap(img);
			fz_droppixmap(img);
			img = conv;
		}
	}

	*imgp = img;
	return fz_okay;
}
コード例 #13
0
ファイル: pdf_xobject.c プロジェクト: iroot/sopdf
fz_error *
pdf_loadxobject(pdf_xobject **formp, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
{
	fz_error *error;
	pdf_xobject *form;
	fz_obj *obj;

	if ((*formp = pdf_finditem(xref->store, PDF_KXOBJECT, ref)))
	{
		pdf_keepxobject(*formp);
		return fz_okay;
	}

	form = fz_malloc(sizeof(pdf_xobject));
	if (!form)
		return fz_throw("outofmem: xobject struct");

	form->refs = 1;
	form->resources = nil;
	form->contents = nil;

	/* Store item immediately, to avoid infinite recursion if contained
	   objects refer again to this xobject */
	error = pdf_storeitem(xref->store, PDF_KXOBJECT, ref, form);
	if (error)
	{
		pdf_dropxobject(form);
		return fz_rethrow(error, "cannot store xobject resource");
	}

	pdf_logrsrc("load xobject %d %d (%p) {\n", fz_tonum(ref), fz_togen(ref), form);

	obj = fz_dictgets(dict, "BBox");
	form->bbox = pdf_torect(obj);

	pdf_logrsrc("bbox [%g %g %g %g]\n",
			form->bbox.x0, form->bbox.y0,
			form->bbox.x1, form->bbox.y1);

	obj = fz_dictgets(dict, "Matrix");
	if (obj)
		form->matrix = pdf_tomatrix(obj);
	else
		form->matrix = fz_identity();

	pdf_logrsrc("matrix [%g %g %g %g %g %g]\n",
			form->matrix.a, form->matrix.b,
			form->matrix.c, form->matrix.d,
			form->matrix.e, form->matrix.f);

	obj = fz_dictgets(dict, "I");
	form->isolated = fz_tobool(obj);
	obj = fz_dictgets(dict, "K");
	form->knockout = fz_tobool(obj);

	pdf_logrsrc("isolated %d\n", form->isolated);
	pdf_logrsrc("knockout %d\n", form->knockout);

	obj = fz_dictgets(dict, "Resources");
	if (obj)
	{
		error = pdf_resolve(&obj, xref);
		if (error)
		{
			fz_dropobj(obj);
			error = fz_rethrow(error, "cannot resolve xobject resources");
			goto cleanup;
		}
		error = pdf_loadresources(&form->resources, xref, obj);
		fz_dropobj(obj);
		if (error)
		{
			error = fz_rethrow(error, "cannot load xobject resources");
			goto cleanup;
		}
	}

	error = pdf_loadstream(&form->contents, xref, fz_tonum(ref), fz_togen(ref));
	if (error)
	{
		error = fz_rethrow(error, "cannot load xobject content stream");
		goto cleanup;
	}

	pdf_logrsrc("stream %d bytes\n", form->contents->wp - form->contents->rp);

	pdf_logrsrc("}\n");

	*formp = form;
	return fz_okay;
cleanup:
	pdf_removeitem(xref->store, PDF_KXOBJECT, ref);
	pdf_dropxobject(form);
	return error;
}
コード例 #14
0
ファイル: pdf_xobject.c プロジェクト: fkhan/mupdf_fareed
fz_error
pdf_loadxobject(pdf_xobject **formp, pdf_xref *xref, fz_obj *dict)
{
	fz_error error;
	pdf_xobject *form;
	fz_obj *obj;

	if ((*formp = pdf_finditem(xref->store, PDF_KXOBJECT, dict)))
	{
		pdf_keepxobject(*formp);
		return fz_okay;
	}

	form = fz_malloc(sizeof(pdf_xobject));
	form->refs = 1;
	form->resources = nil;
	form->contents = nil;

	/* Store item immediately, to avoid possible recursion if objects refer back to this one */
	pdf_storeitem(xref->store, PDF_KXOBJECT, dict, form);

	pdf_logrsrc("load xobject (%d %d R) ptr=%p {\n", fz_tonum(dict), fz_togen(dict), form);

	obj = fz_dictgets(dict, "BBox");
	form->bbox = pdf_torect(obj);

	pdf_logrsrc("bbox [%g %g %g %g]\n",
		form->bbox.x0, form->bbox.y0,
		form->bbox.x1, form->bbox.y1);

	obj = fz_dictgets(dict, "Matrix");
	if (obj)
		form->matrix = pdf_tomatrix(obj);
	else
		form->matrix = fz_identity();

	pdf_logrsrc("matrix [%g %g %g %g %g %g]\n",
		form->matrix.a, form->matrix.b,
		form->matrix.c, form->matrix.d,
		form->matrix.e, form->matrix.f);

	form->isolated = 0;
	form->knockout = 0;
	form->transparency = 0;

	obj = fz_dictgets(dict, "Group");
	if (obj)
	{
		fz_obj *attrs = obj;

		form->isolated = fz_tobool(fz_dictgets(attrs, "I"));
		form->knockout = fz_tobool(fz_dictgets(attrs, "K"));

		obj = fz_dictgets(attrs, "S");
		if (fz_isname(obj) && !strcmp(fz_toname(obj), "Transparency"))
			form->transparency = 1;
	}

	pdf_logrsrc("isolated %d\n", form->isolated);
	pdf_logrsrc("knockout %d\n", form->knockout);
	pdf_logrsrc("transparency %d\n", form->transparency);

	form->resources = fz_dictgets(dict, "Resources");
	if (form->resources)
		fz_keepobj(form->resources);

	error = pdf_loadstream(&form->contents, xref, fz_tonum(dict), fz_togen(dict));
	if (error)
	{
		pdf_removeitem(xref->store, PDF_KXOBJECT, dict);
		pdf_dropxobject(form);
		return fz_rethrow(error, "cannot load xobject content stream (%d %d R)", fz_tonum(dict), fz_togen(dict));
	}

	pdf_logrsrc("stream %d bytes\n", form->contents->wp - form->contents->rp);
	pdf_logrsrc("}\n");

	*formp = form;
	return fz_okay;
}
コード例 #15
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;
}
コード例 #16
0
ファイル: pdf_pattern.c プロジェクト: MaChao5/pdfviewer-win32
fz_error
pdf_loadpattern(pdf_pattern **patp, pdf_xref *xref, fz_obj *dict)
{
	fz_error error;
	pdf_pattern *pat;
	fz_obj *obj;

	if ((*patp = pdf_finditem(xref->store, pdf_droppattern, dict)))
	{
		pdf_keeppattern(*patp);
		return fz_okay;
	}

	pdf_logrsrc("load pattern (%d %d R) {\n", fz_tonum(dict), fz_togen(dict));

	pat = fz_malloc(sizeof(pdf_pattern));
	pat->refs = 1;
	pat->resources = nil;
	pat->contents = nil;

	/* Store pattern now, to avoid possible recursion if objects refer back to this one */
	pdf_storeitem(xref->store, pdf_keeppattern, pdf_droppattern, dict, pat);

	pat->ismask = fz_toint(fz_dictgets(dict, "PaintType")) == 2;
	pat->xstep = fz_toreal(fz_dictgets(dict, "XStep"));
	pat->ystep = fz_toreal(fz_dictgets(dict, "YStep"));

	pdf_logrsrc("mask %d\n", pat->ismask);
	pdf_logrsrc("xstep %g\n", pat->xstep);
	pdf_logrsrc("ystep %g\n", pat->ystep);

	obj = fz_dictgets(dict, "BBox");
	pat->bbox = pdf_torect(obj);

	pdf_logrsrc("bbox [%g %g %g %g]\n",
		pat->bbox.x0, pat->bbox.y0,
		pat->bbox.x1, pat->bbox.y1);

	obj = fz_dictgets(dict, "Matrix");
	if (obj)
		pat->matrix = pdf_tomatrix(obj);
	else
		pat->matrix = fz_identity;

	pdf_logrsrc("matrix [%g %g %g %g %g %g]\n",
		pat->matrix.a, pat->matrix.b,
		pat->matrix.c, pat->matrix.d,
		pat->matrix.e, pat->matrix.f);

	pat->resources = fz_dictgets(dict, "Resources");
	if (pat->resources)
		fz_keepobj(pat->resources);

	error = pdf_loadstream(&pat->contents, xref, fz_tonum(dict), fz_togen(dict));
	if (error)
	{
		pdf_removeitem(xref->store, pdf_droppattern, dict);
		pdf_droppattern(pat);
		return fz_rethrow(error, "cannot load pattern stream (%d %d R)", fz_tonum(dict), fz_togen(dict));
	}

	pdf_logrsrc("}\n");

	*patp = pat;
	return fz_okay;
}
コード例 #17
0
static void savefont(fz_obj *dict, int num, int gen)
{
    fz_error error;
    char name[1024];
    char *subtype;
    fz_buffer *buf;
    fz_obj *stream = nil;
    fz_obj *obj;
    char *ext = "";
    FILE *f;
    unsigned char *p;
    char *fontname = "font";

    obj = fz_dictgets(dict, "FontName");
    if (obj)
        fontname = fz_toname(obj);

    obj = fz_dictgets(dict, "FontFile");
    if (obj)
    {
        stream = obj;
        ext = "pfa";
    }

    obj = fz_dictgets(dict, "FontFile2");
    if (obj)
    {
        stream = obj;
        ext = "ttf";
    }

    obj = fz_dictgets(dict, "FontFile3");
    if (obj)
    {
        stream = obj;

        obj = fz_dictgets(obj, "Subtype");
        if (obj && !fz_isname(obj))
            die(fz_throw("Invalid font descriptor subtype"));

        subtype = fz_toname(obj);
        if (!strcmp(subtype, "Type1C"))
            ext = "cff";
        else if (!strcmp(subtype, "CIDFontType0C"))
            ext = "cid";
        else
            die(fz_throw("Unhandled font type '%s'", subtype));
    }

    if (!stream)
    {
        fz_warn("Unhandled font type");
        return;
    }

    error = fz_newbuffer(&buf, 0);
    if (error)
        die(error);

    error = pdf_loadstream(&buf, xref, fz_tonum(stream), fz_togen(stream));
    if (error)
        die(error);

    sprintf(name, "%s-%04d.%s", fontname, num, ext);

    f = fopen(name, "wb");
    if (f == NULL)
        die(fz_throw("Error creating image file"));

    for (p = buf->rp; p < buf->wp; p ++)
        fprintf(f, "%c", *p);

    if (fclose(f) < 0)
        die(fz_throw("Error closing image file"));

    fz_dropbuffer(buf);
}
コード例 #18
0
fz_error
pdf_loadtype3font(pdf_fontdesc **fontdescp, pdf_xref *xref, fz_obj *rdb, fz_obj *dict)
{
	fz_error error;
	char buf[256];
	char *estrings[256];
	pdf_fontdesc *fontdesc;
	fz_obj *encoding;
	fz_obj *widths;
	fz_obj *charprocs;
	fz_obj *obj;
	int first, last;
	int i, k, n;
	fz_rect bbox;
	fz_matrix matrix;

	obj = fz_dictgets(dict, "Name");
	if (fz_isname(obj))
		fz_strlcpy(buf, fz_toname(obj), sizeof buf);
	else
		sprintf(buf, "Unnamed-T3");

	fontdesc = pdf_newfontdesc();

	pdf_logfont("load type3 font (%d %d R) ptr=%p {\n", fz_tonum(dict), fz_togen(dict), fontdesc);
	pdf_logfont("name %s\n", buf);

	obj = fz_dictgets(dict, "FontMatrix");
	matrix = pdf_tomatrix(obj);

	pdf_logfont("matrix [%g %g %g %g %g %g]\n",
		matrix.a, matrix.b,
		matrix.c, matrix.d,
		matrix.e, matrix.f);

	obj = fz_dictgets(dict, "FontBBox");
	bbox = pdf_torect(obj);

	pdf_logfont("bbox [%g %g %g %g]\n",
		bbox.x0, bbox.y0,
		bbox.x1, bbox.y1);

	fontdesc->font = fz_newtype3font(buf, matrix);

	fz_setfontbbox(fontdesc->font, bbox.x0, bbox.y0, bbox.x1, bbox.y1);

	/* Encoding */

	for (i = 0; i < 256; i++)
		estrings[i] = nil;

	encoding = fz_dictgets(dict, "Encoding");
	if (!encoding)
	{
		error = fz_throw("syntaxerror: Type3 font missing Encoding");
		goto cleanup;
	}

	if (fz_isname(encoding))
		pdf_loadencoding(estrings, fz_toname(encoding));

	if (fz_isdict(encoding))
	{
		fz_obj *base, *diff, *item;

		base = fz_dictgets(encoding, "BaseEncoding");
		if (fz_isname(base))
			pdf_loadencoding(estrings, fz_toname(base));

		diff = fz_dictgets(encoding, "Differences");
		if (fz_isarray(diff))
		{
			n = fz_arraylen(diff);
			k = 0;
			for (i = 0; i < n; i++)
			{
				item = fz_arrayget(diff, i);
				if (fz_isint(item))
					k = fz_toint(item);
				if (fz_isname(item))
					estrings[k++] = fz_toname(item);
				if (k < 0) k = 0;
				if (k > 255) k = 255;
			}
		}
	}

	fontdesc->encoding = pdf_newidentitycmap(0, 1);

	error = pdf_loadtounicode(fontdesc, xref, estrings, nil, fz_dictgets(dict, "ToUnicode"));
	if (error)
		goto cleanup;

	/* Widths */

	pdf_setdefaulthmtx(fontdesc, 0);

	first = fz_toint(fz_dictgets(dict, "FirstChar"));
	last = fz_toint(fz_dictgets(dict, "LastChar"));

	widths = fz_dictgets(dict, "Widths");
	if (!widths)
	{
		error = fz_throw("syntaxerror: Type3 font missing Widths");
		goto cleanup;
	}

	for (i = first; i <= last; i++)
	{
		float w = fz_toreal(fz_arrayget(widths, i - first));
		w = fontdesc->font->t3matrix.a * w * 1000;
		fontdesc->font->t3widths[i] = w * 0.001f;
		pdf_addhmtx(fontdesc, i, i, w);
	}

	pdf_endhmtx(fontdesc);

	/* Resources -- inherit page resources if the font doesn't have its own */

	fontdesc->font->t3resources = fz_dictgets(dict, "Resources");
	if (!fontdesc->font->t3resources)
		fontdesc->font->t3resources = rdb;
	if (fontdesc->font->t3resources)
		fz_keepobj(fontdesc->font->t3resources);
	if (!fontdesc->font->t3resources)
		fz_warn("no resource dictionary for type 3 font!");

	fontdesc->font->t3xref = xref;
	fontdesc->font->t3run = pdf_runcontents;

	/* CharProcs */

	charprocs = fz_dictgets(dict, "CharProcs");
	if (!charprocs)
	{
		error = fz_throw("syntaxerror: Type3 font missing CharProcs");
		goto cleanup;
	}

	for (i = 0; i < 256; i++)
	{
		if (estrings[i])
		{
			obj = fz_dictgets(charprocs, estrings[i]);
			if (pdf_isstream(xref, fz_tonum(obj), fz_togen(obj)))
			{
				error = pdf_loadstream(&fontdesc->font->t3procs[i], xref, fz_tonum(obj), fz_togen(obj));
				if (error)
					goto cleanup;
			}
		}
	}

	pdf_logfont("}\n");

	*fontdescp = fontdesc;
	return fz_okay;

cleanup:
	fz_dropfont(fontdesc->font);
	fz_free(fontdesc);
	return fz_rethrow(error, "cannot load type3 font (%d %d R)", fz_tonum(dict), fz_togen(dict));
}