Back to index

texmacs  1.0.7.15
Classes | Defines | Typedefs | Functions | Variables
pdfobj.c File Reference
#include <ctype.h>
#include <string.h>
#include "system.h"
#include "mem.h"
#include "error.h"
#include "mfileio.h"
#include "dpxutil.h"
#include "pdflimits.h"
#include "pdfencrypt.h"
#include "pdfparse.h"
#include "pdfobj.h"
#include "pdfdev.h"

Go to the source code of this file.

Classes

struct  pdf_obj
struct  pdf_boolean
struct  pdf_number
struct  pdf_string
struct  pdf_name
struct  pdf_array
struct  pdf_dict
struct  pdf_stream
struct  pdf_indirect
struct  xref_entry
struct  pdf_file

Defines

#define STREAM_ALLOC_SIZE   4096u
#define ARRAY_ALLOC_SIZE   256
#define IND_OBJECTS_ALLOC_SIZE   512
#define OBJ_NO_OBJSTM   (1 << 0)
#define OBJ_NO_ENCRYPT   (1 << 1)
#define FORMAT_BUF_SIZE   4096
#define OBJSTM_MAX_OBJS   200
#define BINARY_MARKER   "%\344\360\355\370\n"
#define pdf_out_xchar(f, c)
#define TYPECHECK(o, t)
#define INVALIDOBJ(o)   ((o) == NULL || (o)->type <= 0 || (o)->type > PDF_UNDEFINED)
#define pdf_match_name(o, s)   ((o) && (s) && !strcmp(((pdf_name *)(o)->data)->name, (s)))
#define checklabel(pf, n, g)
#define OBJ_FILE(o)   (((pdf_indirect *)((o)->data))->pf)
#define OBJ_NUM(o)   (((pdf_indirect *)((o)->data))->label)
#define OBJ_GEN(o)   (((pdf_indirect *)((o)->data))->generation)

Typedefs

typedef void pdf_null
typedef struct pdf_boolean
typedef struct pdf_number
typedef struct pdf_string
typedef struct pdf_name
typedef struct pdf_array
typedef struct pdf_dict
typedef struct pdf_stream
typedef struct pdf_indirect
typedef struct xref_entry xref_entry

Functions

static int check_for_pdf_version (FILE *file)
static void pdf_flush_obj (pdf_obj *object, FILE *file)
static void pdf_label_obj (pdf_obj *object)
static void pdf_write_obj (pdf_obj *object, FILE *file)
static void set_objstm_data (pdf_obj *objstm, long *data)
static long * get_objstm_data (pdf_obj *objstm)
static void release_objstm (pdf_obj *objstm)
static void pdf_out_char (FILE *file, char c)
static void pdf_out (FILE *file, const void *buffer, long length)
static void release_indirect (pdf_indirect *data)
static void write_indirect (pdf_indirect *indirect, FILE *file)
static void release_boolean (pdf_obj *data)
static void write_boolean (pdf_boolean *data, FILE *file)
static void release_null (pdf_null *data)
static void write_null (pdf_null *data, FILE *file)
static void release_number (pdf_number *number)
static void write_number (pdf_number *number, FILE *file)
static void write_string (pdf_string *str, FILE *file)
static void release_string (pdf_string *str)
static void write_name (pdf_name *name, FILE *file)
static void release_name (pdf_name *name)
static void write_array (pdf_array *array, FILE *file)
static void release_array (pdf_array *array)
static void write_dict (pdf_dict *dict, FILE *file)
static void release_dict (pdf_dict *dict)
static void write_stream (pdf_stream *stream, FILE *file)
static void release_stream (pdf_stream *stream)
void pdf_set_compression (int level)
void pdf_set_version (unsigned version)
unsigned pdf_get_version (void)
int pdf_obj_get_verbose (void)
void pdf_obj_set_verbose (void)
static void add_xref_entry (unsigned long label, unsigned char type, unsigned long field2, unsigned short field3)
void pdf_out_init (const char *filename, int do_encryption)
static void dump_xref_table (void)
static void dump_trailer_dict (void)
static void dump_xref_stream (void)
void pdf_out_flush (void)
void pdf_error_cleanup (void)
void pdf_set_root (pdf_obj *object)
void pdf_set_info (pdf_obj *object)
void pdf_set_id (pdf_obj *id)
void pdf_set_encrypt (pdf_obj *encrypt)
static int pdf_need_white (int type1, int type2)
static void pdf_out_white (FILE *file)
static pdf_objpdf_new_obj (int type)
int pdf_obj_typeof (pdf_obj *object)
void pdf_transfer_label (pdf_obj *dst, pdf_obj *src)
pdf_objpdf_link_obj (pdf_obj *object)
pdf_objpdf_ref_obj (pdf_obj *object)
pdf_objpdf_new_undefined (void)
pdf_objpdf_new_null (void)
pdf_objpdf_new_boolean (char value)
char pdf_boolean_value (pdf_obj *object)
pdf_objpdf_new_number (double value)
void pdf_set_number (pdf_obj *object, double value)
double pdf_number_value (pdf_obj *object)
pdf_objpdf_new_string (const void *str, unsigned length)
void * pdf_string_value (pdf_obj *object)
unsigned pdf_string_length (pdf_obj *object)
int pdfobj_escape_str (char *buffer, int bufsize, const unsigned char *s, int len)
void pdf_set_string (pdf_obj *object, unsigned char *str, unsigned length)
pdf_objpdf_new_name (const char *name)
char * pdf_name_value (pdf_obj *object)
pdf_objpdf_new_array (void)
pdf_objpdf_get_array (pdf_obj *array, long idx)
unsigned int pdf_array_length (pdf_obj *array)
void pdf_add_array (pdf_obj *array, pdf_obj *object)
void pdf_unshift_array (pdf_obj *array, pdf_obj *object)
pdf_objpdf_new_dict (void)
int pdf_add_dict (pdf_obj *dict, pdf_obj *key, pdf_obj *value)
void pdf_merge_dict (pdf_obj *dict1, pdf_obj *dict2)
int pdf_foreach_dict (pdf_obj *dict, int(*proc)(pdf_obj *, pdf_obj *, void *), void *pdata)
pdf_objpdf_lookup_dict (pdf_obj *dict, const char *name)
pdf_objpdf_dict_keys (pdf_obj *dict)
void pdf_remove_dict (pdf_obj *dict, const char *name)
pdf_objpdf_new_stream (int flags)
pdf_objpdf_stream_dict (pdf_obj *stream)
const void * pdf_stream_dataptr (pdf_obj *stream)
long pdf_stream_length (pdf_obj *stream)
void pdf_add_stream (pdf_obj *stream, const void *stream_data, long length)
int pdf_concat_stream (pdf_obj *dst, pdf_obj *src)
static pdf_objpdf_stream_uncompress (pdf_obj *src)
static long pdf_add_objstm (pdf_obj *objstm, pdf_obj *object)
void pdf_release_obj (pdf_obj *object)
static int backup_line (FILE *pdf_input_file)
static long find_xref (FILE *pdf_input_file)
static pdf_objparse_trailer (pdf_file *pf)
static long next_object_offset (pdf_file *pf, unsigned long obj_num)
pdf_objpdf_new_indirect (pdf_file *pf, unsigned long obj_num, unsigned short obj_gen)
static pdf_objpdf_read_object (unsigned long obj_num, unsigned short obj_gen, pdf_file *pf, long offset, long limit)
static pdf_objread_objstm (pdf_file *pf, unsigned long num)
static pdf_objpdf_get_object (pdf_file *pf, unsigned long obj_num, unsigned short obj_gen)
pdf_objpdf_deref_obj (pdf_obj *obj)
static void extend_xref (pdf_file *pf, long new_size)
static int parse_xref_table (pdf_file *pf, long xref_pos)
static unsigned long parse_xrefstm_field (const char **p, int length, unsigned long def)
static int parse_xrefstm_subsec (pdf_file *pf, const char **p, long *length, int *W, int wsum, long first, long size)
static int parse_xref_stream (pdf_file *pf, long xref_pos, pdf_obj **trailer)
static pdf_objread_xref (pdf_file *pf)
pdf_filepdf_file_new (FILE *file)
static void pdf_file_free (pdf_file *pf)
void pdf_files_init (void)
int pdf_file_get_version (pdf_file *pf)
pdf_objpdf_file_get_catalog (pdf_file *pf)
pdf_filepdf_open (const char *ident, FILE *file)
void pdf_close (pdf_file *pf)
void pdf_files_close (void)
int check_for_pdf (FILE *file)
static int CDECL import_dict (pdf_obj *key, pdf_obj *value, void *pdata)
static pdf_objpdf_import_indirect (pdf_obj *object)
pdf_objpdf_import_object (pdf_obj *object)
int pdf_compare_reference (pdf_obj *ref1, pdf_obj *ref2)

Variables

static FILE * pdf_output_file = NULL
static long pdf_output_file_position = 0
static long pdf_output_line_position = 0
static long compression_saved = 0
static char format_buffer [FORMAT_BUF_SIZE]
static xref_entryoutput_xref
static unsigned long pdf_max_ind_objects
static unsigned long next_label
static unsigned long startxref
static pdf_objoutput_stream
static int enc_mode
static int doc_enc_mode
static pdf_objtrailer_dict
static pdf_objxref_stream
static int verbose = 0
static char compression_level = 9
static unsigned pdf_version = PDF_VERSION_DEFAULT
static pdf_objcurrent_objstm = NULL
static int do_objstm
static struct ht_tablepdf_files = NULL
static pdf_obj loop_marker = { PDF_OBJ_INVALID, 0, 0, 0, 0, NULL }

Class Documentation

struct pdf_obj

Definition at line 60 of file pdfobj.c.

Class Members
void * data
int flags
unsigned short generation
unsigned long label
unsigned refcount
int type
struct pdf_boolean

Definition at line 72 of file pdfobj.c.

Class Members
char value
struct pdf_number

Definition at line 77 of file pdfobj.c.

Class Members
double value
struct pdf_string

Definition at line 82 of file pdfobj.c.

Class Members
unsigned short length
unsigned char * string
struct pdf_name

Definition at line 88 of file pdfobj.c.

Class Members
char * name
struct pdf_array

Definition at line 93 of file pdfobj.c.

Collaboration diagram for pdf_array:
Class Members
unsigned long max
unsigned long size
struct pdf_obj ** values
struct pdf_dict

Definition at line 100 of file pdfobj.c.

Collaboration diagram for pdf_dict:
Class Members
struct pdf_obj * key
struct pdf_dict * next
struct pdf_obj * value
struct pdf_stream

Definition at line 107 of file pdfobj.c.

Collaboration diagram for pdf_stream:
Class Members
unsigned char _flags
struct pdf_obj * dict
unsigned long max_length
long * objstm_data
unsigned char * stream
unsigned long stream_length
struct pdf_indirect

Definition at line 117 of file pdfobj.c.

Collaboration diagram for pdf_indirect:
Class Members
unsigned short generation
unsigned long label
pdf_file * pf
struct xref_entry

Definition at line 143 of file pdfobj.c.

Collaboration diagram for xref_entry:
Class Members
pdf_obj * direct
unsigned long field2
unsigned short field3
pdf_obj * indirect
unsigned char type
struct pdf_file

Definition at line 159 of file pdfobj.c.

Collaboration diagram for pdf_file:
Class Members
pdf_obj * catalog
FILE * file
long file_size
long num_obj
pdf_obj * trailer
int version
xref_entry * xref_table

