shithub: pdffs

ref: d613b76a67a6dbb4d2c16a17e6994e7bdf2731df
dir: /pdf.h/

View raw version
enum {
	Obool,   /* 7.3.2 */
	Onum,    /* 7.3.3 */
	Ostr,    /* 7.3.4 */
	Oname,   /* 7.3.5 */
	Oarray,  /* 7.3.6 */
	Odict,   /* 7.3.7 */
	Ostream, /* 7.3.8 */
	Onull,   /* 7.3.9 */
	Oindir,  /* 7.3.10 */

	Xusual = 0,
	Xuncompressed,
	Xcompressed,
};

typedef struct Buffer Buffer;
typedef struct Filter Filter;
typedef struct KeyValue KeyValue;
typedef struct Object Object;
typedef struct Pdf Pdf;
typedef struct Stream Stream;
typedef struct Xref Xref;
#pragma incomplete Filter

#pragma varargck type "T" Object*
#pragma varargck type "⊗" Xref

struct Buffer {
	uchar *b;
	int ro;
	int maxsz;
	int sz;
	int off;
	int eof;
};

struct Filter {
	char *name;
	int (*readall)(void *aux, Buffer *bi, Buffer *bo);
	int (*open)(Filter *f, Object *o);
	void (*close)(Filter *f);
	void *aux;
};

struct Object {
	int type;
	int ref;
	Pdf *pdf;
	union {
		int bool;
		double num;
		struct {
			char *str;
			int len;
		};
		char *name;

		struct {
			u32int id;
			u16int gen;
		}indir;

		struct {
			KeyValue *kv;
			int nkv;
		}dict;

		struct {
			Object **e;
			int ne;
		}array;

		struct {
			KeyValue *kv;
			int nkv;
			u32int len; /* packed */
			u32int off;
		}stream;
	};
};

struct KeyValue {
	char *key;
	Object *value;
};

struct Pdf {
	Biobuf *bio;
	Xref *xref;
	int nxref; /* 7.5.4 xref subsection number of objects */

	Object *root; /* 7.7.2 root object */
	Object *info; /* 14.3.3 info dictionary */
};

struct Xref {
	u32int id;
	union{
		u32int off;
		u32int objnum;
	};
	u16int gen;
	u16int type;
};

struct Stream {
	Buffer buf;
	Biobuf *bio;
};

extern Object null;

Pdf *pdfopen(Biobuf *b);
void pdfclose(Pdf *pdf);

/*
 * Parse an object.
 */
Object *pdfobj(Pdf *pdf, Biobuf *bio);

/*
 * Deallocate the object and all its children. Refcount is
 * considered.
 */
void pdfobjfree(Object *o);

/*
 * Return a resolved object or &null if can't. Operation is
 * not recursive, ie values of a dictionary won't be resolved
 * automatically.
 */
Object *pdfeval(Object **o);

/*
 * Increment refcount of an object. Freeing an object (or its
 * parent) decrements ref count.
 */
Object *pdfref(Object *o);

/*
 * Returns 1 if the character is whitespace. 0 otherwise.
 * See 7.2.2.
 */
int isws(int c);

/*
 * Returns 1 if the character is a delimiter. 0 otherwise.
 * See 7.2.2.
 */
int isdelim(int c);

int arraylen(Object *o);
Object *arrayget(Object *o, int i);
int arrayint(Object *o, int i);

Object *dictget(Object *o, char *name);
vlong dictint(Object *o, char *name);
char *dictstring(Object *o, char *name);
Object *dictdict(Object *o, char *name);
int dictints(Object *o, char *name, int *el, int nel);

Stream *streamopen(Object *o);
int streamsize(Stream *s);
void streamclose(Stream *s);

Filter *filteropen(char *name, Object *o);
int filterrun(Filter *f, Buffer *bi, Buffer *bo);
void filterclose(Filter *f);

void bufinit(Buffer *b, uchar *d, int sz);
void buffree(Buffer *b);
int bufeof(Buffer *b);
int bufleft(Buffer *b);
uchar *bufdata(Buffer *b, int *sz);
int bufreadn(Buffer *b, Biobuf *bio, int sz);
int bufput(Buffer *b, uchar *d, int sz);
int bufget(Buffer *b, uchar *d, int sz);
void bufdump(Buffer *b);