Beispiel #1
0
void
fz_output_pwg_file_header(fz_context *ctx, fz_output *out)
{
	static const unsigned char pwgsig[4] = { 'R', 'a', 'S', '2' };

	/* Sync word */
	fz_write(ctx, out, pwgsig, 4);
}
Beispiel #2
0
static void
ps_write_band(fz_context *ctx, fz_band_writer *writer_, int stride, int band_start, int band_height, const unsigned char *samples)
{
	ps_band_writer *writer = (ps_band_writer *)writer_;
	fz_output *out = writer->super.out;
	int w = writer->super.w;
	int h = writer->super.h;
	int n = writer->super.n;
	int x, y, i, err;
	int required_input;
	int required_output;
	unsigned char *o;

	if (band_start+band_height >= h)
		band_height = h - band_start;

	required_input = w*(n-1)*band_height;
	required_output = (int)deflateBound(&writer->stream, required_input);

	if (writer->input == NULL || writer->input_size < required_input)
	{
		fz_free(ctx, writer->input);
		writer->input = NULL;
		writer->input = fz_malloc(ctx, required_input);
		writer->input_size = required_input;
	}

	if (writer->output == NULL || writer->output_size < required_output)
	{
		fz_free(ctx, writer->output);
		writer->output = NULL;
		writer->output = fz_malloc(ctx, required_output);
		writer->output_size = required_output;
	}

	o = writer->input;
	for (y = 0; y < band_height; y++)
	{
		for (x = 0; x < w; x++)
		{
			for (i = n-1; i > 0; i--)
				*o++ = *samples++;
			samples++;
		}
		samples += stride - w*n;
	}

	writer->stream.next_in = (Bytef*)writer->input;
	writer->stream.avail_in = required_input;
	writer->stream.next_out = (Bytef*)writer->output;
	writer->stream.avail_out = (uInt)writer->output_size;

	err = deflate(&writer->stream, Z_NO_FLUSH);
	if (err != Z_OK)
		fz_throw(ctx, FZ_ERROR_GENERIC, "compression error %d", err);

	fz_write(ctx, out, writer->output, writer->output_size - writer->stream.avail_out);
}
Beispiel #3
0
void
fz_save_buffer(fz_context *ctx, fz_buffer *buf, const char *filename)
{
	fz_output *out = fz_new_output_with_path(ctx, filename, 0);
	fz_try(ctx)
		fz_write(ctx, out, buf->data, buf->len);
	fz_always(ctx)
		fz_drop_output(ctx, out);
	fz_catch(ctx)
		fz_rethrow(ctx);
}
Beispiel #4
0
void fz_write_ps_band(fz_context *ctx, fz_output *out, fz_ps_output_context *psoc, int w, int h, int n, int stride, int band, int bandheight, unsigned char *samples)
{
	int x, y, i, err;
	int required_input;
	int required_output;
	unsigned char *o;

	band *= bandheight;
	if (band+bandheight >= h)
		bandheight = h - band;

	required_input = w*(n-1)*bandheight;
	required_output = (int)deflateBound(&psoc->stream, required_input);

	if (psoc->input == NULL || psoc->input_size < required_input)
	{
		fz_free(ctx, psoc->input);
		psoc->input = NULL;
		psoc->input = fz_malloc(ctx, required_input);
		psoc->input_size = required_input;
	}

	if (psoc->output == NULL || psoc->output_size < required_output)
	{
		fz_free(ctx, psoc->output);
		psoc->output = NULL;
		psoc->output = fz_malloc(ctx, required_output);
		psoc->output_size = required_output;
	}

	o = psoc->input;
	for (y = 0; y < bandheight; y++)
	{
		for (x = 0; x < w; x++)
		{
			for (i = n-1; i > 0; i--)
				*o++ = *samples++;
			samples++;
		}
		samples += stride - w*n;
	}

	psoc->stream.next_in = (Bytef*)psoc->input;
	psoc->stream.avail_in = required_input;
	psoc->stream.next_out = (Bytef*)psoc->output;
	psoc->stream.avail_out = (uInt)psoc->output_size;

	err = deflate(&psoc->stream, Z_NO_FLUSH);
	if (err != Z_OK)
		fz_throw(ctx, FZ_ERROR_GENERIC, "compression error %d", err);

	fz_write(ctx, out, psoc->output, psoc->output_size - psoc->stream.avail_out);
}
Beispiel #5
0
static fz_output *
end_def(fz_context *ctx, svg_device *sdev)
{
	if (sdev->def_count > 0)
		sdev->def_count--;
	if (sdev->def_count == 1)
		sdev->out = sdev->out_store;
	if (sdev->def_count == 0 && sdev->defs_buffer != NULL)
	{
		fz_write(ctx, sdev->out, sdev->defs_buffer->data, sdev->defs_buffer->len);
		sdev->defs_buffer->len = 0;
	}
	return sdev->out;
}
Beispiel #6
0
static void
ps_write_trailer(fz_context *ctx, fz_band_writer *writer_)
{
	ps_band_writer *writer = (ps_band_writer *)writer_;
	fz_output *out = writer->super.out;
	int err;

	writer->stream.next_in = NULL;
	writer->stream.avail_in = 0;
	writer->stream.next_out = (Bytef*)writer->output;
	writer->stream.avail_out = (uInt)writer->output_size;

	err = deflate(&writer->stream, Z_FINISH);
	if (err != Z_STREAM_END)
		fz_throw(ctx, FZ_ERROR_GENERIC, "compression error %d", err);

	fz_write(ctx, out, writer->output, writer->output_size - writer->stream.avail_out);
	fz_printf(ctx, out, "\nshowpage\n%%%%PageTrailer\n%%%%EndPageTrailer\n\n");
}
Beispiel #7
0
void
fz_write_pam_band(fz_context *ctx, fz_output *out, int w, int h, int n, int alpha, int stride, int band_start, int bandheight, unsigned char *sp)
{
	int y;
	int end = band_start + bandheight;

	if (!out)
		return;

	n += alpha;
	if (end > h)
		end = h;
	end -= band_start;

	for (y = 0; y < end; y++)
	{
		fz_write(ctx, out, sp, w * n);
		sp += stride;
	}
}
Beispiel #8
0
void fz_write_ps_trailer(fz_context *ctx, fz_output *out, fz_ps_output_context *psoc)
{
	if (psoc)
	{
		int err;

		psoc->stream.next_in = NULL;
		psoc->stream.avail_in = 0;
		psoc->stream.next_out = (Bytef*)psoc->output;
		psoc->stream.avail_out = (uInt)psoc->output_size;

		err = deflate(&psoc->stream, Z_FINISH);
		if (err != Z_STREAM_END)
			fz_throw(ctx, FZ_ERROR_GENERIC, "compression error %d", err);

		fz_write(ctx, out, psoc->output, psoc->output_size - psoc->stream.avail_out);
		fz_free(ctx, psoc->input);
		fz_free(ctx, psoc->output);
		fz_free(ctx, psoc);
	}
	fz_printf(ctx, out, "\nshowpage\n%%%%PageTrailer\n%%%%EndPageTrailer\n\n");

}
Beispiel #9
0
void
fz_output_pcl(fz_output *out, const fz_pixmap *pixmap, fz_pcl_options *pcl)
{
    //unsigned char *sp;
    //int y, x, sn, dn, ss;
    fz_context *ctx;

    if (!out || !pixmap)
        return;

    ctx = out->ctx;

    if (pixmap->n != 1 && pixmap->n != 2 && pixmap->n != 4)
        fz_throw(ctx, FZ_ERROR_GENERIC, "pixmap must be grayscale or rgb to write as pcl");

    pcl_header(out, pcl, 1, pixmap->xres);

#if 0
    sn = pixmap->n;
    dn = pixmap->n;
    if (dn == 2 || dn == 4)
        dn--;

    /* Now output the actual bitmap, using a packbits like compression */
    sp = pixmap->samples;
    ss = pixmap->w * sn;
    y = 0;
    while (y < pixmap->h)
    {
        int yrep;

        assert(sp == pixmap->samples + y * ss);

        /* Count the number of times this line is repeated */
        for (yrep = 1; yrep < 256 && y+yrep < pixmap->h; yrep++)
        {
            if (memcmp(sp, sp + yrep * ss, ss) != 0)
                break;
        }
        fz_write_byte(out, yrep-1);

        /* Encode the line */
        x = 0;
        while (x < pixmap->w)
        {
            int d;

            assert(sp == pixmap->samples + y * ss + x * sn);

            /* How far do we have to look to find a repeated value? */
            for (d = 1; d < 128 && x+d < pixmap->w; d++)
            {
                if (memcmp(sp + (d-1)*sn, sp + d*sn, sn) == 0)
                    break;
            }
            if (d == 1)
            {
                int xrep;

                /* We immediately have a repeat (or we've hit
                 * the end of the line). Count the number of
                 * times this value is repeated. */
                for (xrep = 1; xrep < 128 && x+xrep < pixmap->w; xrep++)
                {
                    if (memcmp(sp, sp + xrep*sn, sn) != 0)
                        break;
                }
                fz_write_byte(out, xrep-1);
                fz_write(out, sp, dn);
                sp += sn*xrep;
                x += xrep;
            }
            else
            {
                fz_write_byte(out, 257-d);
                x += d;
                while (d > 0)
                {
                    fz_write(out, sp, dn);
                    sp += sn;
                    d--;
                }
            }
        }

        /* Move to the next line */
        sp += ss*(yrep-1);
        y += yrep;
    }
#endif
}
Beispiel #10
0
void
fz_write_pnm_band(fz_context *ctx, fz_output *out, int w, int h, int n, int alpha, int stride, int band_start, int bandheight, unsigned char *p)
{
	char buffer[2*3*4*5*6]; /* Buffer must be a multiple of 2 and 3 at least. */
	int len;
	int end = band_start + bandheight;

	if (n-alpha != 1 && n-alpha != 3)
		fz_throw(ctx, FZ_ERROR_GENERIC, "pixmap must be grayscale or rgb to write as pnm");

	if (!out)
		return;

	if (end > h)
		end = h;
	end -= band_start;

	/* Tests show that writing single bytes out at a time
	 * is appallingly slow. We get a huge improvement
	 * by collating stuff into buffers first. */

	while (end--)
	{
		len = w;
		while (len)
		{
			int num_written = len;

			switch (n)
			{
			case 1:
				/* No collation required */
				fz_write(ctx, out, p, num_written);
				p += num_written;
				break;
			case 2:
			{
				char *o = buffer;
				int count;

				if (num_written > sizeof(buffer))
					num_written = sizeof(buffer);

				for (count = num_written; count; count--)
				{
					*o++ = *p;
					p += 2;
				}
				fz_write(ctx, out, buffer, num_written);
				break;
			}
			case 3:
			case 4:
			{
				char *o = buffer;
				int count;

				if (num_written > sizeof(buffer)/3)
					num_written = sizeof(buffer)/3;

				for (count = num_written; count; count--)
				{
					*o++ = p[0];
					*o++ = p[1];
					*o++ = p[2];
					p += n;
				}
				fz_write(ctx, out, buffer, num_written * 3);
				break;
			}
			}
			len -= num_written;
		}
		p += stride - w*n;
	}
}
Beispiel #11
0
static void
pdf_out_BI(fz_context *ctx, pdf_processor *proc, fz_image *img)
{
	fz_output *out = ((pdf_output_processor*)proc)->out;
	fz_compressed_buffer *cbuf;
	fz_buffer *buf;
	int i;

	if (img == NULL)
		return;
	cbuf = img->buffer;
	if (cbuf == NULL)
		return;
	buf = cbuf->buffer;
	if (buf == NULL)
		return;

	fz_printf(ctx, out, "BI\n");
	fz_printf(ctx, out, "/W %d\n", img->w);
	fz_printf(ctx, out, "/H %d\n", img->h);
	fz_printf(ctx, out, "/BPC %d\n", img->bpc);
	if (img->imagemask)
		fz_printf(ctx, out, "/IM true\n");
	else if (img->colorspace == fz_device_gray(ctx))
		fz_printf(ctx, out, "/CS/G\n");
	else if (img->colorspace == fz_device_rgb(ctx))
		fz_printf(ctx, out, "/CS/RGB\n");
	else if (img->colorspace == fz_device_cmyk(ctx))
		fz_printf(ctx, out, "/CS/CMYK\n");
	else if (fz_colorspace_is_indexed(ctx, img->colorspace))
		fz_printf(ctx, out, "/CS/I\n");
	if (img->interpolate)
		fz_printf(ctx, out, "/I true\n");
	fz_printf(ctx, out, "/D[");
	for (i = 0; i < img->n * 2; ++i)
	{
		if (i > 0)
			fz_putc(ctx, out, ' ');
		fz_printf(ctx, out, "%g", img->decode[i]);
	}
	fz_printf(ctx, out, "]\n");

	switch (cbuf->params.type)
	{
	default:
		fz_throw(ctx, FZ_ERROR_GENERIC, "unknown compressed buffer type");
		break;

	case FZ_IMAGE_JPEG:
		fz_printf(ctx, out, "/F/DCT\n");
		if (cbuf->params.u.jpeg.color_transform != -1)
			fz_printf(ctx, out, "/DP<</ColorTransform %d>>\n",
				cbuf->params.u.jpeg.color_transform);
		break;

	case FZ_IMAGE_FAX:
		fz_printf(ctx, out, "/F/CCF\n");
		fz_printf(ctx, out, "/DP<<\n");
		fz_printf(ctx, out, "/K %d\n", cbuf->params.u.fax.k);
		if (cbuf->params.u.fax.columns != 1728)
			fz_printf(ctx, out, "/Columns %d\n", cbuf->params.u.fax.columns);
		if (cbuf->params.u.fax.rows > 0)
			fz_printf(ctx, out, "/Rows %d\n", cbuf->params.u.fax.rows);
		if (cbuf->params.u.fax.end_of_line)
			fz_printf(ctx, out, "/EndOfLine true\n");
		if (cbuf->params.u.fax.encoded_byte_align)
			fz_printf(ctx, out, "/EncodedByteAlign true\n");
		if (!cbuf->params.u.fax.end_of_block)
			fz_printf(ctx, out, "/EndOfBlock false\n");
		if (cbuf->params.u.fax.black_is_1)
			fz_printf(ctx, out, "/BlackIs1 true\n");
		if (cbuf->params.u.fax.damaged_rows_before_error > 0)
			fz_printf(ctx, out, "/DamagedRowsBeforeError %d\n",
				cbuf->params.u.fax.damaged_rows_before_error);
		fz_printf(ctx, out, ">>\n");
		break;

	case FZ_IMAGE_RAW:
		break;

	case FZ_IMAGE_RLD:
		fz_printf(ctx, out, "/F/RL\n");
		break;

	case FZ_IMAGE_FLATE:
		fz_printf(ctx, out, "/F/Fl\n");
		if (cbuf->params.u.flate.predictor > 1)
		{
			fz_printf(ctx, out, "/DP<<\n");
			fz_printf(ctx, out, "/Predictor %d\n", cbuf->params.u.flate.predictor);
			if (cbuf->params.u.flate.columns != 1)
				fz_printf(ctx, out, "/Columns %d\n", cbuf->params.u.flate.columns);
			if (cbuf->params.u.flate.colors != 1)
				fz_printf(ctx, out, "/Colors %d\n", cbuf->params.u.flate.colors);
			if (cbuf->params.u.flate.bpc != 8)
				fz_printf(ctx, out, "/BitsPerComponent %d\n", cbuf->params.u.flate.bpc);
			fz_printf(ctx, out, ">>\n");
		}
		break;

	case FZ_IMAGE_LZW:
		fz_printf(ctx, out, "/F/LZW\n");
		if (cbuf->params.u.lzw.predictor > 1)
		{
			fz_printf(ctx, out, "/DP<<\n");
			fz_printf(ctx, out, "/Predictor %d\n", cbuf->params.u.lzw.predictor);
			if (cbuf->params.u.lzw.columns != 1)
				fz_printf(ctx, out, "/Columns %d\n", cbuf->params.u.lzw.columns);
			if (cbuf->params.u.lzw.colors != 1)
				fz_printf(ctx, out, "/Colors %d\n", cbuf->params.u.lzw.colors);
			if (cbuf->params.u.lzw.bpc != 8)
				fz_printf(ctx, out, "/BitsPerComponent %d\n", cbuf->params.u.lzw.bpc);
			if (cbuf->params.u.lzw.early_change != 1)
				fz_printf(ctx, out, "/EarlyChange %d\n", cbuf->params.u.lzw.early_change);
			fz_printf(ctx, out, ">>\n");
		}
		break;
	}

	fz_printf(ctx, out, "ID\n");
	fz_write(ctx, out, buf->data, buf->len);
	fz_printf(ctx, out, "\nEI\n");
}
Beispiel #12
0
void
fz_output_pwg_bitmap_page(fz_context *ctx, fz_output *out, const fz_bitmap *bitmap, const fz_pwg_options *pwg)
{
	unsigned char *sp;
	int y, x, ss;
	int byte_width;

	if (!out || !bitmap)
		return;

	output_header(ctx, out, pwg, bitmap->xres, bitmap->yres, bitmap->w, bitmap->h, 1);

	/* Now output the actual bitmap, using a packbits like compression */
	sp = bitmap->samples;
	ss = bitmap->stride;
	byte_width = (bitmap->w+7)/8;
	y = 0;
	while (y < bitmap->h)
	{
		int yrep;

		assert(sp == bitmap->samples + y * ss);

		/* Count the number of times this line is repeated */
		for (yrep = 1; yrep < 256 && y+yrep < bitmap->h; yrep++)
		{
			if (memcmp(sp, sp + yrep * ss, byte_width) != 0)
				break;
		}
		fz_write_byte(ctx, out, yrep-1);

		/* Encode the line */
		x = 0;
		while (x < byte_width)
		{
			int d;

			assert(sp == bitmap->samples + y * ss + x);

			/* How far do we have to look to find a repeated value? */
			for (d = 1; d < 128 && x+d < byte_width; d++)
			{
				if (sp[d-1] == sp[d])
					break;
			}
			if (d == 1)
			{
				int xrep;

				/* We immediately have a repeat (or we've hit
				 * the end of the line). Count the number of
				 * times this value is repeated. */
				for (xrep = 1; xrep < 128 && x+xrep < byte_width; xrep++)
				{
					if (sp[0] != sp[xrep])
						break;
				}
				fz_write_byte(ctx, out, xrep-1);
				fz_write(ctx, out, sp, 1);
				sp += xrep;
				x += xrep;
			}
			else
			{
				fz_write_byte(ctx, out, 257-d);
				fz_write(ctx, out, sp, d);
				sp += d;
				x += d;
			}
		}

		/* Move to the next line */
		sp += ss*yrep - byte_width;
		y += yrep;
	}
}
Beispiel #13
0
static void
output_header(fz_context *ctx, fz_output *out, const fz_pwg_options *pwg, int xres, int yres, int w, int h, int bpp)
{
	static const char zero[64] = { 0 };
	int i;

	/* Page Header: */
	fz_write(ctx, out, pwg ? pwg->media_class : zero, 64);
	fz_write(ctx, out, pwg ? pwg->media_color : zero, 64);
	fz_write(ctx, out, pwg ? pwg->media_type : zero, 64);
	fz_write(ctx, out, pwg ? pwg->output_type : zero, 64);
	fz_write_int32be(ctx, out, pwg ? pwg->advance_distance : 0);
	fz_write_int32be(ctx, out, pwg ? pwg->advance_media : 0);
	fz_write_int32be(ctx, out, pwg ? pwg->collate : 0);
	fz_write_int32be(ctx, out, pwg ? pwg->cut_media : 0);
	fz_write_int32be(ctx, out, pwg ? pwg->duplex : 0);
	fz_write_int32be(ctx, out, xres);
	fz_write_int32be(ctx, out, yres);
	/* CUPS format says that 284->300 are supposed to be the bbox of the
	 * page in points. PWG says 'Reserved'. */
	for (i=284; i < 300; i += 4)
		fz_write(ctx, out, zero, 4);
	fz_write_int32be(ctx, out, pwg ? pwg->insert_sheet : 0);
	fz_write_int32be(ctx, out, pwg ? pwg->jog : 0);
	fz_write_int32be(ctx, out, pwg ? pwg->leading_edge : 0);
	/* CUPS format says that 312->320 are supposed to be the margins of
	 * the lower left hand edge of page in points. PWG says 'Reserved'. */
	for (i=312; i < 320; i += 4)
		fz_write(ctx, out, zero, 4);
	fz_write_int32be(ctx, out, pwg ? pwg->manual_feed : 0);
	fz_write_int32be(ctx, out, pwg ? pwg->media_position : 0);
	fz_write_int32be(ctx, out, pwg ? pwg->media_weight : 0);
	fz_write_int32be(ctx, out, pwg ? pwg->mirror_print : 0);
	fz_write_int32be(ctx, out, pwg ? pwg->negative_print : 0);
	fz_write_int32be(ctx, out, pwg ? pwg->num_copies : 0);
	fz_write_int32be(ctx, out, pwg ? pwg->orientation : 0);
	fz_write_int32be(ctx, out, pwg ? pwg->output_face_up : 0);
	fz_write_int32be(ctx, out, w * 72/ xres);	/* Page size in points */
	fz_write_int32be(ctx, out, h * 72/ yres);
	fz_write_int32be(ctx, out, pwg ? pwg->separations : 0);
	fz_write_int32be(ctx, out, pwg ? pwg->tray_switch : 0);
	fz_write_int32be(ctx, out, pwg ? pwg->tumble : 0);
	fz_write_int32be(ctx, out, w); /* Page image in pixels */
	fz_write_int32be(ctx, out, h);
	fz_write_int32be(ctx, out, pwg ? pwg->media_type_num : 0);
	fz_write_int32be(ctx, out, bpp < 8 ? 1 : 8); /* Bits per color */
	fz_write_int32be(ctx, out, bpp); /* Bits per pixel */
	fz_write_int32be(ctx, out, (w * bpp + 7)/8); /* Bytes per line */
	fz_write_int32be(ctx, out, 0); /* Chunky pixels */
	switch (bpp)
	{
	case 1: fz_write_int32be(ctx, out, 3); /* Black */ break;
	case 8: fz_write_int32be(ctx, out, 18); /* Sgray */ break;
	case 24: fz_write_int32be(ctx, out, 19); /* Srgb */ break;
	case 32: fz_write_int32be(ctx, out, 6); /* Cmyk */ break;
	default: fz_throw(ctx, FZ_ERROR_GENERIC, "pixmap bpp must be 1, 8, 24 or 32 to write as pwg");
	}
	fz_write_int32be(ctx, out, pwg ? pwg->compression : 0);
	fz_write_int32be(ctx, out, pwg ? pwg->row_count : 0);
	fz_write_int32be(ctx, out, pwg ? pwg->row_feed : 0);
	fz_write_int32be(ctx, out, pwg ? pwg->row_step : 0);
	fz_write_int32be(ctx, out, bpp <= 8 ? 1 : 3); /* Num Colors */
	for (i=424; i < 452; i += 4)
		fz_write(ctx, out, zero, 4);
	fz_write_int32be(ctx, out, 1); /* TotalPageCount */
	fz_write_int32be(ctx, out, 1); /* CrossFeedTransform */
	fz_write_int32be(ctx, out, 1); /* FeedTransform */
	fz_write_int32be(ctx, out, 0); /* ImageBoxLeft */
	fz_write_int32be(ctx, out, 0); /* ImageBoxTop */
	fz_write_int32be(ctx, out, w); /* ImageBoxRight */
	fz_write_int32be(ctx, out, h); /* ImageBoxBottom */
	for (i=480; i < 1668; i += 4)
		fz_write(ctx, out, zero, 4);
	fz_write(ctx, out, pwg ? pwg->rendering_intent : zero, 64);
	fz_write(ctx, out, pwg ? pwg->page_size_name : zero, 64);
}
static fz_error *
writestream(fz_stream *out, pdf_xref *xref, pdf_crypt *encrypt, int oid, int gen)
{
	fz_error *error;
	fz_stream *dststm;
	fz_stream *srcstm;
	unsigned char buf[4096];
	fz_filter *ef;
	int n;

	fz_print(out, "stream\n");

	if (encrypt)
	{
		error = pdf_cryptstream(&ef, encrypt, oid, gen);
		if (error)
			return error;

		error = fz_openrfilter(&dststm, ef, out);
		fz_dropfilter(ef);
		if (error)
			return error;
	}
	else
	{
		dststm = fz_keepstream(out);
	}

	error = pdf_openrawstream(&srcstm, xref, oid, gen);
	if (error)
		goto cleanupdst;

	while (1)
	{
		n = fz_read(srcstm, buf, sizeof buf);
		if (n == 0)
			break;
		if (n < 0)
		{
			error = fz_ioerror(srcstm);
			goto cleanupsrc;
		}

		n = fz_write(dststm, buf, n);
		if (n < 0)
		{
			error = fz_ioerror(dststm);
			goto cleanupsrc;
		}
	}

	fz_dropstream(srcstm);
	fz_dropstream(dststm);

	fz_print(out, "endstream\n");

	return nil;

cleanupsrc:
	fz_dropstream(srcstm);
cleanupdst:
	fz_dropstream(dststm);
	return error;
}
Beispiel #15
0
void
fz_output_pcl_bitmap(fz_output *out, const fz_bitmap *bitmap, fz_pcl_options *pcl)
{
    unsigned char *data, *out_data;
    int y, ss, rmask, line_size;
    fz_context *ctx;
    int num_blank_lines;
    int compression = -1;
    unsigned char *prev_row = NULL;
    unsigned char *out_row_mode_2 = NULL;
    unsigned char *out_row_mode_3 = NULL;
    int out_count;
    int max_mode_2_size;
    int max_mode_3_size;

    if (!out || !bitmap)
        return;

    ctx = out->ctx;

    if (pcl->features & HACK__IS_A_OCE9050)
    {
        /* Enter HPGL/2 mode, begin plot, Initialise (start plot), Enter PCL mode */
        fz_puts(out, "\033%1BBPIN;\033%1A");
    }

    pcl_header(out, pcl, 1, bitmap->xres);

    fz_var(prev_row);
    fz_var(out_row_mode_2);
    fz_var(out_row_mode_3);

    fz_try(ctx)
    {
        num_blank_lines = 0;
        rmask = ~0 << (-bitmap->w & 7);
        line_size = (bitmap->w + 7)/8;
        max_mode_2_size = line_size + (line_size/127) + 1;
        max_mode_3_size = line_size + (line_size/8) + 1;
        prev_row = fz_calloc(ctx, line_size, sizeof(unsigned char));
        out_row_mode_2 = fz_calloc(ctx, max_mode_2_size, sizeof(unsigned char));
        out_row_mode_3 = fz_calloc(ctx, max_mode_3_size, sizeof(unsigned char));

        /* Transfer raster graphics. */
        data = bitmap->samples;
        ss = bitmap->stride;
        for (y = 0; y < bitmap->h; y++, data += ss)
        {
            unsigned char *end_data = data + line_size;

            if ((end_data[-1] & rmask) == 0)
            {
                end_data--;
                while (end_data > data && end_data[-1] == 0)
                    end_data--;
            }
            if (end_data == data)
            {
                /* Blank line */
                num_blank_lines++;
                continue;
            }
            wind();

            /* We've reached a non-blank line. */
            /* Put out a spacing command if necessary. */
            if (num_blank_lines == y) {
                /* We're at the top of a page. */
                if (pcl->features & PCL_ANY_SPACING)
                {
                    if (num_blank_lines > 0)
                        fz_printf(out, "\033*p+%dY", num_blank_lines * bitmap->yres);
                    /* Start raster graphics. */
                    fz_puts(out, "\033*r1A");
                }
                else if (pcl->features & PCL_MODE_3_COMPRESSION)
                {
                    /* Start raster graphics. */
                    fz_puts(out, "\033*r1A");
                    for (; num_blank_lines; num_blank_lines--)
                        fz_puts(out, "\033*b0W");
                }
                else
                {
                    /* Start raster graphics. */
                    fz_puts(out, "\033*r1A");
                    for (; num_blank_lines; num_blank_lines--)
                        fz_puts(out, "\033*bW");
                }
            }

            /* Skip blank lines if any */
            else if (num_blank_lines != 0)
            {
                /* Moving down from current position causes head
                 * motion on the DeskJet, so if the number of lines
                 * is small, we're better off printing blanks.
                 *
                 * For Canon LBP4i and some others, <ESC>*b<n>Y
                 * doesn't properly clear the seed row if we are in
                 * compression mode 3.
                 */
                if ((num_blank_lines < MIN_SKIP_LINES && compression != 3) ||
                        !(pcl->features & PCL_ANY_SPACING))
                {
                    int mode_3ns = ((pcl->features & PCL_MODE_3_COMPRESSION) && !(pcl->features & PCL_ANY_SPACING));
                    if (mode_3ns && compression != 2)
                    {
                        /* Switch to mode 2 */
                        fz_puts(out, from3to2);
                        compression = 2;
                    }
                    if (pcl->features & PCL_MODE_3_COMPRESSION)
                    {
                        /* Must clear the seed row. */
                        fz_puts(out, "\033*b1Y");
                        num_blank_lines--;
                    }
                    if (mode_3ns)
                    {
                        for (; num_blank_lines; num_blank_lines--)
                            fz_puts(out, "\033*b0W");
                    }
                    else
                    {
                        for (; num_blank_lines; num_blank_lines--)
                            fz_puts(out, "\033*bW");
                    }
                }
                else if (pcl->features & PCL3_SPACING)
                    fz_printf(out, "\033*p+%dY", num_blank_lines * bitmap->yres);
                else
                    fz_printf(out, "\033*b%dY", num_blank_lines);
                /* Clear the seed row (only matters for mode 3 compression). */
                memset(prev_row, 0, line_size);
            }
            num_blank_lines = 0;

            /* Choose the best compression mode for this particular line. */
            if (pcl->features & PCL_MODE_3_COMPRESSION)
            {
                /* Compression modes 2 and 3 are both available. Try
                 * both and see which produces the least output data.
                 */
                int count3 = mode3compress(out_row_mode_3, data, prev_row, line_size);
                int count2 = mode2compress(out_row_mode_2, data, line_size);
                int penalty3 = (compression == 3 ? 0 : penalty_from2to3);
                int penalty2 = (compression == 2 ? 0 : penalty_from3to2);

                if (count3 + penalty3 < count2 + penalty2)
                {
                    if (compression != 3)
                        fz_puts(out, from2to3);
                    compression = 3;
                    out_data = (unsigned char *)out_row_mode_3;
                    out_count = count3;
                }
                else
                {
                    if (compression != 2)
                        fz_puts(out, from3to2);
                    compression = 2;
                    out_data = (unsigned char *)out_row_mode_2;
                    out_count = count2;
                }
            }
            else if (pcl->features & PCL_MODE_2_COMPRESSION)
            {
                out_data = out_row_mode_2;
                out_count = mode2compress(out_row_mode_2, data, line_size);
            }
            else
            {
                out_data = data;
                out_count = line_size;
            }

            /* Transfer the data */
            fz_printf(out, "\033*b%dW", out_count);
            fz_write(out, out_data, out_count);
        }

        /* end raster graphics and eject page */
        fz_puts(out, "\033*rB\f");

        if (pcl->features & HACK__IS_A_OCE9050)
        {
            /* Pen up, pen select, advance full page, reset */
            fz_puts(out, "\033%1BPUSP0PG;\033E");
        }
    }
    fz_always(ctx)
    {
        fz_free(ctx, prev_row);
        fz_free(ctx, out_row_mode_2);
        fz_free(ctx, out_row_mode_3);
    }
    fz_catch(ctx)
    {
        fz_rethrow(ctx);
    }
}
Beispiel #16
0
static void savefont(pdf_obj *dict, int num)
{
	char namebuf[1024];
	fz_buffer *buf;
	pdf_obj *stream = NULL;
	pdf_obj *obj;
	char *ext = "";
	fz_output *out;
	char *fontname = "font";
	size_t len;
	unsigned char *data;

	obj = pdf_dict_get(ctx, dict, PDF_NAME_FontName);
	if (obj)
		fontname = pdf_to_name(ctx, obj);

	obj = pdf_dict_get(ctx, dict, PDF_NAME_FontFile);
	if (obj)
	{
		stream = obj;
		ext = "pfa";
	}

	obj = pdf_dict_get(ctx, dict, PDF_NAME_FontFile2);
	if (obj)
	{
		stream = obj;
		ext = "ttf";
	}

	obj = pdf_dict_get(ctx, dict, PDF_NAME_FontFile3);
	if (obj)
	{
		stream = obj;

		obj = pdf_dict_get(ctx, obj, PDF_NAME_Subtype);
		if (obj && !pdf_is_name(ctx, obj))
			fz_throw(ctx, FZ_ERROR_GENERIC, "invalid font descriptor subtype");

		if (pdf_name_eq(ctx, obj, PDF_NAME_Type1C))
			ext = "cff";
		else if (pdf_name_eq(ctx, obj, PDF_NAME_CIDFontType0C))
			ext = "cid";
		else if (pdf_name_eq(ctx, obj, PDF_NAME_OpenType))
			ext = "otf";
		else
			fz_throw(ctx, FZ_ERROR_GENERIC, "unhandled font type '%s'", pdf_to_name(ctx, obj));
	}

	if (!stream)
	{
		fz_warn(ctx, "unhandled font type");
		return;
	}

	buf = pdf_load_stream(ctx, doc, pdf_to_num(ctx, stream));
	len = fz_buffer_storage(ctx, buf, &data);
	fz_try(ctx)
	{
		snprintf(namebuf, sizeof(namebuf), "%s-%04d.%s", fontname, num, ext);
		printf("extracting font %s\n", namebuf);
		out = fz_new_output_with_path(ctx, namebuf, 0);
		fz_try(ctx)
			fz_write(ctx, out, data, len);
		fz_always(ctx)
			fz_drop_output(ctx, out);
		fz_catch(ctx)
			fz_rethrow(ctx);
	}
	fz_always(ctx)
		fz_drop_buffer(ctx, buf);
	fz_catch(ctx)
		fz_rethrow(ctx);
}
Beispiel #17
0
void
fz_save_gproof(fz_context *ctx, const char *pdf_file, fz_document *doc, const char *filename, int res,
				const char *print_profile, const char *display_profile)
{
	int i;
	int num_pages = fz_count_pages(ctx, doc);
	fz_output *out;
	fz_page *page = NULL;

	fz_var(page);

	if (num_pages <= 0)
		fz_throw(ctx, FZ_ERROR_GENERIC, "Cannot write a 0 page GProof skeleton file");

	out = fz_new_output_with_path(ctx, filename, 0);

	fz_try(ctx)
	{
		/* File Signature: GPRO */
		fz_write_int32_le(ctx, out, 0x4f525047);

		/* Version = 1 */
		fz_write_byte(ctx, out, 1);
		fz_write_byte(ctx, out, 0);

		/* Resolution */
		fz_write_int32_le(ctx, out, res);

		/* Num Pages */
		fz_write_int32_le(ctx, out, num_pages);

		for (i = 0; i < num_pages; i++)
		{
			fz_rect rect;
			int w, h;

			page = fz_load_page(ctx, doc, i);
			fz_bound_page(ctx, page, &rect);
			fz_drop_page(ctx, page);
			page = NULL;

			/* Same lack of rounding as gs uses */
			w = (int)((rect.x1 - rect.x0) * res / 72.0);
			h = (int)((rect.y1 - rect.y0) * res / 72.0);
			fz_write_int32_le(ctx, out, w);
			fz_write_int32_le(ctx, out, h);
		}

		/* Filenames */
		fz_write(ctx, out, pdf_file, strlen(pdf_file)+1);
		fz_write(ctx, out, print_profile, strlen(print_profile) + 1);
		fz_write(ctx, out, display_profile, strlen(display_profile) + 1);

	}
	fz_always(ctx)
	{
		fz_drop_page(ctx, page);
		fz_drop_output(ctx, out);
	}
	fz_catch(ctx)
	{
		fz_rethrow(ctx);
	}
}