Define Documentation

#define ARRAY_ALLOC_SIZE   256

Definition at line 49 of file pdfobj.c.

#define BINARY_MARKER   "%\344\360\355\370\n"

Definition at line 293 of file pdfobj.c.

#define checklabel (   pf,
  n,
  g 
)
Value:
((n) > 0 && (n) < (pf)->num_obj && ( \
  ((pf)->xref_table[(n)].type == 1 && (pf)->xref_table[(n)].field3 == (g)) || \
  ((pf)->xref_table[(n)].type == 2 && !(g))))

Definition at line 2262 of file pdfobj.c.

#define FORMAT_BUF_SIZE   4096

Definition at line 140 of file pdfobj.c.

#define IND_OBJECTS_ALLOC_SIZE   512

Definition at line 50 of file pdfobj.c.

#define INVALIDOBJ (   o)    ((o) == NULL || (o)->type <= 0 || (o)->type > PDF_UNDEFINED)

Definition at line 593 of file pdfobj.c.

#define OBJ_FILE (   o)    (((pdf_indirect *)((o)->data))->pf)

Definition at line 2503 of file pdfobj.c.

#define OBJ_GEN (   o)    (((pdf_indirect *)((o)->data))->generation)

Definition at line 2505 of file pdfobj.c.

#define OBJ_NO_ENCRYPT   (1 << 1)

Definition at line 55 of file pdfobj.c.

#define OBJ_NO_OBJSTM   (1 << 0)

Definition at line 52 of file pdfobj.c.

#define OBJ_NUM (   o)    (((pdf_indirect *)((o)->data))->label)

Definition at line 2504 of file pdfobj.c.

#define OBJSTM_MAX_OBJS   200

Definition at line 172 of file pdfobj.c.

#define pdf_match_name (   o,
 
)    ((o) && (s) && !strcmp(((pdf_name *)(o)->data)->name, (s)))

Definition at line 1524 of file pdfobj.c.

#define pdf_out_xchar (   f,
 
)
Value:
do {\
  int __tmpnum;\
  __tmpnum = ((c) >> 4) & 0x0f;\
  pdf_out_char((f), (((__tmpnum) >= 10) ? (__tmpnum)+'W' : (__tmpnum)+'0'));\
  __tmpnum = (c) & 0x0f;\
  pdf_out_char((f), (((__tmpnum) >= 10) ? (__tmpnum)+'W' : (__tmpnum)+'0'));\
} while (0)

Definition at line 542 of file pdfobj.c.

#define STREAM_ALLOC_SIZE   4096u

Definition at line 48 of file pdfobj.c.

#define TYPECHECK (   o,
 
)
Value:
if (!(o) || (o)->type != (t)) {\
  ERROR("typecheck: Invalid object type: %d %d (line %d)", (o) ? (o)->type : -1, (t), __LINE__);\
}

Definition at line 589 of file pdfobj.c.


Typedef Documentation

typedef struct pdf_array

Definition at line 129 of file pdfobj.c.

typedef struct pdf_boolean

Definition at line 125 of file pdfobj.c.

typedef struct pdf_dict

Definition at line 130 of file pdfobj.c.

typedef struct pdf_indirect

Definition at line 132 of file pdfobj.c.

typedef struct pdf_name

Definition at line 128 of file pdfobj.c.

typedef void pdf_null

Definition at line 124 of file pdfobj.c.

typedef struct pdf_number

Definition at line 126 of file pdfobj.c.

typedef struct pdf_stream

Definition at line 131 of file pdfobj.c.

typedef struct pdf_string

Definition at line 127 of file pdfobj.c.

typedef struct xref_entry xref_entry

Function Documentation

static void add_xref_entry ( unsigned long  label,
unsigned char  type,
unsigned long  field2,
unsigned short  field3 
) [static]

Definition at line 279 of file pdfobj.c.

Here is the caller graph for this function:

static int backup_line ( FILE *  pdf_input_file) [static]

Definition at line 2146 of file pdfobj.c.

