Ejemplo n.º 1
0
static fz_error *
openfile(fz_stream **stmp, char *path, int mode, int realmode)
{
	fz_error *error;
	fz_stream *stm;

	stm = newstm(FZ_SFILE, mode);
	if (!stm)
		return fz_throw("outofmem: stream struct");

	error = fz_newbuffer(&stm->buffer, FZ_BUFSIZE);
	if (error)
	{
		fz_free(stm);
		return fz_rethrow(error, "cannot create buffer");
	}

	stm->file = open(path, realmode, 0666);
	if (stm->file < 0)
	{
		fz_dropbuffer(stm->buffer);
		fz_free(stm);
		return fz_throw("syserr: open '%s': %s", path, strerror(errno));
	}

	*stmp = stm;
	return fz_okay;
}
Ejemplo n.º 2
0
static fz_buffer *hexbuf(unsigned char *p, int n)
{
	static const char hex[16] = "0123456789abcdef";
	fz_buffer *buf;
	int x = 0;

	buf = fz_newbuffer(n * 2 + (n / 32) + 2);

	while (n--)
	{
		buf->data[buf->len++] = hex[*p >> 4];
		buf->data[buf->len++] = hex[*p & 15];
		if (++x == 32)
		{
			buf->data[buf->len++] = '\n';
			x = 0;
		}
		p++;
	}

	buf->data[buf->len++] = '>';
	buf->data[buf->len++] = '\n';

	return buf;
}
Ejemplo n.º 3
0
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;
}
fz_error fz_openrfile(fz_stream **stmp, char *path)
{
	fz_error error;
	fz_stream *stm;

	stm = newstm(FZ_SFILE);
	if (!stm)
		return fz_rethrow(-1, "out of memory: stream struct");

	error = fz_newbuffer(&stm->buffer, FZ_BUFSIZE);
	if (error)
	{
		fz_free(stm);
		return fz_rethrow(error, "cannot create buffer");
	}

	stm->file = open(path, O_BINARY | O_RDONLY, 0666);
	if (stm->file < 0)
	{
		fz_dropbuffer(stm->buffer);
		fz_free(stm);
		return fz_throw("syserr: open '%s': %s", path, strerror(errno));
	}

	*stmp = stm;
	return fz_okay;
}
Ejemplo n.º 5
0
fz_error *
fz_newpipeline(fz_filter **fp, fz_filter *head, fz_filter *tail)
{
	fz_error *error;

	FZ_NEWFILTER(fz_pipeline, p, pipeline);
	p->head = fz_keepfilter(head);
	p->tail = fz_keepfilter(tail);
	p->tailneedsin = 1;

	error = fz_newbuffer(&p->buffer, FZ_BUFSIZE);
	if (error) { fz_free(p); return error; }

	return nil;
}
fz_error fz_openrfilter(fz_stream **stmp, fz_filter *flt, fz_stream *src)
{
	fz_error error;
	fz_stream *stm;

	stm = newstm(FZ_SFILTER);
	if (!stm)
		return fz_rethrow(-1, "out of memory: stream struct");

	error = fz_newbuffer(&stm->buffer, FZ_BUFSIZE);
	if (error)
	{
		fz_free(stm);
		return fz_rethrow(error, "cannot create buffer");
	}

	stm->chain = fz_keepstream(src);
	stm->filter = fz_keepfilter(flt);

	*stmp = stm;
	return fz_okay;
}
Ejemplo n.º 7
0
static fz_error *
openfilter(fz_stream **stmp, fz_filter *flt, fz_stream *src, int mode)
{
	fz_error *error;
	fz_stream *stm;

	stm = newstm(FZ_SFILTER, mode);
	if (!stm)
		return fz_throw("outofmem: stream struct");

	error = fz_newbuffer(&stm->buffer, FZ_BUFSIZE);
	if (error)
	{
		fz_free(stm);
		return fz_rethrow(error, "cannot create buffer");
	}

	stm->chain = fz_keepstream(src);
	stm->filter = fz_keepfilter(flt);

	*stmp = stm;
	return fz_okay;
}
Ejemplo n.º 8
0
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;
}
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);
}
Ejemplo n.º 10
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;
}
Ejemplo n.º 11
0
fz_error *
pdf_loadinlineimage(pdf_image **imgp, pdf_xref *xref,
		fz_obj *rdb, fz_obj *dict, fz_stream *file)
{
	fz_error *error;
	pdf_image *img;
	fz_filter *filter;
	fz_obj *f;
	fz_obj *cs;
	fz_obj *d;
	int ismask;
	int i;

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

	pdf_logimage("load inline image %p {\n", img);

	img->super.loadtile = pdf_loadtile;
	img->super.drop = pdf_dropimage;
	img->super.n = 0;
	img->super.a = 0;
	img->super.refs = 0;
	img->indexed = nil;
	img->usecolorkey = 0;
	img->mask = nil;

	img->super.w = fz_toint(fz_dictgetsa(dict, "Width", "W"));
	img->super.h = fz_toint(fz_dictgetsa(dict, "Height", "H"));
	img->bpc = fz_toint(fz_dictgetsa(dict, "BitsPerComponent", "BPC"));
	ismask = fz_tobool(fz_dictgetsa(dict, "ImageMask", "IM"));
	d = fz_dictgetsa(dict, "Decode", "D");
	cs = fz_dictgetsa(dict, "ColorSpace", "CS");

	pdf_logimage("size %dx%d %d\n", img->super.w, img->super.h, img->bpc);

	if (ismask)
	{
		pdf_logimage("is mask\n");
		img->super.cs = nil;
		img->super.n = 0;
		img->super.a = 1;
		img->bpc = 1;
	}

	if (cs)
	{
		img->super.cs = nil;

		if (fz_isname(cs))
		{
			fz_obj *csd = fz_dictgets(rdb, "ColorSpace");
			if (csd)
			{
				fz_obj *cso = fz_dictget(csd, cs);
				img->super.cs = pdf_finditem(xref->store, PDF_KCOLORSPACE, cso);
				if (img->super.cs)
					fz_keepcolorspace(img->super.cs);
			}
		}

		if (!img->super.cs)
		{
			/* XXX danger! danger! does this resolve? */
			error = pdf_loadcolorspace(&img->super.cs, xref, cs);
			if (error)
				return error;
		}

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

		pdf_logimage("colorspace %s\n", img->super.cs->name);

		img->super.n = img->super.cs->n;
		img->super.a = 0;
	}

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

	if (img->indexed)
		img->stride = (img->super.w * img->bpc + 7) / 8;
	else
		img->stride = (img->super.w * (img->super.n + img->super.a) * img->bpc + 7) / 8;

	/* load image data */

	f = fz_dictgetsa(dict, "Filter", "F");
	if (f)
	{
		fz_stream *tempfile;

		error = pdf_buildinlinefilter(&filter, dict);
		if (error)
			return error;

		error = fz_openrfilter(&tempfile, filter, file);
		if (error)
			return error;

		i = fz_readall(&img->samples, tempfile);
		if (i < 0)
			return fz_ioerror(tempfile);

		fz_dropfilter(filter);
		fz_dropstream(tempfile);
	}
	else
	{
		error = fz_newbuffer(&img->samples, img->super.h * img->stride);
		if (error)
			return error;

		i = fz_read(file, img->samples->bp, img->super.h * img->stride);
		if (i < 0)
			return fz_ioerror(file);

		img->samples->wp += img->super.h * img->stride;
	}

	/* 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;
	}

	pdf_logimage("}\n");

	*imgp = img;
	return nil;
}