Allow > 2GB PDF files on platforms with 32-bit long

This commit is contained in:
Adrian Johnson 2021-09-01 21:33:29 +09:30
parent 42d3f4cc29
commit 6e3c7431ff
4 changed files with 49 additions and 29 deletions

View file

@ -58,7 +58,7 @@ struct _cairo_output_stream {
cairo_output_stream_write_func_t write_func;
cairo_output_stream_flush_func_t flush_func;
cairo_output_stream_close_func_t close_func;
unsigned long position;
long long position;
cairo_status_t status;
cairo_bool_t closed;
};
@ -140,7 +140,7 @@ cairo_private void
_cairo_output_stream_print_matrix (cairo_output_stream_t *stream,
const cairo_matrix_t *matrix);
cairo_private long
cairo_private long long
_cairo_output_stream_get_position (cairo_output_stream_t *stream);
cairo_private cairo_status_t

View file

@ -1,3 +1,4 @@
/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
/* cairo-output-stream.c: Output stream abstraction
*
* Copyright © 2005 Red Hat, Inc
@ -382,7 +383,8 @@ _cairo_dtostr (char *buffer, size_t size, double d, cairo_bool_t limited_precisi
}
enum {
LENGTH_MODIFIER_LONG = 0x100
LENGTH_MODIFIER_LONG = 0x100,
LENGTH_MODIFIER_LONG_LONG = 0x200
};
/* Here's a limited reimplementation of printf. The reason for doing
@ -440,6 +442,10 @@ _cairo_output_stream_vprintf (cairo_output_stream_t *stream,
if (*f == 'l') {
length_modifier = LENGTH_MODIFIER_LONG;
f++;
if (*f == 'l') {
length_modifier = LENGTH_MODIFIER_LONG_LONG;
f++;
}
}
/* The only format strings exist in the cairo implementation
@ -490,6 +496,20 @@ _cairo_output_stream_vprintf (cairo_output_stream_t *stream,
single_fmt, va_arg (ap, long int));
}
break;
case 'd' | LENGTH_MODIFIER_LONG_LONG:
case 'u' | LENGTH_MODIFIER_LONG_LONG:
case 'o' | LENGTH_MODIFIER_LONG_LONG:
case 'x' | LENGTH_MODIFIER_LONG_LONG:
case 'X' | LENGTH_MODIFIER_LONG_LONG:
if (var_width) {
width = va_arg (ap, int);
snprintf (buffer, sizeof buffer,
single_fmt, width, va_arg (ap, long long int));
} else {
snprintf (buffer, sizeof buffer,
single_fmt, va_arg (ap, long long int));
}
break;
case 's': {
/* Write out strings as they may be larger than the buffer. */
const char *s = va_arg (ap, const char *);
@ -570,7 +590,7 @@ _cairo_output_stream_print_matrix (cairo_output_stream_t *stream,
m.xx, m.yx, m.xy, m.yy, m.x0, m.y0);
}
long
long long
_cairo_output_stream_get_position (cairo_output_stream_t *stream)
{
return stream->position;

View file

@ -302,7 +302,7 @@ struct _cairo_pdf_surface {
cairo_bool_t active;
cairo_pdf_resource_t self;
cairo_pdf_resource_t length;
long start_offset;
long long start_offset;
cairo_bool_t compressed;
cairo_output_stream_t *old_output;
} pdf_stream;

View file

@ -243,7 +243,7 @@ typedef enum {
typedef struct _cairo_pdf_object {
cairo_pdf_object_type_t type;
union {
long offset; /* type == PDF_OBJECT_UNCOMPRESSED */
long long offset; /* type == PDF_OBJECT_UNCOMPRESSED */
struct compressed_obj { /* type == PDF_OBJECT_COMPRESSED */
cairo_pdf_resource_t xref_stream;
int index;
@ -253,7 +253,7 @@ typedef struct _cairo_pdf_object {
typedef struct _cairo_xref_stream_object {
cairo_pdf_resource_t resource;
long offset;
long long offset;
} cairo_xref_stream_object_t;
typedef struct _cairo_pdf_font {
@ -313,7 +313,7 @@ static cairo_int_status_t
_cairo_pdf_surface_write_catalog (cairo_pdf_surface_t *surface,
cairo_pdf_resource_t catalog);
static long
static long long
_cairo_pdf_surface_write_xref (cairo_pdf_surface_t *surface);
static cairo_int_status_t
@ -321,7 +321,7 @@ _cairo_pdf_surface_write_xref_stream (cairo_pdf_surface_t *surface,
cairo_pdf_resource_t xref_res,
cairo_pdf_resource_t root_res,
cairo_pdf_resource_t info_res,
long *xref_offset);
long long *xref_offset);
static cairo_int_status_t
_cairo_pdf_surface_write_patterns_and_smask_groups (cairo_pdf_surface_t *surface,
@ -1936,7 +1936,7 @@ static cairo_int_status_t
_cairo_pdf_surface_close_stream (cairo_pdf_surface_t *surface)
{
cairo_int_status_t status;
long length;
long long length;
if (! surface->pdf_stream.active)
return CAIRO_INT_STATUS_SUCCESS;
@ -1966,7 +1966,7 @@ _cairo_pdf_surface_close_stream (cairo_pdf_surface_t *surface)
surface->pdf_stream.length);
_cairo_output_stream_printf (surface->output,
"%d 0 obj\n"
" %ld\n"
" %lld\n"
"endobj\n",
surface->pdf_stream.length.id,
length);
@ -2205,7 +2205,7 @@ _cairo_pdf_surface_close_object_stream (cairo_pdf_surface_t *surface)
{
int i, num_objects;
cairo_xref_stream_object_t *xref_obj;
long start_pos, length;
long long start_pos, length;
cairo_output_stream_t *index_stream;
cairo_output_stream_t *deflate_stream;
cairo_pdf_resource_t length_res;
@ -2230,7 +2230,7 @@ _cairo_pdf_surface_close_object_stream (cairo_pdf_surface_t *surface)
for (i = 0; i < num_objects; i++) {
xref_obj = _cairo_array_index (&surface->object_stream.objects, i);
_cairo_output_stream_printf (index_stream,
"%d %ld\n",
"%d %lld\n",
xref_obj->resource.id,
xref_obj->offset);
}
@ -2285,7 +2285,7 @@ _cairo_pdf_surface_close_object_stream (cairo_pdf_surface_t *surface)
length_res);
_cairo_output_stream_printf (surface->output,
"%d 0 obj\n"
" %ld\n"
" %lld\n"
"endobj\n",
length_res.id,
length);
@ -2423,7 +2423,7 @@ static cairo_status_t
_cairo_pdf_surface_finish (void *abstract_surface)
{
cairo_pdf_surface_t *surface = abstract_surface;
long offset;
long long offset;
cairo_pdf_resource_t catalog;
cairo_status_t status, status2;
int size, i;
@ -2491,7 +2491,7 @@ _cairo_pdf_surface_finish (void *abstract_surface)
}
_cairo_output_stream_printf (surface->output,
"startxref\n"
"%ld\n"
"%lld\n"
"%%%%EOF\n",
offset);
@ -6738,12 +6738,12 @@ _cairo_pdf_surface_write_catalog (cairo_pdf_surface_t *surface,
return status;
}
static long
static long long
_cairo_pdf_surface_write_xref (cairo_pdf_surface_t *surface)
{
cairo_pdf_object_t *object;
int num_objects, i;
long offset;
long long offset;
char buffer[11];
num_objects = _cairo_array_num_elements (&surface->objects);
@ -6758,7 +6758,7 @@ _cairo_pdf_surface_write_xref (cairo_pdf_surface_t *surface)
"0000000000 65535 f \n");
for (i = 0; i < num_objects; i++) {
object = _cairo_array_index (&surface->objects, i);
snprintf (buffer, sizeof buffer, "%010ld", object->u.offset);
snprintf (buffer, sizeof buffer, "%010lld", object->u.offset);
_cairo_output_stream_printf (surface->output,
"%s 00000 n \n", buffer);
}
@ -6771,7 +6771,7 @@ _cairo_write_xref_stream_entry (cairo_output_stream_t *stream,
int id,
int type,
int field2_size,
long field2,
long long field2,
int field3,
cairo_bool_t write_as_comments)
{
@ -6779,7 +6779,7 @@ _cairo_write_xref_stream_entry (cairo_output_stream_t *stream,
int i;
if (write_as_comments) {
_cairo_output_stream_printf (stream, "%% %5d %2d %10ld %d\n", id, type, field2, field3);
_cairo_output_stream_printf (stream, "%% %5d %2d %10lld %d\n", id, type, field2, field3);
} else {
/* Each field is big endian */
buf[0] = type; /* field 1 */
@ -6794,10 +6794,10 @@ _cairo_write_xref_stream_entry (cairo_output_stream_t *stream,
}
static void
_cairo_write_xref_stream_entrys (cairo_pdf_surface_t *surface,
cairo_output_stream_t *stream,
int field2_size,
cairo_bool_t write_as_comments)
_cairo_write_xref_stream_entries (cairo_pdf_surface_t *surface,
cairo_output_stream_t *stream,
int field2_size,
cairo_bool_t write_as_comments)
{
cairo_pdf_object_t *object;
int num_objects, i;
@ -6847,11 +6847,11 @@ _cairo_pdf_surface_write_xref_stream (cairo_pdf_surface_t *surface,
cairo_pdf_resource_t xref_res,
cairo_pdf_resource_t root_res,
cairo_pdf_resource_t info_res,
long *xref_offset)
long long *xref_offset)
{
cairo_output_stream_t *mem_stream;
cairo_output_stream_t *xref_stream;
long offset;
long long offset;
int offset_bytes;
cairo_status_t status;
@ -6867,7 +6867,7 @@ _cairo_pdf_surface_write_xref_stream (cairo_pdf_surface_t *surface,
mem_stream = _cairo_memory_stream_create ();
xref_stream = _cairo_deflate_stream_create (mem_stream);
_cairo_write_xref_stream_entrys (surface, xref_stream, offset_bytes, FALSE);
_cairo_write_xref_stream_entries (surface, xref_stream, offset_bytes, FALSE);
status = _cairo_output_stream_destroy (xref_stream);
if (unlikely (status))
@ -6900,7 +6900,7 @@ _cairo_pdf_surface_write_xref_stream (cairo_pdf_surface_t *surface,
*/
_cairo_output_stream_printf (surface->output,
"%% id type offset/obj gen/index\n");
_cairo_write_xref_stream_entrys (surface, surface->output, offset_bytes, TRUE);
_cairo_write_xref_stream_entries (surface, surface->output, offset_bytes, TRUE);
}
_cairo_output_stream_printf (surface->output,