{
  int ch = -1;

  /*
   * Note: this code should work even if \r\n is eol. It could fail on a
   * machine where \n is eol and there is a \r in the stream --- Highly
   * unlikely in the last few bytes where this is likely to be used.
   */
  if (tell_position(pdf_input_file) > 1)
    do {
      seek_relative (pdf_input_file, -2);
    } while (tell_position(pdf_input_file) > 0 &&
            (ch = fgetc(pdf_input_file)) >= 0 &&
            (ch != '\n' && ch != '\r' ));
  if (ch < 0) {
    return 0;
  }

  return 1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int check_for_pdf ( FILE *  file)

Definition at line 3010 of file pdfobj.c.

{
  return (check_for_pdf_version(file) >= 0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int check_for_pdf_version ( FILE *  file) [static]

Definition at line 2999 of file pdfobj.c.

{
  unsigned short minor;

  rewind(file);

  return (ungetc(fgetc(file), file) == '%' &&
         fscanf(file, "%%PDF-1.%hu", &minor) == 1) ? minor : -1;
}

Here is the caller graph for this function:

static void dump_trailer_dict ( void  ) [static]

Definition at line 363 of file pdfobj.c.

Here is the call graph for this function:

Here is the caller graph for this function:

static void dump_xref_stream ( void  ) [static]

Definition at line 377 of file pdfobj.c.

{
  unsigned long pos, i;
  unsigned poslen;
  unsigned char buf[7] = {0, 0, 0, 0, 0};

  pdf_obj *w;

  /* determine the necessary size of the offset field */
  pos = startxref; /* maximal offset value */
  poslen = 1;
  while (pos >>= 8)
    poslen++;

  w = pdf_new_array();
  pdf_add_array(w, pdf_new_number(1));      /* type                */
  pdf_add_array(w, pdf_new_number(poslen)); /* offset (big-endian) */
  pdf_add_array(w, pdf_new_number(2));      /* generation          */
  pdf_add_dict(trailer_dict, pdf_new_name("W"), w);

  /* We need the xref entry for the xref stream right now */
  add_xref_entry(next_label-1, 1, startxref, 0);

  for (i = 0; i < next_label; i++) {
    unsigned j;
    unsigned short f3;
    buf[0] = output_xref[i].type;
    pos = output_xref[i].field2;
    for (j = poslen; j--; ) {
      buf[1+j] = (unsigned char) pos;
      pos >>= 8;
    }
    f3 = output_xref[i].field3;
    buf[poslen+1] = (unsigned char) (f3 >> 8);
    buf[poslen+2] = (unsigned char) (f3);
    pdf_add_stream(xref_stream, &buf, poslen+3);
  }

  pdf_release_obj(xref_stream);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void dump_xref_table ( void  ) [static]

Definition at line 336 of file pdfobj.c.

{
  long length;
  unsigned long i;

  pdf_out(pdf_output_file, "xref\n", 5);

  length = sprintf(format_buffer, "%d %lu\n", 0, next_label);
  pdf_out(pdf_output_file, format_buffer, length);

  /*
   * Every space counts.  The space after the 'f' and 'n' is * *essential*.
   * The PDF spec says the lines must be 20 characters long including the
   * end of line character.
   */
  for (i = 0; i < next_label; i++) {
    unsigned char type = output_xref[i].type;
    if (type > 1)
      ERROR("object type %hu not allowed in xref table", type);
    length = sprintf(format_buffer, "%010lu %05hu %c \n",
                   output_xref[i].field2, output_xref[i].field3,
                   type ? 'n' : 'f');
    pdf_out(pdf_output_file, format_buffer, length);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void extend_xref ( pdf_file pf,
long  new_size 
) [static]

Definition at line 2537 of file pdfobj.c.

{
  unsigned long i;

  pf->xref_table = RENEW(pf->xref_table, new_size, xref_entry);
  for (i = pf->num_obj; i < new_size; i++) {
    pf->xref_table[i].direct   = NULL;
    pf->xref_table[i].indirect = NULL;
    pf->xref_table[i].type     = 0;
    pf->xref_table[i].field3 = 0;
    pf->xref_table[i].field2 = 0L;
  }
  pf->num_obj = new_size;
}

Here is the caller graph for this function:

static long find_xref ( FILE *  pdf_input_file) [static]

Definition at line 2169 of file pdfobj.c.

{
  long xref_pos;
  int  tries = 10;

  do {
    long currentpos;

    if (!backup_line(pdf_input_file)) {
      tries = 0;
      break;
    }
    currentpos = tell_position(pdf_input_file);
    fread(work_buffer, sizeof(char), strlen("startxref"), pdf_input_file);
    seek_absolute(pdf_input_file, currentpos);
    tries--;
  } while (tries > 0 &&
          strncmp(work_buffer, "startxref", strlen("startxref")));
  if (tries <= 0)
    return 0;

  /* Skip rest of this line */
  mfgets(work_buffer, WORK_BUFFER_SIZE, pdf_input_file);
  /* Next line of input file should contain actual xref location */
  mfgets(work_buffer, WORK_BUFFER_SIZE, pdf_input_file);

  {
    char *start, *end, *number;

    start = work_buffer;
    end   = start + strlen(work_buffer);
    skip_white(&start, end);
    number   = parse_number(&start, end);
    xref_pos = (long) atof(number);
    RELEASE(number);
  }

  return xref_pos;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static long * get_objstm_data ( pdf_obj objstm) [static]

Definition at line 1785 of file pdfobj.c.

                                  {
  TYPECHECK(objstm, PDF_STREAM);

  return ((pdf_stream *) objstm->data)->objstm_data;
}

Here is the caller graph for this function:

static int CDECL import_dict ( pdf_obj key,
pdf_obj value,
void *  pdata 
) [static]

Definition at line 3016 of file pdfobj.c.

{
  pdf_obj *copy;
  pdf_obj *tmp;

  copy = (pdf_obj *) pdata;

  tmp  = pdf_import_object(value);
  if (!tmp) {
    return -1;
  }
  pdf_add_dict(copy, pdf_link_obj(key), tmp);

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static long next_object_offset ( pdf_file pf,
unsigned long  obj_num 
) [static]

Definition at line 2245 of file pdfobj.c.

{
  long  next = pf->file_size;  /* Worst case */
  long  i, curr;

  curr = pf->xref_table[obj_num].field2;
  /* Check all other type 1 objects to find next one */
  for (i = 0; i < pf->num_obj; i++) {
    if (pf->xref_table[i].type == 1 &&
        pf->xref_table[i].field2 > curr &&
        pf->xref_table[i].field2 < next)
      next = pf->xref_table[i].field2;
  }

  return  next;
}

Here is the caller graph for this function:

static pdf_obj* parse_trailer ( pdf_file pf) [static]

Definition at line 2214 of file pdfobj.c.

{
  pdf_obj *result;
  /*
   * Fill work_buffer and hope trailer fits. This should
   * be made a bit more robust sometime.
   */
  if (fread(work_buffer, sizeof(char),
           WORK_BUFFER_SIZE, pf->file) == 0 ||
      strncmp(work_buffer, "trailer", strlen("trailer"))) {
    WARN("No trailer.  Are you sure this is a PDF file?");
    WARN("buffer:\n->%s<-\n", work_buffer);
    result = NULL;
  } else {
    char *p = work_buffer + strlen("trailer");
    skip_white(&p, work_buffer + WORK_BUFFER_SIZE);
    result = parse_pdf_dict(&p, work_buffer + WORK_BUFFER_SIZE, pf);
  }

  return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int parse_xref_stream ( pdf_file pf,
long  xref_pos,
pdf_obj **  trailer 
) [static]

Definition at line 2684 of file pdfobj.c.

{
  pdf_obj *xrefstm, *size_obj, *W_obj, *index;
  unsigned long size;
  long length;
  int W[3], i, wsum = 0;
  const char *p;

  xrefstm = pdf_read_object(0, 0, pf, xref_pos, pf->file_size);
  if (!PDF_OBJ_STREAMTYPE(xrefstm))
    goto error;

  {
    pdf_obj *tmp = pdf_stream_uncompress(xrefstm);
    if (!tmp)
      goto error;
    pdf_release_obj(xrefstm);
    xrefstm = tmp;
  }

  *trailer = pdf_link_obj(pdf_stream_dict(xrefstm));

  size_obj = pdf_lookup_dict(*trailer, "Size");
  if (!PDF_OBJ_NUMBERTYPE(size_obj))
    goto error;
  size = (unsigned long) pdf_number_value(size_obj);

  length = pdf_stream_length(xrefstm);

  W_obj = pdf_lookup_dict(*trailer, "W");
  if (!PDF_OBJ_ARRAYTYPE(W_obj) || pdf_array_length(W_obj) != 3)
    goto error;

  for (i = 0; i < 3; i++) {
    pdf_obj *tmp = pdf_get_array(W_obj, i);
    if (!PDF_OBJ_NUMBERTYPE(tmp))
      goto error;
    wsum += (W[i] = (int) pdf_number_value(tmp));
  }

  p = pdf_stream_dataptr(xrefstm);

  index = pdf_lookup_dict(*trailer, "Index");
  if (index) {
    unsigned int index_len;
    if (!PDF_OBJ_ARRAYTYPE(index) ||
       ((index_len = pdf_array_length(index)) % 2 ))
      goto error;

    i = 0;
    while (i < index_len) {
      pdf_obj *first = pdf_get_array(index, i++);
      pdf_obj *size  = pdf_get_array(index, i++);
      if (!PDF_OBJ_NUMBERTYPE(first) ||
         !PDF_OBJ_NUMBERTYPE(size) ||
         parse_xrefstm_subsec(pf, &p, &length, W, wsum,
                            (long) pdf_number_value(first),
                            (long) pdf_number_value(size)))
       goto error;
    }
  } else if (parse_xrefstm_subsec(pf, &p, &length, W, wsum, 0, size))
      goto error;

  if (length)
    WARN("Garbage in xref stream.");

  pdf_release_obj(xrefstm);

  return 1;

 error:
  WARN("Cannot parse cross-reference stream.");
  if (xrefstm)
    pdf_release_obj(xrefstm);
  if (*trailer) {
    pdf_release_obj(*trailer);
    *trailer = NULL;
  }
  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int parse_xref_table ( pdf_file pf,
long  xref_pos 
) [static]

Definition at line 2553 of file pdfobj.c.

{
  FILE         *pdf_input_file = pf->file;
  unsigned long first, size;
  unsigned long i, offset;
  unsigned int  obj_gen;
  char          flag;
  int           r;

  /*
   * This routine reads one xref segment. It may be called multiple times
   * on the same file.  xref tables sometimes come in pieces.
   */

  seek_absolute(pf->file, xref_pos);

  mfgets(work_buffer, WORK_BUFFER_SIZE, pdf_input_file);
  if (memcmp(work_buffer, "xref", strlen("xref"))) {
    /* Might be an xref stream and not an xref table */
    return 0;
  }
  /* Next line in file has first item and size of table */
  for (;;) {
    unsigned long current_pos;

    current_pos = tell_position(pdf_input_file);
    if (mfgets(work_buffer, WORK_BUFFER_SIZE, pdf_input_file) == NULL) {
      WARN("Premature end of PDF file while parsing xref table.");
      return -1;
    }
    if (!strncmp(work_buffer, "trailer", strlen ("trailer"))) {
      /*
       * Backup... This is ugly, but it seems like the safest thing to
       * do.  It is possible the trailer dictionary starts on the same
       * logical line as the word trailer.  In that case, the mfgets
       * call might have started to read the trailer dictionary and
       * parse_trailer would fail.
       */
      seek_absolute(pdf_input_file, current_pos);
      break;
    }
    sscanf(work_buffer, "%lu %lu", &first, &size);
    if (pf->num_obj < first + size) {
      extend_xref(pf, first + size);
    }

    for (i = first; i < first + size; i++) {
      fread(work_buffer, sizeof(char), 20, pdf_input_file);
      /*
       * Don't overwrite positions that have already been set by a
       * modified xref table.  We are working our way backwards
       * through the reference table, so we only set "position" 
       * if it hasn't been set yet.
       */
      work_buffer[19] = 0;
      offset = 0UL; obj_gen = 0; flag = 0;
      r = sscanf(work_buffer, "%010lu %05u %c", &offset, &obj_gen, &flag);
      if ( r != 3 ||
          ((flag != 'n' && flag != 'f') ||
           (flag == 'n' &&
           (offset >= pf->file_size || (offset > 0 && offset < 4))))) {
        WARN("Invalid xref table entry [%lu]. PDF file is corrupt...", i);
        return -1;
      }
      if (!pf->xref_table[i].field2) {
       pf->xref_table[i].type   = (flag == 'n');
       pf->xref_table[i].field2 = offset;
       pf->xref_table[i].field3 = obj_gen;       
      }
    }
  }

  return  1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static unsigned long parse_xrefstm_field ( const char **  p,
int  length,
unsigned long  def 
) [static]

Definition at line 2629 of file pdfobj.c.

{
  unsigned long val = 0;

  if (!length)
    return def;

  while (length--) {
    val <<= 8;
    val |= (unsigned char) *((*p)++);
  }

  return val;
}

Here is the caller graph for this function:

static int parse_xrefstm_subsec ( pdf_file pf,
const char **  p,
long *  length,
int *  W,
int  wsum,
long  first,
long  size 
) [static]

Definition at line 2645 of file pdfobj.c.

                                           {
  xref_entry *e;

  if ((*length -= wsum*size) < 0)
    return -1;

  if (pf->num_obj < first+size)
    extend_xref(pf, first+size);  /* TODO: change! why? */

  e = pf->xref_table + first;
  while (size--) {
    unsigned char  type;
    unsigned long  field2;
    unsigned short field3;

    type = (unsigned char) parse_xrefstm_field(p, W[0], 1);
    if (type > 2)
      WARN("Unknown cross-reference stream entry type.");
    else if (!W[1] || (type != 1 && !W[2]))
      return -1;

    field2 = (unsigned long)  parse_xrefstm_field(p, W[1], 0);
    field3 = (unsigned short) parse_xrefstm_field(p, W[2], 0);

    if (!e->field2) {
      e->type   = type;
      e->field2 = field2;
      e->field3 = field3;   
      }
    e++;
  }

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void pdf_add_array ( pdf_obj array,
pdf_obj object 
)

Definition at line 1234 of file pdfobj.c.

{
  pdf_array *data;

  TYPECHECK(array, PDF_ARRAY);

  data = array->data;
  if (data->size >= data->max) {
    data->max   += ARRAY_ALLOC_SIZE;
    data->values = RENEW(data->values, data->max, pdf_obj *);
  }
  data->values[data->size] = object;
  data->size++;

  return;
}

Here is the caller graph for this function:

int pdf_add_dict ( pdf_obj dict,
pdf_obj key,
pdf_obj value 
)

Definition at line 1406 of file pdfobj.c.

{
  pdf_dict *data, *new_node;

  TYPECHECK(dict, PDF_DICT);
  TYPECHECK(key,  PDF_NAME);

  /* It seems that NULL is sometimes used for null object... */
  if (value != NULL && INVALIDOBJ(value))
    ERROR("pdf_add_dict(): Passed invalid value");

  /* If this key already exists, simply replace the value */
  for (data = dict->data; data->key != NULL; data = data->next) {
    if (!strcmp(pdf_name_value(key), pdf_name_value(data->key))) {
      /* Release the old value */
      pdf_release_obj(data->value);
      /* Release the new key (we don't need it) */
      pdf_release_obj(key);
      data->value = value;
      return 1;
    }
  }
  /*
   * We didn't find the key. We build a new "end" node and add
   * the new key just before the end
   */
  new_node = NEW (1, pdf_dict);
  new_node->key = NULL;
  new_node->value = NULL;
  new_node->next = NULL;
  data->next  = new_node;
  data->key   = key;
  data->value = value;
  return 0;
}

Here is the call graph for this function:

static long pdf_add_objstm ( pdf_obj objstm,
pdf_obj object 
) [static]

Definition at line 2013 of file pdfobj.c.

{
  long *data, pos;

  TYPECHECK(objstm, PDF_STREAM);

  data = get_objstm_data(objstm);
  pos = ++data[0];

  data[2*pos]   = object->label;
  data[2*pos+1] = pdf_stream_length(objstm);

  add_xref_entry(object->label, 2, objstm->label, pos-1);
 
  /* redirect output into objstm */
  output_stream = objstm;
  enc_mode = 0;
  pdf_write_obj(object, pdf_output_file);
  pdf_out_char(pdf_output_file, '\n');
  output_stream = NULL;

  return pos;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void pdf_add_stream ( pdf_obj stream,
const void *  stream_data,
long  length 
)

Definition at line 1792 of file pdfobj.c.

{
  pdf_stream *data;

  TYPECHECK(stream, PDF_STREAM);

  if (length < 1)
    return;
  data = stream->data;
  if (data->stream_length + length > data->max_length) {
    data->max_length += length + STREAM_ALLOC_SIZE;
    data->stream      = RENEW(data->stream, data->max_length, unsigned char);
  }
  memcpy(data->stream + data->stream_length, stream_data, length);
  data->stream_length += length;
}

Here is the caller graph for this function:

unsigned int pdf_array_length ( pdf_obj array)

Definition at line 1202 of file pdfobj.c.

{
  pdf_array *data;

  TYPECHECK(array, PDF_ARRAY);

  data = (pdf_array *) array->data;

  return (unsigned int) data->size;
}

Here is the caller graph for this function:

char pdf_boolean_value ( pdf_obj object)

Definition at line 789 of file pdfobj.c.

{
  pdf_boolean *data;

  TYPECHECK(object, PDF_BOOLEAN);

  data = object->data;

  return data->value;
}

Here is the caller graph for this function:

void pdf_close ( pdf_file pf)

Definition at line 2984 of file pdfobj.c.

{
  if (pf)
    pf->file = NULL;
}

Here is the caller graph for this function:

int pdf_compare_reference ( pdf_obj ref1,
pdf_obj ref2 
)

Definition at line 3148 of file pdfobj.c.

{
  pdf_indirect *data1, *data2;

  ASSERT(PDF_OBJ_INDIRECTTYPE(ref1) && PDF_OBJ_INDIRECTTYPE(ref2));

  data1 = (pdf_indirect *) ref1->data;
  data2 = (pdf_indirect *) ref2->data;

  return data1->pf != data2->pf || data1->label != data2->label
    || data1->generation != data2->generation;
}

Here is the caller graph for this function:

int pdf_concat_stream ( pdf_obj dst,
pdf_obj src 
)

Definition at line 1854 of file pdfobj.c.

{
  const char *stream_data;
  long        stream_length;
  pdf_obj    *stream_dict;
  pdf_obj    *filter;

  if (!PDF_OBJ_STREAMTYPE(dst) || !PDF_OBJ_STREAMTYPE(src))
    ERROR("Invalid type.");

  stream_data   = pdf_stream_dataptr(src);
  stream_length = pdf_stream_length (src);
  stream_dict   = pdf_stream_dict   (src);

  if (pdf_lookup_dict(stream_dict, "DecodeParms")) {
    WARN("Streams with DecodeParams not supported.");
    return -1;
  }

  filter = pdf_lookup_dict(stream_dict, "Filter");
  if (!filter) {
    pdf_add_stream(dst, stream_data, stream_length);
    return 0;
#if HAVE_ZLIB
  } else {
    char *filter_name;
    if (PDF_OBJ_NAMETYPE(filter)) {
      filter_name = pdf_name_value(filter);
      if (filter_name && !strcmp(filter_name, "FlateDecode"))
       return pdf_add_stream_flate(dst, stream_data, stream_length);
      else {
       WARN("DecodeFilter \"%s\" not supported.", filter_name);
       return -1;
      }
    } else if (PDF_OBJ_ARRAYTYPE(filter)) {
      if (pdf_array_length(filter) > 1) {
       WARN("Multiple DecodeFilter not supported.");
       return -1;
      } else {
       filter_name = pdf_name_value(pdf_get_array(filter, 0));
       if (filter_name && !strcmp(filter_name, "FlateDecode"))
         return pdf_add_stream_flate(dst, stream_data, stream_length);
       else {
         WARN("DecodeFilter \"%s\" not supported.", filter_name);
         return -1;
       }
      }
    } else
      ERROR("Broken PDF file?");
#endif /* HAVE_ZLIB */
  }

  return -1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2510 of file pdfobj.c.

{
  int count = PDF_OBJ_MAX_DEPTH;

  if (obj)
    obj = pdf_link_obj(obj);

  while (PDF_OBJ_INDIRECTTYPE(obj) && --count) {
    pdf_file *pf = OBJ_FILE(obj);
    unsigned long  obj_num = OBJ_NUM(obj);
    unsigned short obj_gen = OBJ_GEN(obj);
    ASSERT(pf);
    pdf_release_obj(obj);
    obj = pdf_get_object(pf, obj_num, obj_gen);
  }

  if (!count)
    ERROR("Loop in object hierarchy detected. Broken PDF file?");

  if (PDF_OBJ_NULLTYPE(obj)) {
    pdf_release_obj(obj);
    return NULL;
  } else
    return obj;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1547 of file pdfobj.c.

{
  pdf_obj  *keys;
  pdf_dict *data;

  TYPECHECK(dict, PDF_DICT);

  keys = pdf_new_array();
  for (data = dict->data; (data &&
                        data->key != NULL); data = data->next) {
    /* We duplicate name object rather than linking keys.
     * If we forget to free keys, broken PDF is generated.
     */
    pdf_add_array(keys, pdf_new_name(pdf_name_value(data->key)));
  }

  return keys;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void pdf_error_cleanup ( void  )

Definition at line 473 of file pdfobj.c.

{
  /*
   * This routine is the cleanup required for an abnormal exit.
   * For now, simply close the file.
   */
  if (pdf_output_file)
    MFCLOSE(pdf_output_file);
}

Here is the caller graph for this function:

static void pdf_file_free ( pdf_file pf) [static]

Definition at line 2860 of file pdfobj.c.

{
  unsigned long i;

  if (!pf) {
    return;
  }

  for (i = 0; i < pf->num_obj; i++) {
    if (pf->xref_table[i].direct)
      pdf_release_obj(pf->xref_table[i].direct);
    if (pf->xref_table[i].indirect)
      pdf_release_obj(pf->xref_table[i].indirect);
  }

  RELEASE(pf->xref_table);
  if (pf->trailer) {
    pdf_release_obj(pf->trailer);
    pf->trailer = NULL;
  }
  if (pf->catalog) {
    pdf_release_obj(pf->catalog);
    pf->catalog = NULL;
  }

  RELEASE(pf);  
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2912 of file pdfobj.c.

{
  ASSERT(pf);
  return pf->catalog;
}

Here is the caller graph for this function:

Definition at line 2896 of file pdfobj.c.

{
  ASSERT(pf);
  return pf->version;
}

Here is the caller graph for this function:

pdf_file* pdf_file_new ( FILE *  file)

Definition at line 2841 of file pdfobj.c.

{
  pdf_file *pf;
  ASSERT(file);
  pf = NEW(1, pdf_file);
  pf->file    = file;
  pf->trailer = NULL;
  pf->xref_table = NULL;
  pf->catalog = NULL;
  pf->num_obj = 0;
  pf->version = 0;

  seek_end(file);
  pf->file_size = tell_position(file);

  return pf;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void pdf_files_close ( void  )

Definition at line 2991 of file pdfobj.c.

Here is the call graph for this function:

Here is the caller graph for this function:

void pdf_files_init ( void  )

Definition at line 2889 of file pdfobj.c.

{
  pdf_files = NEW(1, struct ht_table);
  ht_init_table(pdf_files, (void (*)(void *)) pdf_file_free);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void pdf_flush_obj ( pdf_obj object,
FILE *  file 
) [static]

Definition at line 1994 of file pdfobj.c.

{
  long length;

  /*
   * Record file position
   */
  add_xref_entry(object->label, 1,
               pdf_output_file_position, object->generation);
  length = sprintf(format_buffer, "%lu %hu obj\n", object->label, object->generation);
  enc_mode = doc_enc_mode && !(object->flags & OBJ_NO_ENCRYPT);
  pdf_enc_set_label(object->label);
  pdf_enc_set_generation(object->generation);
  pdf_out(file, format_buffer, length);
  pdf_write_obj(object, file);
  pdf_out(file, "\nendobj\n", 8);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int pdf_foreach_dict ( pdf_obj dict,
int(*)(pdf_obj *, pdf_obj *, void *)  proc,
void *  pdata 
)

Definition at line 1504 of file pdfobj.c.

{
  int       error = 0;
  pdf_dict *data;

  ASSERT(proc);

  TYPECHECK(dict, PDF_DICT);

  data = dict->data;
  while (!error &&
        data->key != NULL) {
    error = proc(data->key, data->value, pdata);
    data = data->next;
  }

  return error;
}

Here is the call graph for this function:

Here is the caller graph for this function:

pdf_obj* pdf_get_array ( pdf_obj array,
long  idx 
)

Definition at line 1184 of file pdfobj.c.

{
  pdf_obj   *result = NULL;
  pdf_array *data;

  TYPECHECK(array, PDF_ARRAY);

  data = array->data;
  if (idx < 0)
    result = data->values[idx + data->size];
  else if (idx < data->size) {
    result = data->values[idx];
  }

  return result;
}

Here is the caller graph for this function:

static pdf_obj* pdf_get_object ( pdf_file pf,
unsigned long  obj_num,
unsigned short  obj_gen 
) [static]

Definition at line 2443 of file pdfobj.c.

{
  pdf_obj *result;

  if (!checklabel(pf, obj_num, obj_gen)) {
    WARN("Trying to read nonexistent or deleted object: %lu %u",
         obj_num, obj_gen);
    return pdf_new_null();
  }

  if ((result = pf->xref_table[obj_num].direct)) {
    return pdf_link_obj(result);
  }

  if (pf->xref_table[obj_num].type == 1) {
    /* type == 1 */
    unsigned long offset;
    long limit;
    offset = pf->xref_table[obj_num].field2;
    limit  = next_object_offset(pf, obj_num);
    result = pdf_read_object(obj_num, obj_gen, pf, offset, limit);
  } else {
    /* type == 2 */
    unsigned long  objstm_num = pf->xref_table[obj_num].field2;
    unsigned short index = pf->xref_table[obj_num].field3;
    pdf_obj *objstm;
    long *data, n, first, length;
    char *p, *q;

    if (objstm_num >= pf->num_obj ||
       pf->xref_table[objstm_num].type != 1 ||
       !((objstm = pf->xref_table[objstm_num].direct) ||
         (objstm = read_objstm(pf, objstm_num))))
      goto error;

    data = get_objstm_data(objstm);
    n = *(data++);
    first = *(data++);

    if (index >= n || data[2*index] != obj_num)
      goto error;

    length = pdf_stream_length(objstm);
    p = (char *) pdf_stream_dataptr(objstm) + first + data[2*index+1];
    q = p + (index == n-1 ? length : first+data[2*index+3]);
    result = parse_pdf_object(&p, q, pf);
    if (!result)
      goto error;
  }

  /* Make sure the caller doesn't free this object */
  pf->xref_table[obj_num].direct = pdf_link_obj(result);

  return result;

 error:
  WARN("Could not read object from object stream.");
  return pdf_new_null();
}

Here is the call graph for this function:

Here is the caller graph for this function:

unsigned pdf_get_version ( void  )

Definition at line 258 of file pdfobj.c.

{
  return pdf_version;
}

Here is the caller graph for this function:

static pdf_obj* pdf_import_indirect ( pdf_obj object) [static]

Definition at line 3035 of file pdfobj.c.

{
  pdf_file *pf = OBJ_FILE(object);
  unsigned long obj_num = OBJ_NUM(object);
  unsigned short obj_gen = OBJ_GEN(object);

  pdf_obj *ref;

  ASSERT(pf);

  if (!checklabel(pf, obj_num, obj_gen)) {
    WARN("Can't resolve object: %lu %u", obj_num, obj_gen);
    return pdf_new_null();
  }

  if ((ref = pf->xref_table[obj_num].indirect)) {
    if (ref == &loop_marker)
      ERROR("Loop in object hierarchy detected. Broken PDF file?");
    return  pdf_link_obj(ref);
  } else {
    pdf_obj *obj, *tmp;

    obj = pdf_get_object(pf, obj_num, obj_gen);

    /* We mark the reference to be able to detect loops */
    pf->xref_table[obj_num].indirect = &loop_marker;

    tmp = pdf_import_object(obj);
    
    pf->xref_table[obj_num].indirect = ref = pdf_ref_obj(tmp);
    
    pdf_release_obj(tmp);
    pdf_release_obj(obj);
    
    return  pdf_link_obj(ref);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 3081 of file pdfobj.c.

{
  pdf_obj  *imported;
  pdf_obj  *tmp;
  int       i;

  switch (pdf_obj_typeof(object)) {

  case PDF_INDIRECT:
    if (OBJ_FILE(object)) {
      imported = pdf_import_indirect(object);
    } else {
      imported = pdf_link_obj(object);
    }
    break;

  case PDF_STREAM:
    {
      pdf_obj *stream_dict;

      tmp = pdf_import_object(pdf_stream_dict(object));
      if (!tmp)
       return NULL;

      imported    = pdf_new_stream(0);
      stream_dict = pdf_stream_dict(imported);
      pdf_merge_dict(stream_dict, tmp);
      pdf_release_obj(tmp);
      pdf_add_stream(imported,
                   pdf_stream_dataptr(object),
                   pdf_stream_length(object));
    }
    break;

  case PDF_DICT:

    imported = pdf_new_dict();
    if (pdf_foreach_dict(object, import_dict, imported) < 0) {
      pdf_release_obj(imported);
      return NULL;
    }

    break;

  case PDF_ARRAY:

    imported = pdf_new_array();
    for (i = 0; i < pdf_array_length(object); i++) {
      tmp = pdf_import_object(pdf_get_array(object, i));
      if (!tmp) {
       pdf_release_obj(imported);
       return NULL;
      }
      pdf_add_array(imported, tmp);
    }
    break;

  default:
    imported = pdf_link_obj(object);
  }

  return imported;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void pdf_label_obj ( pdf_obj object) [static]

Definition at line 624 of file pdfobj.c.

{
  if (INVALIDOBJ(object))
    ERROR("pdf_label_obj(): passed invalid object.");

  /*
   * Don't change label on an already labeled object. Ignore such calls.
   */
  if (object->label == 0) {
    object->label      = next_label++;
    object->generation = 0;
  }
}

Here is the caller graph for this function:

pdf_obj* pdf_link_obj ( pdf_obj object)

Definition at line 658 of file pdfobj.c.

{
  if (INVALIDOBJ(object))
    ERROR("pdf_link_obj(): passed invalid object.");

  object->refcount += 1;

  return object;
}

Here is the caller graph for this function:

pdf_obj* pdf_lookup_dict ( pdf_obj dict,
const char *  name 
)

Definition at line 1526 of file pdfobj.c.

{
  pdf_dict *data;

  ASSERT(name);

  TYPECHECK(dict, PDF_DICT);

  data = dict->data;
  while (data->key != NULL) {
    if (!strcmp(name, pdf_name_value(data->key))) {
      return data->value;
    }
    data = data->next;
  }

  return NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void pdf_merge_dict ( pdf_obj dict1,
pdf_obj dict2 
)

Definition at line 1489 of file pdfobj.c.

{
  pdf_dict *data;

  TYPECHECK(dict1, PDF_DICT);
  TYPECHECK(dict2, PDF_DICT);

  data = dict2->data;
  while (data->key != NULL) {
    pdf_add_dict(dict1, pdf_link_obj(data->key), pdf_link_obj(data->value));
    data = data->next;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

char* pdf_name_value ( pdf_obj object)

Definition at line 1129 of file pdfobj.c.

{
  pdf_name *data;

  TYPECHECK(object, PDF_NAME);

  data = object->data;

  return data->name;
}

Here is the caller graph for this function:

static int pdf_need_white ( int  type1,
int  type2 
) [static]

Definition at line 572 of file pdfobj.c.

{
  return !(type1 == PDF_STRING || type1 == PDF_ARRAY || type1 == PDF_DICT ||
          type2 == PDF_STRING || type2 == PDF_NAME ||
          type2 == PDF_ARRAY || type2 == PDF_DICT);
}

Here is the caller graph for this function:

pdf_obj* pdf_new_array ( void  )

Definition at line 1146 of file pdfobj.c.

{
  pdf_obj   *result;
  pdf_array *data;

  result = pdf_new_obj(PDF_ARRAY);
  data   = NEW(1, pdf_array);
  data->values = NULL;
  data->max    = 0;
  data->size   = 0;
  result->data = data;

  return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

pdf_obj* pdf_new_boolean ( char  value)

Definition at line 746 of file pdfobj.c.

{
  pdf_obj     *result;
  pdf_boolean *data;

  result = pdf_new_obj(PDF_BOOLEAN);
  data   = NEW(1, pdf_boolean);
  data->value  = value;
  result->data = data;

  return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

pdf_obj* pdf_new_dict ( void  )

Definition at line 1371 of file pdfobj.c.

{
  pdf_obj  *result;
  pdf_dict *data;

  result = pdf_new_obj(PDF_DICT);
  data   = NEW(1, pdf_dict);
  data->key    = NULL;
  data->value  = NULL;
  data->next   = NULL;
  result->data = data;

  return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

pdf_obj* pdf_new_indirect ( pdf_file pf,
unsigned long  obj_num,
unsigned short  obj_gen 
)

Definition at line 2267 of file pdfobj.c.

{
  pdf_obj      *result;
  pdf_indirect *indirect;

  indirect = NEW(1, pdf_indirect);
  indirect->pf         = pf;
  indirect->label      = obj_num;
  indirect->generation = obj_gen;

  result   = pdf_new_obj(PDF_INDIRECT);
  result->data = indirect;

  return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

pdf_obj* pdf_new_name ( const char *  name)

Definition at line 1034 of file pdfobj.c.

{
  pdf_obj  *result;
  unsigned  length;
  pdf_name *data;

  result = pdf_new_obj(PDF_NAME);
  data   = NEW (1, pdf_name);
  result->data = data;
  length = strlen(name);
  if (length != 0) {
    data->name = NEW(length+1, char);
    memcpy(data->name, name, length);
    data->name[length] = '\0';
  } else {
    data->name = NULL;
  }

  return result;
}

Here is the call graph for this function:

pdf_obj* pdf_new_null ( void  )

Definition at line 723 of file pdfobj.c.

{
  pdf_obj *result;

  result = pdf_new_obj(PDF_NULL);
  result->data = NULL;

  return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

pdf_obj* pdf_new_number ( double  value)

Definition at line 801 of file pdfobj.c.

{
  pdf_obj    *result;
  pdf_number *data;

  result = pdf_new_obj(PDF_NUMBER);
  data   = NEW(1, pdf_number);
  data->value  = value;
  result->data = data;

  return result;
}

Here is the call graph for this function:

static pdf_obj* pdf_new_obj ( int  type) [static]

Definition at line 596 of file pdfobj.c.

{
  pdf_obj *result;

  result = NEW(1, pdf_obj);
  result->type  = type;
  result->data  = NULL;
  result->label      = 0;
  result->generation = 0;
  result->refcount   = 1;
  result->flags      = 0;

  if (INVALIDOBJ(result))
    ERROR("Invalid object type: %d", type);

  return result;
}

Here is the caller graph for this function:

pdf_obj* pdf_new_stream ( int  flags)

Definition at line 1589 of file pdfobj.c.

{
  pdf_obj    *result;
  pdf_stream *data;

  result = pdf_new_obj(PDF_STREAM);
  data   = NEW(1, pdf_stream);
  /*
   * Although we are using an arbitrary pdf_object here, it must have
   * type=PDF_DICT and cannot be an indirect reference.  This will be
   * checked by the output routine.
   */
  data->dict   = pdf_new_dict();
  data->_flags = flags;
  data->stream = NULL;
  data->stream_length = 0;
  data->max_length    = 0;
  data->objstm_data = NULL;

  result->data = data;
  result->flags |= OBJ_NO_OBJSTM;

  return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

pdf_obj* pdf_new_string ( const void *  str,
unsigned  length 
)

Definition at line 855 of file pdfobj.c.

{
  pdf_obj    *result;
  pdf_string *data;

  ASSERT(str);

  result = pdf_new_obj(PDF_STRING);
  data   = NEW(1, pdf_string);
  result->data = data;

  data->length = length;
  data->string = NEW(length+1, unsigned char);
  memcpy(data->string, str, length);
  /* Shouldn't assume NULL terminated. */
  data->string[length] = '\0';

  return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 712 of file pdfobj.c.

{
  pdf_obj *result;

  result = pdf_new_obj(PDF_UNDEFINED);
  result->data = NULL;

  return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

double pdf_number_value ( pdf_obj object)

Definition at line 843 of file pdfobj.c.

{
  pdf_number *data;

  TYPECHECK(object, PDF_NUMBER);

  data = object->data;

  return data->value;
}

Here is the caller graph for this function:

int pdf_obj_get_verbose ( void  )

Definition at line 264 of file pdfobj.c.

{
  return verbose;
}

Here is the caller graph for this function:

void pdf_obj_set_verbose ( void  )

Definition at line 270 of file pdfobj.c.

{
  verbose++;
}
int pdf_obj_typeof ( pdf_obj object)

Definition at line 615 of file pdfobj.c.

{
  if (INVALIDOBJ(object))
    return PDF_OBJ_INVALID;

  return object->type;
}

Here is the caller graph for this function:

pdf_file* pdf_open ( const char *  ident,
FILE *  file 
)

Definition at line 2919 of file pdfobj.c.

{
  pdf_file *pf;

  ASSERT(pdf_files);

  pf = (pdf_file *) ht_lookup_table(pdf_files, ident, strlen(ident));

  if (pf) {
    pf->file = file;
  } else {
    int version;
    pdf_obj *new_version;

    version = check_for_pdf_version(file);
    if (version < 0) {
      WARN("Not a PDF file.");
      return NULL;
    }

    pf = pdf_file_new(file);
    pf->version = version;

    if (!(pf->trailer = read_xref(pf)))
      goto error;

    if (pdf_lookup_dict(pf->trailer, "Encrypt")) {
      WARN("PDF document is encrypted.");
      goto error;
    }

    pf->catalog = pdf_deref_obj(pdf_lookup_dict(pf->trailer, "Root"));
    if (!PDF_OBJ_DICTTYPE(pf->catalog)) {
      WARN("Cannot read PDF document catalog. Broken PDF file?");
      goto error;
    }

    new_version = pdf_deref_obj(pdf_lookup_dict(pf->catalog, "Version"));
    if (new_version) {
      unsigned short minor;

      if (!PDF_OBJ_NAMETYPE(new_version) ||
         sscanf(pdf_name_value(new_version), "1.%hu", &minor) != 1) {
       pdf_release_obj(new_version);
       WARN("Illegal Version entry in document catalog. Broken PDF file?");
       goto error;
      }

      if (pf->version < minor)
       pf->version = minor;

      pdf_release_obj(new_version);
    }

    ht_append_table(pdf_files, ident, strlen(ident), pf);
  }

  return pf;

 error:
  pdf_file_free(pf);
  return NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void pdf_out ( FILE *  file,
const void *  buffer,
long  length 
) [static]

Definition at line 551 of file pdfobj.c.

{
  if (output_stream && file ==  pdf_output_file)
    pdf_add_stream(output_stream, buffer, length);
  else {
    fwrite(buffer, 1, length, file);
    /* Keep tallys for xref table *only* if writing a pdf file */
    if (file == pdf_output_file) {
      pdf_output_file_position += length;
      pdf_output_line_position += length;
      /* "foo\nbar\n "... */
      if (length > 0 &&
       ((char *)buffer)[length-1] == '\n')
        pdf_output_line_position = 0;
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void pdf_out_char ( FILE *  file,
char  c 
) [static]

Definition at line 525 of file pdfobj.c.

{
  if (output_stream && file ==  pdf_output_file)
    pdf_add_stream(output_stream, &c, 1);
  else {
    fputc(c, file);
    /* Keep tallys for xref table *only* if writing a pdf file. */
    if (file == pdf_output_file) {
      pdf_output_file_position += 1;
      if (c == '\n')
        pdf_output_line_position  = 0;
      else
        pdf_output_line_position += 1;
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void pdf_out_flush ( void  )

Definition at line 419 of file pdfobj.c.

{
  if (pdf_output_file) {
    long length;

    /* Flush current object stream */
    if (current_objstm) {
      release_objstm(current_objstm);
      current_objstm =NULL;
    }

    /*
     * Label xref stream - we need the number of correct objects
     * for the xref stream dictionary (= trailer).
     * Labelling it in pdf_out_init (with 1)  does not work (why?).
     */
    if (xref_stream)
      pdf_label_obj(xref_stream);

    /* Record where this xref is for trailer */
    startxref = pdf_output_file_position;

    pdf_add_dict(trailer_dict, pdf_new_name("Size"),
               pdf_new_number(next_label));

    if (xref_stream)
      dump_xref_stream();
    else {
      dump_xref_table();
      dump_trailer_dict();
    }

    /* Done with xref table */
    RELEASE(output_xref);

    pdf_out(pdf_output_file, "startxref\n", 10);
    length = sprintf(format_buffer, "%lu\n", startxref);
    pdf_out(pdf_output_file, format_buffer, length);
    pdf_out(pdf_output_file, "%%EOF\n", 6);

    MESG("\n");
    if (verbose) {
      if (compression_level > 0) {
       MESG("Compression saved %ld bytes%s\n", compression_saved,
            pdf_version < 5 ? ". Try \"-V 5\" for better compression" : "");
      }
    }
    MESG("%ld bytes written", pdf_output_file_position);

    MFCLOSE(pdf_output_file);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void pdf_out_init ( const char *  filename,
int  do_encryption 
)

Definition at line 295 of file pdfobj.c.

{
  char v;

  output_xref = NULL;
  pdf_max_ind_objects = 0;
  add_xref_entry(0, 0, 0, 0xffff);
  next_label = 1;

  if (pdf_version >= 5) {
    xref_stream = pdf_new_stream(STREAM_COMPRESS);
    xref_stream->flags |= OBJ_NO_ENCRYPT;
    trailer_dict = pdf_stream_dict(xref_stream);
    pdf_add_dict(trailer_dict, pdf_new_name("Type"), pdf_new_name("XRef"));
    do_objstm = 1;
  } else {
    xref_stream = NULL;
    trailer_dict = pdf_new_dict();
    do_objstm = 0;
  }

  output_stream = NULL;

  pdf_output_file = MFOPEN(filename, FOPEN_WBIN_MODE);
  if (!pdf_output_file) {
    if (strlen(filename) < 128)
      ERROR("Unable to open \"%s\".", filename);
    else
      ERROR("Unable to open file.");
  }
  pdf_out(pdf_output_file, "%PDF-1.", strlen("%PDF-1."));
  v = '0' + pdf_version;
  pdf_out(pdf_output_file, &v, 1);
  pdf_out(pdf_output_file, "\n", 1);
  pdf_out(pdf_output_file, BINARY_MARKER, strlen(BINARY_MARKER));

  enc_mode = 0;
  doc_enc_mode = do_encryption;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void pdf_out_white ( FILE *  file) [static]

Definition at line 580 of file pdfobj.c.

{
  if (file == pdf_output_file && pdf_output_line_position >= 80) {
    pdf_out_char(file, '\n');
  } else {
    pdf_out_char(file, ' ');
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static pdf_obj* pdf_read_object ( unsigned long  obj_num,
unsigned short  obj_gen,
pdf_file pf,
long  offset,
long  limit 
) [static]

Definition at line 2284 of file pdfobj.c.

{
  long     length;
  char    *buffer, *p, *endptr;
  pdf_obj *result;

  length = limit - offset;

  if (length <= 0)
    return NULL;

  buffer = NEW(length + 1, char);

  seek_absolute(pf->file, offset);
  fread(buffer, sizeof(char), length, pf->file);

  p      = buffer;
  endptr = p + length;

  /* Check for obj_num and obj_gen */
  {
    char         *q = p; /* <== p */
    char         *sp;
    unsigned long n, g;

    skip_white(&q, endptr);
    sp = parse_unsigned(&q, endptr);
    if (!sp) {
      RELEASE(buffer);
      return NULL;
    }
    n = strtoul(sp, NULL, 10);
    RELEASE(sp);

    skip_white(&q, endptr);
    sp = parse_unsigned(&q, endptr);
    if (!sp) {
      RELEASE(buffer);
      return NULL;
    }
    g = strtoul(sp, NULL, 10);
    RELEASE(sp);

    if (obj_num && (n != obj_num || g != obj_gen)) {
      RELEASE(buffer);
      return NULL;
    }

    p = q; /* ==> p */
  }


  skip_white(&p, endptr);
  if (memcmp(p, "obj", strlen("obj"))) {
    WARN("Didn't find \"obj\".");
    RELEASE(buffer);
    return NULL;
  }
  p += strlen("obj");

  result = parse_pdf_object(&p, endptr, pf);

  skip_white(&p, endptr);
  if (memcmp(p, "endobj", strlen("endobj"))) {
    WARN("Didn't find \"endobj\".");
    if (result)
      pdf_release_obj(result);
    result = NULL;
  }
  RELEASE(buffer);

  return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

pdf_obj* pdf_ref_obj ( pdf_obj object)

Definition at line 670 of file pdfobj.c.

{
  if (INVALIDOBJ(object))
    ERROR("pdf_ref_obj(): passed invalid object.");
  
  if (object->refcount == 0) {
    MESG("\nTrying to refer already released object!!!\n");
    pdf_write_obj(object, stderr);
    ERROR("Cannot continue...");
  }

  if (PDF_OBJ_INDIRECTTYPE(object)) {
    return pdf_link_obj(object);
  } else {
    if (object->label == 0) {
      pdf_label_obj(object);
    }
    return pdf_new_indirect(NULL, object->label, object->generation);
  }
}

Here is the call graph for this function:

void pdf_release_obj ( pdf_obj object)

Definition at line 2074 of file pdfobj.c.

{
  if (object == NULL)
    return;
  if (INVALIDOBJ(object) || object->refcount <= 0) {
    MESG("\npdf_release_obj: object=%p, type=%d, refcount=%d\n",
        object, object->type, object->refcount);
    pdf_write_obj(object, stderr);
    ERROR("pdf_release_obj:  Called with invalid object.");
  }
  object->refcount -= 1;
  if (object->refcount == 0) {
    /*
     * Nothing is using this object so it's okay to remove it.
     * Nonzero "label" means object needs to be written before it's destroyed.
     */
    if (object->label && pdf_output_file != NULL) {
      if (!do_objstm || object->flags & OBJ_NO_OBJSTM
         || (doc_enc_mode && object->flags & OBJ_NO_ENCRYPT)
         || object->generation)
       pdf_flush_obj(object, pdf_output_file);
      else {
        if (!current_objstm) {
         long *data = NEW(2*OBJSTM_MAX_OBJS+2, long);
         data[0] = data[1] = 0;
         current_objstm = pdf_new_stream(STREAM_COMPRESS);
         set_objstm_data(current_objstm, data);
         pdf_label_obj(current_objstm);
       }
       if (pdf_add_objstm(current_objstm, object) == OBJSTM_MAX_OBJS) {
         release_objstm(current_objstm);
         current_objstm = NULL;
       }
      }
    }
    switch (object->type) {
    case PDF_BOOLEAN:
      release_boolean(object->data);
      break;
    case PDF_NULL:
      release_null(object->data);
      break;
    case PDF_NUMBER:
      release_number(object->data);
      break;
    case PDF_STRING:
      release_string(object->data);
      break;
    case PDF_NAME:
      release_name(object->data);
      break;
    case PDF_ARRAY:
      release_array(object->data);
      break;
    case PDF_DICT:
      release_dict(object->data);
      break;
    case PDF_STREAM:
      release_stream(object->data);
      break;
    case PDF_INDIRECT:
      release_indirect(object->data);
      break;
    }
    /* This might help detect freeing already freed objects */
    object->type = -1;
    object->data = NULL;
    RELEASE(object);
  }
}

Here is the call graph for this function:

void pdf_remove_dict ( pdf_obj dict,
const char *  name 
)

Definition at line 1567 of file pdfobj.c.

{
  pdf_dict *data, **data_p;

  TYPECHECK(dict, PDF_DICT);

  data   = dict->data;
  data_p = (pdf_dict **) (void *) &(dict->data);
  while (data->key != NULL) {
    if (pdf_match_name(data->key, name)) {
      pdf_release_obj(data->key);
      pdf_release_obj(data->value);
      *data_p = data->next;
      RELEASE(data);
      break;
    }
    data_p = &(data->next);
    data   = data->next;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void pdf_set_compression ( int  level)

Definition at line 227 of file pdfobj.c.

{
#ifndef   HAVE_ZLIB
  ERROR("You don't have compression compiled in. Possibly libz wasn't found by configure.");
#else
#ifndef HAVE_ZLIB_COMPRESS2
  if (level != 0) 
    WARN("Unable to set compression level -- your zlib doesn't have compress2().");
#endif
  if (level >= 0 && level <= 9) 
    compression_level = level;
  else {
    ERROR("set_compression: invalid compression level: %d", level);
  }
#endif /* !HAVE_ZLIB */

  return;
}

Here is the call graph for this function:

void pdf_set_encrypt ( pdf_obj encrypt)

Definition at line 516 of file pdfobj.c.

{
  if (pdf_add_dict(trailer_dict, pdf_new_name("Encrypt"), pdf_ref_obj(encrypt))) {
    ERROR("Encrypt object already set!");
  }
  encrypt->flags |= OBJ_NO_ENCRYPT;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void pdf_set_id ( pdf_obj id)

Definition at line 508 of file pdfobj.c.

{
  if (pdf_add_dict(trailer_dict, pdf_new_name("ID"), id)) {
    ERROR ("ID already set!");
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void pdf_set_info ( pdf_obj object)

Definition at line 500 of file pdfobj.c.

{
  if (pdf_add_dict(trailer_dict, pdf_new_name("Info"), pdf_ref_obj(object))) {
    ERROR ("Info object already set!");
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void pdf_set_number ( pdf_obj object,
double  value 
)

Definition at line 832 of file pdfobj.c.

{
  pdf_number *data;

  TYPECHECK(object, PDF_NUMBER);

  data = object->data;
  data->value = value;
}
void pdf_set_root ( pdf_obj object)

Definition at line 485 of file pdfobj.c.

{
  if (pdf_add_dict(trailer_dict, pdf_new_name("Root"), pdf_ref_obj(object))) {
    ERROR("Root object already set!");
  }
  /* Adobe Readers don't like a document catalog inside an encrypted
   * object stream, although the PDF v1.5 spec seems to allow this.
   * Note that we don't set OBJ_NO_ENCRYPT since the name dictionary in
   * a document catalog may contain strings, which should be encrypted.
   */
  if (doc_enc_mode)
    object->flags |= OBJ_NO_OBJSTM;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void pdf_set_string ( pdf_obj object,
unsigned char *  str,
unsigned  length 
)

Definition at line 1011 of file pdfobj.c.

{
  pdf_string *data;

  TYPECHECK(object, PDF_STRING);

  data = object->data;
  if (data->string != 0) {
    RELEASE(data->string);
  }
  if (length != 0) {
    data->length = length;
    data->string = NEW(length + 1, unsigned char);
    memcpy(data->string, str, length);
    data->string[length] = '\0';
  } else {
    data->length = 0;
    data->string = NULL;
  }
}
void pdf_set_version ( unsigned  version)

Definition at line 249 of file pdfobj.c.

{
  /* Don't forget to update CIDFont_stdcc_def[] in cid.c too! */
  if (version >= PDF_VERSION_MIN && version <= PDF_VERSION_MAX) {
    pdf_version = version;
  }
}

Here is the caller graph for this function:

const void* pdf_stream_dataptr ( pdf_obj stream)

Definition at line 1754 of file pdfobj.c.

{
  pdf_stream *data;

  TYPECHECK(stream, PDF_STREAM);

  data = stream->data;

  return (const void *) data->stream;
}

Here is the caller graph for this function:

Definition at line 1742 of file pdfobj.c.

{
  pdf_stream *data;

  TYPECHECK(stream, PDF_STREAM);

  data = stream->data;

  return data->dict;
}

Here is the caller graph for this function:

long pdf_stream_length ( pdf_obj stream)

Definition at line 1766 of file pdfobj.c.

{
  pdf_stream *data;

  TYPECHECK(stream, PDF_STREAM);

  data = stream->data;

  return (long) data->stream_length;
}

Here is the caller graph for this function:

static pdf_obj* pdf_stream_uncompress ( pdf_obj src) [static]

Definition at line 1910 of file pdfobj.c.

Here is the call graph for this function:

Here is the caller graph for this function:

unsigned pdf_string_length ( pdf_obj object)

Definition at line 888 of file pdfobj.c.

{
  pdf_string *data;

  TYPECHECK(object, PDF_STRING);

  data = object->data;

  return (unsigned) (data->length);
}

Here is the caller graph for this function:

void* pdf_string_value ( pdf_obj object)

Definition at line 876 of file pdfobj.c.

{
  pdf_string *data;

  TYPECHECK(object, PDF_STRING);

  data = object->data;

  return data->string;
}

Here is the caller graph for this function:

void pdf_transfer_label ( pdf_obj dst,
pdf_obj src 
)

Definition at line 643 of file pdfobj.c.

{
  ASSERT(dst && !dst->label && src);

  dst->label      = src->label;
  dst->generation = src->generation;
  src->label      = 0;
  src->generation = 0;
}

Here is the caller graph for this function:

void pdf_unshift_array ( pdf_obj array,
pdf_obj object 
)

Definition at line 1308 of file pdfobj.c.

{
  pdf_array *data;
  int        i;

  TYPECHECK(array, PDF_ARRAY);

  data = array->data;
  if (data->size >= data->max) {
    data->max   += ARRAY_ALLOC_SIZE;
    data->values = RENEW(data->values, data->max, pdf_obj *);
  }
  for (i = 0; i < data->size; i++)
    data->values[i+1] = data->values[i];
  data->values[0] = object;
  data->size++;
}

Here is the caller graph for this function:

static void pdf_write_obj ( pdf_obj object,
FILE *  file 
) [static]

Definition at line 1948 of file pdfobj.c.

{
  if (object == NULL) {
    write_null(NULL, file);
    return;
  }

  if (INVALIDOBJ(object) || PDF_OBJ_UNDEFINED(object))
    ERROR("pdf_write_obj: Invalid object, type = %d\n", object->type);

  if (file == stderr)
    fprintf(stderr, "{%d}", object->refcount);

  switch (object->type) {
  case PDF_BOOLEAN:
    write_boolean(object->data, file);
    break;
  case PDF_NUMBER:
    write_number (object->data, file);
    break;
  case PDF_STRING:
    write_string (object->data, file);
    break;
  case PDF_NAME:
    write_name(object->data, file);
    break;
  case PDF_ARRAY:
    write_array(object->data, file);
    break;
  case PDF_DICT:
    write_dict (object->data, file);
    break;
  case PDF_STREAM:
    write_stream(object->data, file);
    break;
  case PDF_NULL:
    write_null(NULL, file);
    break;
  case PDF_INDIRECT:
    write_indirect(object->data, file);
    break;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

int pdfobj_escape_str ( char *  buffer,
int  bufsize,
const unsigned char *  s,
int  len 
)

Definition at line 904 of file pdfobj.c.

{
  int result = 0;
  int i;

  for (i = 0; i < len; i++) {
    unsigned char ch;

    ch = s[i];
    if (result > bufsize - 4)
      ERROR("pdfobj_escape_str: Buffer overflow");

    /*
     * We always write three octal digits. Optimization only gives few Kb
     * smaller size for most documents when zlib compressed.
     */
    if (ch < 32 || ch > 126) {
      buffer[result++] = '\\';
#if 0
      if (i < len - 1 && !isdigit(s[i+1]))
       result += sprintf(buffer+result, "%o", ch);
      else
       result += sprintf(buffer+result, "%03o", ch);
#endif
      result += sprintf(buffer+result, "%03o", ch);
    } else {
      switch (ch) {
      case '(':
       buffer[result++] = '\\';
       buffer[result++] = '(';
       break;
      case ')':
       buffer[result++] = '\\';
       buffer[result++] = ')';
       break;
      case '\\':
       buffer[result++] = '\\';
       buffer[result++] = '\\';
       break;
      default:
       buffer[result++] = ch;
       break;
      }
    }
  }

  return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static pdf_obj* read_objstm ( pdf_file pf,
unsigned long  num 
) [static]

Definition at line 2360 of file pdfobj.c.

{
  unsigned long offset = pf->xref_table[num].field2;
  unsigned short gen = pf->xref_table[num].field3;
  long limit = next_object_offset(pf, num), n, first, *header = NULL;
  char *data, data1, *p, *q;
  int i;

  pdf_obj *objstm, *dict, *type, *n_obj, *first_obj;

  objstm = pdf_read_object(num, gen, pf, offset, limit);

  if (!PDF_OBJ_STREAMTYPE(objstm))
    goto error;

  {
    pdf_obj *tmp = pdf_stream_uncompress(objstm);
    if (!tmp)
      goto error;
    pdf_release_obj(objstm);
    objstm = tmp;
  }

  dict = pdf_stream_dict(objstm);

  type = pdf_lookup_dict(dict, "Type");
  if (!PDF_OBJ_NAMETYPE(type) ||
      strcmp(pdf_name_value(type), "ObjStm"))
    goto error;

  n_obj = pdf_lookup_dict(dict, "N");
  if (!PDF_OBJ_NUMBERTYPE(n_obj))
    goto error;
  n = (long) pdf_number_value(n_obj);

  first_obj = pdf_lookup_dict(dict, "First");
  if (!PDF_OBJ_NUMBERTYPE(first_obj))
    goto error;
  first = (long) pdf_number_value(first_obj);
  /* reject object streams without object data */
  if (first >= pdf_stream_length(objstm))
    goto error;

  header = NEW(2*(n+1), long);
  set_objstm_data(objstm, header);
  *(header++) = n;
  *(header++) = first;

  data = (char *) pdf_stream_dataptr(objstm);

  /* hack to avoid parsing beyond offset table */
  data1 = data[first];
  data[first] = 0;

  p = data;
  i = 2*n;
  while (i--) {
    *(header++) = strtoul(p, &q, 10);
    if (q == p)
      goto error;
    p = q;
  }
  data[first] = data1;

  /* Any garbage after last entry? */
  skip_white(&p, data+first);
  if (p != data+first)
    goto error;
  
  return pf->xref_table[num].direct = objstm;

 error:
  WARN("Cannot parse object stream.");
  if (objstm)
    pdf_release_obj(objstm);
  return NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static pdf_obj* read_xref ( pdf_file pf) [static]

Definition at line 2766 of file pdfobj.c.

{
  pdf_obj *trailer = NULL, *main_trailer = NULL;
  long     xref_pos;

  if (!(xref_pos = find_xref(pf->file)))
    goto error;

  while (xref_pos) {
    pdf_obj *prev;

    int res = parse_xref_table(pf, xref_pos);
    if (res > 0) {
      /* cross-reference table */
      pdf_obj *xrefstm;

      if (!(trailer = parse_trailer(pf)))
       goto error;

      if (!main_trailer)
       main_trailer = pdf_link_obj(trailer);

      if ((xrefstm = pdf_lookup_dict(trailer, "XRefStm"))) {
       pdf_obj *new_trailer = NULL;
       if (PDF_OBJ_NUMBERTYPE(xrefstm) &&
           parse_xref_stream(pf, (long) pdf_number_value(xrefstm),
                           &new_trailer))
         pdf_release_obj(new_trailer);
       else
         WARN("Skipping hybrid reference section.");
       /* Many PDF 1.5 xref streams use DecodeParms, which we cannot
          parse. This way we can use at least xref tables in hybrid
          documents. Or should we better stop parsing the file?
       */
      }

    } else if (!res && parse_xref_stream(pf, xref_pos, &trailer)) {
      /* cross-reference stream */
      if (!main_trailer)
       main_trailer = pdf_link_obj(trailer);
    } else
      goto error;

    if ((prev = pdf_lookup_dict(trailer, "Prev"))) {
      if (PDF_OBJ_NUMBERTYPE(prev))
       xref_pos = (long) pdf_number_value(prev);
      else
       goto error;
    } else
      xref_pos = 0;

    pdf_release_obj(trailer);
  }

#if 0
  if (!pdf_lookup_dict(main_trailer, "Root")) {
      WARN("Trailer doesn't have catalog. Is this a correct PDF file?");
      goto error;
    }
#endif

  return main_trailer;

 error:
  WARN("Error while parsing PDF file.");
  if (trailer)
    pdf_release_obj(trailer);
  if (main_trailer)
    pdf_release_obj(main_trailer);
  return NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void release_array ( pdf_array array) [static]

Definition at line 1214 of file pdfobj.c.

{
  unsigned long i;

  if (data->values) {
    for (i = 0; i < data->size; i++) {
      pdf_release_obj(data->values[i]);
      data->values[i] = NULL;
    }
    RELEASE(data->values);
    data->values = NULL;
  }
  RELEASE(data);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void release_boolean ( pdf_obj data) [static]

Definition at line 760 of file pdfobj.c.

{
  RELEASE (data);
}

Here is the caller graph for this function:

static void release_dict ( pdf_dict dict) [static]

Definition at line 1387 of file pdfobj.c.

{
  pdf_dict *next;

  while (data != NULL && data->key != NULL) {
    pdf_release_obj(data->key);
    pdf_release_obj(data->value);
    data->key   = NULL;
    data->value = NULL;
    next = data->next;
    RELEASE(data);
    data = next;
  }
  RELEASE(data);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void release_indirect ( pdf_indirect data) [static]

Definition at line 692 of file pdfobj.c.

{
  RELEASE(data);
}

Here is the caller graph for this function:

static void release_name ( pdf_name name) [static]

Definition at line 1095 of file pdfobj.c.

{
  if (data->name != NULL) {
    RELEASE(data->name);
    data->name = NULL;
  }
  RELEASE(data);
}

Here is the caller graph for this function:

static void release_null ( pdf_null data) [static]

Definition at line 734 of file pdfobj.c.

{
  return;
}

Here is the caller graph for this function:

static void release_number ( pdf_number number) [static]

Definition at line 815 of file pdfobj.c.

{
  RELEASE (data);
}

Here is the caller graph for this function:

static void release_objstm ( pdf_obj objstm) [static]

Definition at line 2038 of file pdfobj.c.

{
  long *data = get_objstm_data(objstm);
  long pos = data[0];
  pdf_obj *dict;
  pdf_stream *stream;
  unsigned char *old_buf;
  unsigned long old_length;
  stream = (pdf_stream *) objstm->data;

  /* Precede stream data by offset table */
  old_buf = stream->stream;
  old_length = stream->stream_length;
  /* Reserve 22 bytes for each entry (two 10 digit numbers plus two spaces) */
  stream->stream = NEW(old_length + 22*pos, unsigned char);
  stream->stream_length = 0;

  {
    long i = 2*pos, *val = data+2;
    while (i--) {
      long length = sprintf(format_buffer, "%ld ", *(val++));
      pdf_add_stream(objstm, format_buffer, length);
    }
  }

  dict = pdf_stream_dict(objstm);
  pdf_add_dict(dict, pdf_new_name("Type"), pdf_new_name("ObjStm"));
  pdf_add_dict(dict, pdf_new_name("N"), pdf_new_number(pos));
  pdf_add_dict(dict, pdf_new_name("First"), pdf_new_number(stream->stream_length));
  
  pdf_add_stream(objstm, old_buf, old_length);
  RELEASE(old_buf);
  pdf_release_obj(objstm);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void release_stream ( pdf_stream stream) [static]

Definition at line 1723 of file pdfobj.c.

{
  pdf_release_obj(stream->dict);
  stream->dict = NULL;

  if (stream->stream) {
    RELEASE(stream->stream);
    stream->stream = NULL;
  }

  if (stream->objstm_data) {
    RELEASE(stream->objstm_data);
    stream->objstm_data = NULL;
  }

  RELEASE(stream);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void release_string ( pdf_string str) [static]

Definition at line 1001 of file pdfobj.c.

{
  if (data->string != NULL) {
    RELEASE(data->string);
    data->string = NULL;
  }
  RELEASE(data);
}

Here is the caller graph for this function:

static void set_objstm_data ( pdf_obj objstm,
long *  data 
) [static]

Definition at line 1778 of file pdfobj.c.

                                              {
  TYPECHECK(objstm, PDF_STREAM);

  ((pdf_stream *) objstm->data)->objstm_data = data;
}

Here is the caller graph for this function:

static void write_array ( pdf_array array,
FILE *  file 
) [static]

Definition at line 1162 of file pdfobj.c.

{
  pdf_out_char(file, '[');
  if (array->size > 0) {
    unsigned long i;
    int type1 = PDF_UNDEFINED, type2;
    
    for (i = 0; i < array->size; i++) {
      if (array->values[i]) {
       type2 = array->values[i]->type;
       if (type1 != PDF_UNDEFINED && pdf_need_white(type1, type2))
         pdf_out_white(file);
       type1 = type2;
       pdf_write_obj(array->values[i], file);
      } else
       WARN("PDF array element #ld undefined.", i);
    }
  }
  pdf_out_char(file, ']');
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void write_boolean ( pdf_boolean data,
FILE *  file 
) [static]

Definition at line 766 of file pdfobj.c.

{
  if (data->value) {
    pdf_out(file, "true", 4);
  } else {
    pdf_out(file, "false", 5);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void write_dict ( pdf_dict dict,
FILE *  file 
) [static]

Definition at line 1349 of file pdfobj.c.

{
#if 0
  pdf_out (file, "<<\n", 3); /* dropping \n saves few kb. */
#else
  pdf_out (file, "<<", 2);
#endif
  while (dict->key != NULL) {
    pdf_write_obj(dict->key, file);
    if (pdf_need_white(PDF_NAME, (dict->value)->type)) {
      pdf_out_white(file);
    }
    pdf_write_obj(dict->value, file);
#if 0
    pdf_out_char (file, '\n'); /* removing this saves few kb. */
#endif
    dict = dict->next;
  }
  pdf_out(file, ">>", 2);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void write_indirect ( pdf_indirect indirect,
FILE *  file 
) [static]

Definition at line 698 of file pdfobj.c.

{
  long length;

  ASSERT(!indirect->pf);

  length = sprintf(format_buffer, "%lu %hu R", indirect->label, indirect->generation);
  pdf_out(file, format_buffer, length);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void write_name ( pdf_name name,
FILE *  file 
) [static]

Definition at line 1056 of file pdfobj.c.

{
  char *s;
  int i, length;

  s      = name->name;
  length = name->name ? strlen(name->name) : 0;
  /*
   * From PDF Reference, 3rd ed., p.33:
   *
   *  Beginning with PDF 1.2, any character except null (character code 0)
   *  may be included in a name by writing its 2-digit hexadecimal code,
   *  preceded bythe number sign character (#); see implementation notes 3
   *  and 4 in Appendix H. This syntax is required in order to represent
   *  any of the delimiter or white-space characters or the number sign
   *  character itself; it is recommended but not required for characters
   *  whose codes are outside the range 33 (!) to 126 (~).
   */
#ifndef is_delim
  /* Avoid '{' and '}' for PostScript compatibility? */
#define is_delim(c) ((c) == '(' || (c) == '/' || \
                     (c) == '<' || (c) == '>' || \
                     (c) == '[' || (c) == ']' || \
                     (c) == '{' || (c) == '}' || \
                     (c) == '%')
#endif
  pdf_out_char(file, '/');
  for (i = 0; i < length; i++) {
    if (s[i] < '!' || s[i] > '~' || s[i] == '#' || is_delim(s[i])) {
      /*     ^ "space" is here. */
      pdf_out_char (file, '#');
      pdf_out_xchar(file, s[i]);
    } else {
      pdf_out_char (file, s[i]);
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void write_null ( pdf_null data,
FILE *  file 
) [static]

Definition at line 740 of file pdfobj.c.

{
  pdf_out(file, "null", 4);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void write_number ( pdf_number number,
FILE *  file 
) [static]

Definition at line 821 of file pdfobj.c.

{
  int count;

  count = pdf_sprint_number(format_buffer, number->value);

  pdf_out(file, format_buffer, count);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void write_stream ( pdf_stream stream,
FILE *  file 
) [static]

Definition at line 1615 of file pdfobj.c.

{
  unsigned char *filtered;
  unsigned long  filtered_length;
  unsigned long  buffer_length;
  unsigned char *buffer;

  /*
   * Always work from a copy of the stream. All filters read from
   * "filtered" and leave their result in "filtered".
   */
#if 0
  filtered = NEW(stream->stream_length + 1, unsigned char);
#endif
  filtered = NEW(stream->stream_length, unsigned char);
  memcpy(filtered, stream->stream, stream->stream_length);
  filtered_length = stream->stream_length;

#if 0
  if (stream->stream_length < 10)
    stream->_flags &= ^STREAM_COMPRESS;
#endif

#ifdef HAVE_ZLIB
  /* Apply compression filter if requested */
  if (stream->stream_length > 0 &&
      (stream->_flags & STREAM_COMPRESS) &&
      compression_level > 0) {

    pdf_obj *filters = pdf_lookup_dict(stream->dict, "Filter");

    buffer_length = filtered_length + filtered_length/1000 + 14;
    buffer = NEW(buffer_length, unsigned char);
    {
      pdf_obj *filter_name = pdf_new_name("FlateDecode");

      if (filters)
        /*
         * FlateDecode is the first filter to be applied to the stream.
         */
        pdf_unshift_array(filters, filter_name);
      else
        /*
         * Adding the filter as a name instead of a one-element array
         * is crucial because otherwise Adobe Reader cannot read the
         * cross-reference stream any more, cf. the PDF v1.5 Errata.
         */
        pdf_add_dict(stream->dict, pdf_new_name("Filter"), filter_name);
    }
#ifdef HAVE_ZLIB_COMPRESS2    
    if (compress2(buffer, &buffer_length, filtered,
                filtered_length, compression_level)) {
      ERROR("Zlib error");
    }
#else 
    if (compress(buffer, &buffer_length, filtered,
               filtered_length)) {
      ERROR ("Zlib error");
    }
#endif /* HAVE_ZLIB_COMPRESS2 */
    RELEASE(filtered);
    compression_saved += filtered_length - buffer_length
      - (filters ? strlen("/FlateDecode "): strlen("/Filter/FlateDecode\n"));

    filtered        = buffer;
    filtered_length = buffer_length;
  }
#endif /* HAVE_ZLIB */

#if 0
  /*
   * An optional end-of-line marker preceding the "endstream" is
   * not part of stream data. See, PDF Reference 4th ed., p. 38.
   */
  /* Add a '\n' if the last character wasn't one */
  if (filtered_length > 0 &&
      filtered[filtered_length-1] != '\n') {
    filtered[filtered_length] = '\n';
    filtered_length++;
  }
#endif
  pdf_add_dict(stream->dict,
              pdf_new_name("Length"), pdf_new_number(filtered_length));

  pdf_write_obj(stream->dict, file);

  pdf_out(file, "\nstream\n", 8);

  if (enc_mode)
    pdf_encrypt_data(filtered, filtered_length);

  if (filtered_length > 0) {
    pdf_out(file, filtered, filtered_length);
  }
  RELEASE(filtered);

  /*
   * This stream length "object" gets reset every time write_stream is
   * called for the stream object.
   * If this stream gets written more than once with different
   * filters, this could be a problem.
   */

  pdf_out(file, "\n", 1);
  pdf_out(file, "endstream", 9);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void write_string ( pdf_string str,
FILE *  file 
) [static]

Definition at line 954 of file pdfobj.c.

{
  unsigned char *s;
  char wbuf[FORMAT_BUF_SIZE]; /* Shouldn't use format_buffer[]. */
  int  nescc = 0, i, count;

  s = str->string;

  if (enc_mode)
    pdf_encrypt_data(s, str->length);

  /*
   * Count all ASCII non-printable characters.
   */
  for (i = 0; i < str->length; i++) {
    if (!isprint(s[i]))
      nescc++;
  }
  /*
   * If the string contains much escaped chars, then we write it as
   * ASCII hex string.
   */
  if (nescc > str->length / 3) {
    pdf_out_char(file, '<');
    for (i = 0; i < str->length; i++) {
      pdf_out_xchar(file, s[i]);
    }
    pdf_out_char(file, '>');
  } else {
    pdf_out_char(file, '(');
    /*
     * This section of code probably isn't speed critical.  Escaping the
     * characters in the string one at a time may seem slow, but it's
     * safe if the formatted string length exceeds FORMAT_BUF_SIZE.
     * Occasionally you see some long strings in PDF.  pdfobj_escape_str
     * is also used for strings of text with no kerning.  These must be
     * handled as quickly as possible since there are so many of them.
     */ 
    for (i = 0; i < str->length; i++) {
      count = pdfobj_escape_str(wbuf, FORMAT_BUF_SIZE, &(s[i]), 1);
      pdf_out(file, wbuf, count);
    }
    pdf_out_char(file, ')');
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

char compression_level = 9 [static]

Definition at line 224 of file pdfobj.c.

long compression_saved = 0 [static]

Definition at line 138 of file pdfobj.c.

pdf_obj* current_objstm = NULL [static]

Definition at line 275 of file pdfobj.c.

int do_objstm [static]

Definition at line 276 of file pdfobj.c.

int doc_enc_mode [static]

Definition at line 176 of file pdfobj.c.

int enc_mode [static]

Definition at line 175 of file pdfobj.c.

Definition at line 141 of file pdfobj.c.

pdf_obj loop_marker = { PDF_OBJ_INVALID, 0, 0, 0, 0, NULL } [static]

Definition at line 3032 of file pdfobj.c.

unsigned long next_label [static]

Definition at line 155 of file pdfobj.c.

Definition at line 170 of file pdfobj.c.

Definition at line 152 of file pdfobj.c.

struct ht_table* pdf_files = NULL [static]

Definition at line 2838 of file pdfobj.c.

unsigned long pdf_max_ind_objects [static]

Definition at line 154 of file pdfobj.c.

FILE* pdf_output_file = NULL [static]

Definition at line 134 of file pdfobj.c.

long pdf_output_file_position = 0 [static]

Definition at line 136 of file pdfobj.c.

long pdf_output_line_position = 0 [static]

Definition at line 137 of file pdfobj.c.

unsigned pdf_version = PDF_VERSION_DEFAULT [static]

Definition at line 246 of file pdfobj.c.

unsigned long startxref [static]

Definition at line 157 of file pdfobj.c.

pdf_obj* trailer_dict [static]

Definition at line 178 of file pdfobj.c.

int verbose = 0 [static]

Definition at line 223 of file pdfobj.c.

pdf_obj* xref_stream [static]

Definition at line 179 of file pdfobj.c.