From f6e4a9614978334ca4a8e212bb8b44f34ac94ce2 Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Sun, 10 Apr 2011 00:11:25 +0200 Subject: Make fz_obj struct opaque. --- fitz/base_object.c | 802 ++++++++++++++++++++++++++++++++++++++++++++++++++ fitz/fitz.h | 63 +--- fitz/obj_array.c | 155 ---------- fitz/obj_dict.c | 282 ------------------ fitz/obj_print.c | 14 +- fitz/obj_simple.c | 324 -------------------- pdf/pdf_crypt.c | 4 +- pdf/pdf_type3.c | 8 +- pdf/pdf_xref.c | 5 +- win32/libmupdf.vcproj | 16 +- 10 files changed, 830 insertions(+), 843 deletions(-) create mode 100644 fitz/base_object.c delete mode 100644 fitz/obj_array.c delete mode 100644 fitz/obj_dict.c delete mode 100644 fitz/obj_simple.c diff --git a/fitz/base_object.c b/fitz/base_object.c new file mode 100644 index 00000000..5c20767a --- /dev/null +++ b/fitz/base_object.c @@ -0,0 +1,802 @@ +#include "fitz.h" + +typedef enum fz_objkind_e +{ + FZ_NULL, + FZ_BOOL, + FZ_INT, + FZ_REAL, + FZ_STRING, + FZ_NAME, + FZ_ARRAY, + FZ_DICT, + FZ_INDIRECT +} fz_objkind; + +struct keyval +{ + fz_obj *k; + fz_obj *v; +}; + +struct fz_obj_s +{ + int refs; + fz_objkind kind; + union + { + int b; + int i; + float f; + struct { + unsigned short len; + char buf[1]; + } s; + char n[1]; + struct { + int len; + int cap; + fz_obj **items; + } a; + struct { + char sorted; + int len; + int cap; + struct keyval *items; + } d; + struct { + int num; + int gen; + struct pdf_xref_s *xref; + } r; + } u; +}; + +static fz_obj *fz_resolve_indirect_null(fz_obj *ref) +{ + return ref; +} + +fz_obj* (*fz_resolve_indirect)(fz_obj*) = fz_resolve_indirect_null; + +fz_obj * +fz_new_null(void) +{ + fz_obj *obj = fz_malloc(sizeof(fz_obj)); + obj->refs = 1; + obj->kind = FZ_NULL; + return obj; +} + +fz_obj * +fz_new_bool(int b) +{ + fz_obj *obj = fz_malloc(sizeof(fz_obj)); + obj->refs = 1; + obj->kind = FZ_BOOL; + obj->u.b = b; + return obj; +} + +fz_obj * +fz_new_int(int i) +{ + fz_obj *obj = fz_malloc(sizeof(fz_obj)); + obj->refs = 1; + obj->kind = FZ_INT; + obj->u.i = i; + return obj; +} + +fz_obj * +fz_new_real(float f) +{ + fz_obj *obj = fz_malloc(sizeof(fz_obj)); + obj->refs = 1; + obj->kind = FZ_REAL; + obj->u.f = f; + return obj; +} + +fz_obj * +fz_new_string(char *str, int len) +{ + fz_obj *obj = fz_malloc(offsetof(fz_obj, u.s.buf) + len + 1); + obj->refs = 1; + obj->kind = FZ_STRING; + obj->u.s.len = len; + memcpy(obj->u.s.buf, str, len); + obj->u.s.buf[len] = '\0'; + return obj; +} + +fz_obj * +fz_new_name(char *str) +{ + fz_obj *obj = fz_malloc(offsetof(fz_obj, u.n) + strlen(str) + 1); + obj->refs = 1; + obj->kind = FZ_NAME; + strcpy(obj->u.n, str); + return obj; +} + +fz_obj * +fz_new_indirect(int num, int gen, void *xref) +{ + fz_obj *obj = fz_malloc(sizeof(fz_obj)); + obj->refs = 1; + obj->kind = FZ_INDIRECT; + obj->u.r.num = num; + obj->u.r.gen = gen; + obj->u.r.xref = xref; + return obj; +} + +fz_obj * +fz_keep_obj(fz_obj *obj) +{ + assert(obj != NULL); + obj->refs ++; + return obj; +} + +int fz_is_indirect(fz_obj *obj) +{ + return obj ? obj->kind == FZ_INDIRECT : 0; +} + +int fz_is_null(fz_obj *obj) +{ + obj = fz_resolve_indirect(obj); + return obj ? obj->kind == FZ_NULL : 0; +} + +int fz_is_bool(fz_obj *obj) +{ + obj = fz_resolve_indirect(obj); + return obj ? obj->kind == FZ_BOOL : 0; +} + +int fz_is_int(fz_obj *obj) +{ + obj = fz_resolve_indirect(obj); + return obj ? obj->kind == FZ_INT : 0; +} + +int fz_is_real(fz_obj *obj) +{ + obj = fz_resolve_indirect(obj); + return obj ? obj->kind == FZ_REAL : 0; +} + +int fz_is_string(fz_obj *obj) +{ + obj = fz_resolve_indirect(obj); + return obj ? obj->kind == FZ_STRING : 0; +} + +int fz_is_name(fz_obj *obj) +{ + obj = fz_resolve_indirect(obj); + return obj ? obj->kind == FZ_NAME : 0; +} + +int fz_is_array(fz_obj *obj) +{ + obj = fz_resolve_indirect(obj); + return obj ? obj->kind == FZ_ARRAY : 0; +} + +int fz_is_dict(fz_obj *obj) +{ + obj = fz_resolve_indirect(obj); + return obj ? obj->kind == FZ_DICT : 0; +} + +int fz_to_bool(fz_obj *obj) +{ + obj = fz_resolve_indirect(obj); + if (fz_is_bool(obj)) + return obj->u.b; + return 0; +} + +int fz_to_int(fz_obj *obj) +{ + obj = fz_resolve_indirect(obj); + if (fz_is_int(obj)) + return obj->u.i; + if (fz_is_real(obj)) + return obj->u.f; + return 0; +} + +float fz_to_real(fz_obj *obj) +{ + obj = fz_resolve_indirect(obj); + if (fz_is_real(obj)) + return obj->u.f; + if (fz_is_int(obj)) + return obj->u.i; + return 0; +} + +char *fz_to_name(fz_obj *obj) +{ + obj = fz_resolve_indirect(obj); + if (fz_is_name(obj)) + return obj->u.n; + return ""; +} + +char *fz_to_str_buf(fz_obj *obj) +{ + obj = fz_resolve_indirect(obj); + if (fz_is_string(obj)) + return obj->u.s.buf; + return ""; +} + +int fz_to_str_len(fz_obj *obj) +{ + obj = fz_resolve_indirect(obj); + if (fz_is_string(obj)) + return obj->u.s.len; + return 0; +} + +/* for use by pdf_crypt_obj_imp to decrypt AES string in place */ +void fz_set_str_len(fz_obj *obj, int newlen) +{ + obj = fz_resolve_indirect(obj); + if (fz_is_string(obj)) + if (newlen < obj->u.s.len) + obj->u.s.len = newlen; +} + +int fz_to_num(fz_obj *obj) +{ + if (fz_is_indirect(obj)) + return obj->u.r.num; + return 0; +} + +int fz_to_gen(fz_obj *obj) +{ + if (fz_is_indirect(obj)) + return obj->u.r.gen; + return 0; +} + +void *fz_get_indirect_xref(fz_obj *obj) +{ + if (fz_is_indirect(obj)) + return obj->u.r.xref; + return NULL; +} + +int +fz_objcmp(fz_obj *a, fz_obj *b) +{ + int i; + + if (a == b) + return 0; + + if (!a || !b) + return 1; + + if (a->kind != b->kind) + return 1; + + switch (a->kind) + { + case FZ_NULL: + return 0; + + case FZ_BOOL: + return a->u.b - b->u.b; + + case FZ_INT: + return a->u.i - b->u.i; + + case FZ_REAL: + if (a->u.f < b->u.f) + return -1; + if (a->u.f > b->u.f) + return 1; + return 0; + + case FZ_STRING: + if (a->u.s.len < b->u.s.len) + { + if (memcmp(a->u.s.buf, b->u.s.buf, a->u.s.len) <= 0) + return -1; + return 1; + } + if (a->u.s.len > b->u.s.len) + { + if (memcmp(a->u.s.buf, b->u.s.buf, b->u.s.len) >= 0) + return 1; + return -1; + } + return memcmp(a->u.s.buf, b->u.s.buf, a->u.s.len); + + case FZ_NAME: + return strcmp(a->u.n, b->u.n); + + case FZ_INDIRECT: + if (a->u.r.num == b->u.r.num) + return a->u.r.gen - b->u.r.gen; + return a->u.r.num - b->u.r.num; + + case FZ_ARRAY: + if (a->u.a.len != b->u.a.len) + return a->u.a.len - b->u.a.len; + for (i = 0; i < a->u.a.len; i++) + if (fz_objcmp(a->u.a.items[i], b->u.a.items[i])) + return 1; + return 0; + + case FZ_DICT: + if (a->u.d.len != b->u.d.len) + return a->u.d.len - b->u.d.len; + for (i = 0; i < a->u.d.len; i++) + { + if (fz_objcmp(a->u.d.items[i].k, b->u.d.items[i].k)) + return 1; + if (fz_objcmp(a->u.d.items[i].v, b->u.d.items[i].v)) + return 1; + } + return 0; + + } + return 1; +} + +static char * +fz_objkindstr(fz_obj *obj) +{ + if (obj == NULL) + return ""; + switch (obj->kind) + { + case FZ_NULL: return "null"; + case FZ_BOOL: return "boolean"; + case FZ_INT: return "integer"; + case FZ_REAL: return "real"; + case FZ_STRING: return "string"; + case FZ_NAME: return "name"; + case FZ_ARRAY: return "array"; + case FZ_DICT: return "dictionary"; + case FZ_INDIRECT: return "reference"; + } + return ""; +} + +fz_obj * +fz_new_array(int initialcap) +{ + fz_obj *obj; + int i; + + obj = fz_malloc(sizeof(fz_obj)); + obj->refs = 1; + obj->kind = FZ_ARRAY; + + obj->u.a.len = 0; + obj->u.a.cap = initialcap > 1 ? initialcap : 6; + + obj->u.a.items = fz_calloc(obj->u.a.cap, sizeof(fz_obj*)); + for (i = 0; i < obj->u.a.cap; i++) + obj->u.a.items[i] = NULL; + + return obj; +} + +fz_obj * +fz_copy_array(fz_obj *obj) +{ + fz_obj *new; + int i; + + if (fz_is_indirect(obj) || !fz_is_array(obj)) + fz_warn("assert: not an array (%s)", fz_objkindstr(obj)); + + new = fz_new_array(fz_array_len(obj)); + for (i = 0; i < fz_array_len(obj); i++) + fz_array_push(new, fz_array_get(obj, i)); + + return new; +} + +int +fz_array_len(fz_obj *obj) +{ + obj = fz_resolve_indirect(obj); + if (!fz_is_array(obj)) + return 0; + return obj->u.a.len; +} + +fz_obj * +fz_array_get(fz_obj *obj, int i) +{ + obj = fz_resolve_indirect(obj); + + if (!fz_is_array(obj)) + return NULL; + + if (i < 0 || i >= obj->u.a.len) + return NULL; + + return obj->u.a.items[i]; +} + +void +fz_array_put(fz_obj *obj, int i, fz_obj *item) +{ + obj = fz_resolve_indirect(obj); + + if (!fz_is_array(obj)) + fz_warn("assert: not an array (%s)", fz_objkindstr(obj)); + else if (i < 0) + fz_warn("assert: index %d < 0", i); + else if (i >= obj->u.a.len) + fz_warn("assert: index %d > length %d", i, obj->u.a.len); + else + { + if (obj->u.a.items[i]) + fz_drop_obj(obj->u.a.items[i]); + obj->u.a.items[i] = fz_keep_obj(item); + } +} + +void +fz_array_push(fz_obj *obj, fz_obj *item) +{ + obj = fz_resolve_indirect(obj); + + if (!fz_is_array(obj)) + fz_warn("assert: not an array (%s)", fz_objkindstr(obj)); + else + { + if (obj->u.a.len + 1 > obj->u.a.cap) + { + int i; + obj->u.a.cap = (obj->u.a.cap * 3) / 2; + obj->u.a.items = fz_realloc(obj->u.a.items, obj->u.a.cap, sizeof(fz_obj*)); + for (i = obj->u.a.len ; i < obj->u.a.cap; i++) + obj->u.a.items[i] = NULL; + } + obj->u.a.items[obj->u.a.len] = fz_keep_obj(item); + obj->u.a.len++; + } +} + +void +fz_array_insert(fz_obj *obj, fz_obj *item) +{ + obj = fz_resolve_indirect(obj); + + if (!fz_is_array(obj)) + fz_warn("assert: not an array (%s)", fz_objkindstr(obj)); + else + { + if (obj->u.a.len + 1 > obj->u.a.cap) + { + int i; + obj->u.a.cap = (obj->u.a.cap * 3) / 2; + obj->u.a.items = fz_realloc(obj->u.a.items, obj->u.a.cap, sizeof(fz_obj*)); + for (i = obj->u.a.len ; i < obj->u.a.cap; i++) + obj->u.a.items[i] = NULL; + } + memmove(obj->u.a.items + 1, obj->u.a.items, obj->u.a.len * sizeof(fz_obj*)); + obj->u.a.items[0] = fz_keep_obj(item); + obj->u.a.len++; + } +} + +/* dicts may only have names as keys! */ + +static int keyvalcmp(const void *ap, const void *bp) +{ + const struct keyval *a = ap; + const struct keyval *b = bp; + return strcmp(fz_to_name(a->k), fz_to_name(b->k)); +} + +fz_obj * +fz_new_dict(int initialcap) +{ + fz_obj *obj; + int i; + + obj = fz_malloc(sizeof(fz_obj)); + obj->refs = 1; + obj->kind = FZ_DICT; + + obj->u.d.sorted = 1; + obj->u.d.len = 0; + obj->u.d.cap = initialcap > 1 ? initialcap : 10; + + obj->u.d.items = fz_calloc(obj->u.d.cap, sizeof(struct keyval)); + for (i = 0; i < obj->u.d.cap; i++) + { + obj->u.d.items[i].k = NULL; + obj->u.d.items[i].v = NULL; + } + + return obj; +} + +fz_obj * +fz_copy_dict(fz_obj *obj) +{ + fz_obj *new; + int i; + + if (fz_is_indirect(obj) || !fz_is_dict(obj)) + fz_throw("assert: not a dict (%s)", fz_objkindstr(obj)); + + new = fz_new_dict(fz_dict_len(obj)); + for (i = 0; i < fz_dict_len(obj); i++) + fz_dict_put(new, fz_dict_get_key(obj, i), fz_dict_get_val(obj, i)); + + return new; +} + +int +fz_dict_len(fz_obj *obj) +{ + obj = fz_resolve_indirect(obj); + if (!fz_is_dict(obj)) + return 0; + return obj->u.d.len; +} + +fz_obj * +fz_dict_get_key(fz_obj *obj, int i) +{ + obj = fz_resolve_indirect(obj); + + if (!fz_is_dict(obj)) + return NULL; + + if (i < 0 || i >= obj->u.d.len) + return NULL; + + return obj->u.d.items[i].k; +} + +fz_obj * +fz_dict_get_val(fz_obj *obj, int i) +{ + obj = fz_resolve_indirect(obj); + + if (!fz_is_dict(obj)) + return NULL; + + if (i < 0 || i >= obj->u.d.len) + return NULL; + + return obj->u.d.items[i].v; +} + +static int +fz_dict_finds(fz_obj *obj, char *key) +{ + if (obj->u.d.sorted) + { + int l = 0; + int r = obj->u.d.len - 1; + while (l <= r) + { + int m = (l + r) >> 1; + int c = -strcmp(fz_to_name(obj->u.d.items[m].k), key); + if (c < 0) + r = m - 1; + else if (c > 0) + l = m + 1; + else + return m; + } + } + + else + { + int i; + for (i = 0; i < obj->u.d.len; i++) + if (strcmp(fz_to_name(obj->u.d.items[i].k), key) == 0) + return i; + } + + return -1; +} + +fz_obj * +fz_dict_gets(fz_obj *obj, char *key) +{ + int i; + + obj = fz_resolve_indirect(obj); + + if (!fz_is_dict(obj)) + return NULL; + + i = fz_dict_finds(obj, key); + if (i >= 0) + return obj->u.d.items[i].v; + + return NULL; +} + +fz_obj * +fz_dict_get(fz_obj *obj, fz_obj *key) +{ + if (fz_is_name(key)) + return fz_dict_gets(obj, fz_to_name(key)); + return NULL; +} + +fz_obj * +fz_dict_getsa(fz_obj *obj, char *key, char *abbrev) +{ + fz_obj *v; + v = fz_dict_gets(obj, key); + if (v) + return v; + return fz_dict_gets(obj, abbrev); +} + +void +fz_dict_put(fz_obj *obj, fz_obj *key, fz_obj *val) +{ + char *s; + int i; + + obj = fz_resolve_indirect(obj); + + if (!fz_is_dict(obj)) + { + fz_warn("assert: not a dict (%s)", fz_objkindstr(obj)); + return; + } + + if (fz_is_name(key)) + s = fz_to_name(key); + else + { + fz_warn("assert: key is not a name (%s)", fz_objkindstr(obj)); + return; + } + + if (!val) + { + fz_warn("assert: val does not exist for key (%s)", s); + return; + } + + i = fz_dict_finds(obj, s); + if (i >= 0) + { + fz_drop_obj(obj->u.d.items[i].v); + obj->u.d.items[i].v = fz_keep_obj(val); + return; + } + + if (obj->u.d.len + 1 > obj->u.d.cap) + { + obj->u.d.cap = (obj->u.d.cap * 3) / 2; + obj->u.d.items = fz_realloc(obj->u.d.items, obj->u.d.cap, sizeof(struct keyval)); + for (i = obj->u.d.len; i < obj->u.d.cap; i++) + { + obj->u.d.items[i].k = NULL; + obj->u.d.items[i].v = NULL; + } + } + + /* borked! */ + if (obj->u.d.len) + if (strcmp(fz_to_name(obj->u.d.items[obj->u.d.len - 1].k), s) > 0) + obj->u.d.sorted = 0; + + obj->u.d.items[obj->u.d.len].k = fz_keep_obj(key); + obj->u.d.items[obj->u.d.len].v = fz_keep_obj(val); + obj->u.d.len ++; +} + +void +fz_dict_puts(fz_obj *obj, char *key, fz_obj *val) +{ + fz_obj *keyobj = fz_new_name(key); + fz_dict_put(obj, keyobj, val); + fz_drop_obj(keyobj); +} + +void +fz_dict_dels(fz_obj *obj, char *key) +{ + obj = fz_resolve_indirect(obj); + + if (!fz_is_dict(obj)) + fz_warn("assert: not a dict (%s)", fz_objkindstr(obj)); + else + { + int i = fz_dict_finds(obj, key); + if (i >= 0) + { + fz_drop_obj(obj->u.d.items[i].k); + fz_drop_obj(obj->u.d.items[i].v); + obj->u.d.sorted = 0; + obj->u.d.items[i] = obj->u.d.items[obj->u.d.len-1]; + obj->u.d.len --; + } + } +} + +void +fz_dict_del(fz_obj *obj, fz_obj *key) +{ + if (fz_is_name(key)) + fz_dict_dels(obj, fz_to_name(key)); + else + fz_warn("assert: key is not a name (%s)", fz_objkindstr(obj)); +} + +void +fz_sort_dict(fz_obj *obj) +{ + obj = fz_resolve_indirect(obj); + if (!fz_is_dict(obj)) + return; + if (!obj->u.d.sorted) + { + qsort(obj->u.d.items, obj->u.d.len, sizeof(struct keyval), keyvalcmp); + obj->u.d.sorted = 1; + } +} + +static void +fz_free_array(fz_obj *obj) +{ + int i; + + for (i = 0; i < obj->u.a.len; i++) + if (obj->u.a.items[i]) + fz_drop_obj(obj->u.a.items[i]); + + fz_free(obj->u.a.items); + fz_free(obj); +} + +static void +fz_free_dict(fz_obj *obj) +{ + int i; + + for (i = 0; i < obj->u.d.len; i++) { + if (obj->u.d.items[i].k) + fz_drop_obj(obj->u.d.items[i].k); + if (obj->u.d.items[i].v) + fz_drop_obj(obj->u.d.items[i].v); + } + + fz_free(obj->u.d.items); + fz_free(obj); +} + +void +fz_drop_obj(fz_obj *obj) +{ + assert(obj != NULL); + if (--obj->refs == 0) + { + if (obj->kind == FZ_ARRAY) + fz_free_array(obj); + else if (obj->kind == FZ_DICT) + fz_free_dict(obj); + else + fz_free(obj); + } +} diff --git a/fitz/fitz.h b/fitz/fitz.h index 7de81c42..15ac5e28 100644 --- a/fitz/fitz.h +++ b/fitz/fitz.h @@ -348,61 +348,6 @@ void aes_crypt_cbc( fz_aes *ctx, int mode, int length, */ typedef struct fz_obj_s fz_obj; -typedef struct fz_keyval_s fz_keyval; - -struct pdf_xref_s; - -typedef enum fz_objkind_e -{ - FZ_NULL, - FZ_BOOL, - FZ_INT, - FZ_REAL, - FZ_STRING, - FZ_NAME, - FZ_ARRAY, - FZ_DICT, - FZ_INDIRECT -} fz_objkind; - -struct fz_keyval_s -{ - fz_obj *k; - fz_obj *v; -}; - -struct fz_obj_s -{ - int refs; - fz_objkind kind; - union - { - int b; - int i; - float f; - struct { - unsigned short len; - char buf[1]; - } s; - char n[1]; - struct { - int len; - int cap; - fz_obj **items; - } a; - struct { - char sorted; - int len; - int cap; - fz_keyval *items; - } d; - struct { - int num; - int gen; - struct pdf_xref_s *xref; - } r; - } u; -}; extern fz_obj* (*fz_resolve_indirect)(fz_obj*); @@ -435,7 +380,7 @@ int fz_is_indirect(fz_obj *obj); int fz_objcmp(fz_obj *a, fz_obj *b); -/* silent failure, no error reporting */ +/* safe, silent failure, no error reporting */ int fz_to_bool(fz_obj *obj); int fz_to_int(fz_obj *obj); float fz_to_real(fz_obj *obj); @@ -449,7 +394,6 @@ int fz_array_len(fz_obj *array); fz_obj *fz_array_get(fz_obj *array, int i); void fz_array_put(fz_obj *array, int i, fz_obj *obj); void fz_array_push(fz_obj *array, fz_obj *obj); -void fz_array_drop(fz_obj *array); void fz_array_insert(fz_obj *array, fz_obj *obj); int fz_dict_len(fz_obj *dict); @@ -468,7 +412,8 @@ int fz_fprint_obj(FILE *fp, fz_obj *obj, int tight); void fz_debug_obj(fz_obj *obj); void fz_debug_ref(fz_obj *obj); -char *fz_objkindstr(fz_obj *obj); +void fz_set_str_len(fz_obj *obj, int newlen); /* private */ +void *fz_get_indirect_xref(fz_obj *obj); /* private */ /* * Data buffers. @@ -804,7 +749,7 @@ struct fz_font_s fz_buffer **t3procs; /* has 256 entries if used */ float *t3widths; /* has 256 entries if used */ void *t3xref; /* a pdf_xref for the callback */ - fz_error (*t3run)(struct pdf_xref_s *xref, fz_obj *resources, fz_buffer *contents, + fz_error (*t3run)(void *xref, fz_obj *resources, fz_buffer *contents, struct fz_device_s *dev, fz_matrix ctm); fz_rect bbox; diff --git a/fitz/obj_array.c b/fitz/obj_array.c deleted file mode 100644 index d6ffb687..00000000 --- a/fitz/obj_array.c +++ /dev/null @@ -1,155 +0,0 @@ -#include "fitz.h" - -fz_obj * -fz_new_array(int initialcap) -{ - fz_obj *obj; - int i; - - obj = fz_malloc(sizeof(fz_obj)); - obj->refs = 1; - obj->kind = FZ_ARRAY; - - obj->u.a.len = 0; - obj->u.a.cap = initialcap > 1 ? initialcap : 6; - - obj->u.a.items = fz_calloc(obj->u.a.cap, sizeof(fz_obj*)); - for (i = 0; i < obj->u.a.cap; i++) - obj->u.a.items[i] = NULL; - - return obj; -} - -fz_obj * -fz_copy_array(fz_obj *obj) -{ - fz_obj *new; - int i; - - if (fz_is_indirect(obj) || !fz_is_array(obj)) - fz_warn("assert: not an array (%s)", fz_objkindstr(obj)); - - new = fz_new_array(fz_array_len(obj)); - for (i = 0; i < fz_array_len(obj); i++) - fz_array_push(new, fz_array_get(obj, i)); - - return new; -} - -int -fz_array_len(fz_obj *obj) -{ - obj = fz_resolve_indirect(obj); - if (!fz_is_array(obj)) - return 0; - return obj->u.a.len; -} - -fz_obj * -fz_array_get(fz_obj *obj, int i) -{ - obj = fz_resolve_indirect(obj); - - if (!fz_is_array(obj)) - return NULL; - - if (i < 0 || i >= obj->u.a.len) - return NULL; - - return obj->u.a.items[i]; -} - -void -fz_array_put(fz_obj *obj, int i, fz_obj *item) -{ - obj = fz_resolve_indirect(obj); - - if (!fz_is_array(obj)) - fz_warn("assert: not an array (%s)", fz_objkindstr(obj)); - else if (i < 0) - fz_warn("assert: index %d < 0", i); - else if (i >= obj->u.a.len) - fz_warn("assert: index %d > length %d", i, obj->u.a.len); - else - { - if (obj->u.a.items[i]) - fz_drop_obj(obj->u.a.items[i]); - obj->u.a.items[i] = fz_keep_obj(item); - } -} - -void -fz_array_push(fz_obj *obj, fz_obj *item) -{ - obj = fz_resolve_indirect(obj); - - if (!fz_is_array(obj)) - fz_warn("assert: not an array (%s)", fz_objkindstr(obj)); - else - { - if (obj->u.a.len + 1 > obj->u.a.cap) - { - int i; - obj->u.a.cap = (obj->u.a.cap * 3) / 2; - obj->u.a.items = fz_realloc(obj->u.a.items, obj->u.a.cap, sizeof(fz_obj*)); - for (i = obj->u.a.len ; i < obj->u.a.cap; i++) - obj->u.a.items[i] = NULL; - } - obj->u.a.items[obj->u.a.len] = fz_keep_obj(item); - obj->u.a.len++; - } -} - -void -fz_array_drop(fz_obj *obj) -{ - obj = fz_resolve_indirect(obj); - - if (!fz_is_array(obj)) - fz_warn("assert: not an array (%s)", fz_objkindstr(obj)); - else - { - if (obj->u.a.len > 0) - { - fz_drop_obj(obj->u.a.items[--obj->u.a.len]); - } - } -} - -void -fz_array_insert(fz_obj *obj, fz_obj *item) -{ - obj = fz_resolve_indirect(obj); - - if (!fz_is_array(obj)) - fz_warn("assert: not an array (%s)", fz_objkindstr(obj)); - else - { - if (obj->u.a.len + 1 > obj->u.a.cap) - { - int i; - obj->u.a.cap = (obj->u.a.cap * 3) / 2; - obj->u.a.items = fz_realloc(obj->u.a.items, obj->u.a.cap, sizeof(fz_obj*)); - for (i = obj->u.a.len ; i < obj->u.a.cap; i++) - obj->u.a.items[i] = NULL; - } - memmove(obj->u.a.items + 1, obj->u.a.items, obj->u.a.len * sizeof(fz_obj*)); - obj->u.a.items[0] = fz_keep_obj(item); - obj->u.a.len++; - } -} - -void -fz_free_array(fz_obj *obj) -{ - int i; - - assert(obj->kind == FZ_ARRAY); - - for (i = 0; i < obj->u.a.len; i++) - if (obj->u.a.items[i]) - fz_drop_obj(obj->u.a.items[i]); - - fz_free(obj->u.a.items); - fz_free(obj); -} diff --git a/fitz/obj_dict.c b/fitz/obj_dict.c deleted file mode 100644 index d165f46d..00000000 --- a/fitz/obj_dict.c +++ /dev/null @@ -1,282 +0,0 @@ -#include "fitz.h" - -/* dicts may only have names as keys! */ - -static int keyvalcmp(const void *ap, const void *bp) -{ - const fz_keyval *a = ap; - const fz_keyval *b = bp; - return strcmp(fz_to_name(a->k), fz_to_name(b->k)); -} - -fz_obj * -fz_new_dict(int initialcap) -{ - fz_obj *obj; - int i; - - obj = fz_malloc(sizeof(fz_obj)); - obj->refs = 1; - obj->kind = FZ_DICT; - - obj->u.d.sorted = 1; - obj->u.d.len = 0; - obj->u.d.cap = initialcap > 1 ? initialcap : 10; - - obj->u.d.items = fz_calloc(obj->u.d.cap, sizeof(fz_keyval)); - for (i = 0; i < obj->u.d.cap; i++) - { - obj->u.d.items[i].k = NULL; - obj->u.d.items[i].v = NULL; - } - - return obj; -} - -fz_obj * -fz_copy_dict(fz_obj *obj) -{ - fz_obj *new; - int i; - - if (fz_is_indirect(obj) || !fz_is_dict(obj)) - fz_throw("assert: not a dict (%s)", fz_objkindstr(obj)); - - new = fz_new_dict(fz_dict_len(obj)); - for (i = 0; i < fz_dict_len(obj); i++) - fz_dict_put(new, fz_dict_get_key(obj, i), fz_dict_get_val(obj, i)); - - return new; -} - -int -fz_dict_len(fz_obj *obj) -{ - obj = fz_resolve_indirect(obj); - if (!fz_is_dict(obj)) - return 0; - return obj->u.d.len; -} - -fz_obj * -fz_dict_get_key(fz_obj *obj, int i) -{ - obj = fz_resolve_indirect(obj); - - if (!fz_is_dict(obj)) - return NULL; - - if (i < 0 || i >= obj->u.d.len) - return NULL; - - return obj->u.d.items[i].k; -} - -fz_obj * -fz_dict_get_val(fz_obj *obj, int i) -{ - obj = fz_resolve_indirect(obj); - - if (!fz_is_dict(obj)) - return NULL; - - if (i < 0 || i >= obj->u.d.len) - return NULL; - - return obj->u.d.items[i].v; -} - -static int -fz_dict_finds(fz_obj *obj, char *key) -{ - if (obj->u.d.sorted) - { - int l = 0; - int r = obj->u.d.len - 1; - while (l <= r) - { - int m = (l + r) >> 1; - int c = -strcmp(fz_to_name(obj->u.d.items[m].k), key); - if (c < 0) - r = m - 1; - else if (c > 0) - l = m + 1; - else - return m; - } - } - - else - { - int i; - for (i = 0; i < obj->u.d.len; i++) - if (strcmp(fz_to_name(obj->u.d.items[i].k), key) == 0) - return i; - } - - return -1; -} - -fz_obj * -fz_dict_gets(fz_obj *obj, char *key) -{ - int i; - - obj = fz_resolve_indirect(obj); - - if (!fz_is_dict(obj)) - return NULL; - - i = fz_dict_finds(obj, key); - if (i >= 0) - return obj->u.d.items[i].v; - - return NULL; -} - -fz_obj * -fz_dict_get(fz_obj *obj, fz_obj *key) -{ - if (fz_is_name(key)) - return fz_dict_gets(obj, fz_to_name(key)); - return NULL; -} - -fz_obj * -fz_dict_getsa(fz_obj *obj, char *key, char *abbrev) -{ - fz_obj *v; - v = fz_dict_gets(obj, key); - if (v) - return v; - return fz_dict_gets(obj, abbrev); -} - -void -fz_dict_put(fz_obj *obj, fz_obj *key, fz_obj *val) -{ - char *s; - int i; - - obj = fz_resolve_indirect(obj); - - if (!fz_is_dict(obj)) - { - fz_warn("assert: not a dict (%s)", fz_objkindstr(obj)); - return; - } - - if (fz_is_name(key)) - s = fz_to_name(key); - else - { - fz_warn("assert: key is not a name (%s)", fz_objkindstr(obj)); - return; - } - - if (!val) - { - fz_warn("assert: val does not exist for key (%s)", s); - return; - } - - i = fz_dict_finds(obj, s); - if (i >= 0) - { - fz_drop_obj(obj->u.d.items[i].v); - obj->u.d.items[i].v = fz_keep_obj(val); - return; - } - - if (obj->u.d.len + 1 > obj->u.d.cap) - { - obj->u.d.cap = (obj->u.d.cap * 3) / 2; - obj->u.d.items = fz_realloc(obj->u.d.items, obj->u.d.cap, sizeof(fz_keyval)); - for (i = obj->u.d.len; i < obj->u.d.cap; i++) - { - obj->u.d.items[i].k = NULL; - obj->u.d.items[i].v = NULL; - } - } - - /* borked! */ - if (obj->u.d.len) - if (strcmp(fz_to_name(obj->u.d.items[obj->u.d.len - 1].k), s) > 0) - obj->u.d.sorted = 0; - - obj->u.d.items[obj->u.d.len].k = fz_keep_obj(key); - obj->u.d.items[obj->u.d.len].v = fz_keep_obj(val); - obj->u.d.len ++; -} - -void -fz_dict_puts(fz_obj *obj, char *key, fz_obj *val) -{ - fz_obj *keyobj = fz_new_name(key); - fz_dict_put(obj, keyobj, val); - fz_drop_obj(keyobj); -} - -void -fz_dict_dels(fz_obj *obj, char *key) -{ - obj = fz_resolve_indirect(obj); - - if (!fz_is_dict(obj)) - fz_warn("assert: not a dict (%s)", fz_objkindstr(obj)); - else - { - int i = fz_dict_finds(obj, key); - if (i >= 0) - { - fz_drop_obj(obj->u.d.items[i].k); - fz_drop_obj(obj->u.d.items[i].v); - obj->u.d.sorted = 0; - obj->u.d.items[i] = obj->u.d.items[obj->u.d.len-1]; - obj->u.d.len --; - } - } -} - -void -fz_dict_del(fz_obj *obj, fz_obj *key) -{ - if (fz_is_name(key)) - fz_dict_dels(obj, fz_to_name(key)); - else - fz_warn("assert: key is not a name (%s)", fz_objkindstr(obj)); -} - -void -fz_free_dict(fz_obj *obj) -{ - int i; - - obj = fz_resolve_indirect(obj); - - if (!fz_is_dict(obj)) - return; - - for (i = 0; i < obj->u.d.len; i++) { - if (obj->u.d.items[i].k) - fz_drop_obj(obj->u.d.items[i].k); - if (obj->u.d.items[i].v) - fz_drop_obj(obj->u.d.items[i].v); - } - - fz_free(obj->u.d.items); - fz_free(obj); -} - -void -fz_sort_dict(fz_obj *obj) -{ - obj = fz_resolve_indirect(obj); - if (!fz_is_dict(obj)) - return; - if (!obj->u.d.sorted) - { - qsort(obj->u.d.items, obj->u.d.len, sizeof(fz_keyval), keyvalcmp); - obj->u.d.sorted = 1; - } -} diff --git a/fitz/obj_print.c b/fitz/obj_print.c index 3433903c..d53d888a 100644 --- a/fitz/obj_print.c +++ b/fitz/obj_print.c @@ -78,12 +78,14 @@ static inline void fmt_sep(struct fmt *fmt) static void fmt_str(struct fmt *fmt, fz_obj *obj) { + char *s = fz_to_str_buf(obj); + int n = fz_to_str_len(obj); int i, c; fmt_putc(fmt, '('); - for (i = 0; i < obj->u.s.len; i++) + for (i = 0; i < n; i++) { - c = (unsigned char) obj->u.s.buf[i]; + c = (unsigned char)s[i]; if (c == '\n') fmt_puts(fmt, "\\n"); else if (c == '\r') @@ -112,11 +114,13 @@ static void fmt_str(struct fmt *fmt, fz_obj *obj) static void fmt_hex(struct fmt *fmt, fz_obj *obj) { + char *s = fz_to_str_buf(obj); + int n = fz_to_str_len(obj); int i, b, c; fmt_putc(fmt, '<'); - for (i = 0; i < obj->u.s.len; i++) { - b = (unsigned char) obj->u.s.buf[i]; + for (i = 0; i < n; i++) { + b = (unsigned char) s[i]; c = (b >> 4) & 0x0f; fmt_putc(fmt, c < 0xA ? c + '0' : c + 'A' - 0xA); c = (b) & 0x0f; @@ -258,7 +262,7 @@ static void fmt_obj(struct fmt *fmt, fz_obj *obj) else if (c >= 127) added += 3; } - if (added < obj->u.s.len) + if (added < len) fmt_str(fmt, obj); else fmt_hex(fmt, obj); diff --git a/fitz/obj_simple.c b/fitz/obj_simple.c deleted file mode 100644 index 2dc9d686..00000000 --- a/fitz/obj_simple.c +++ /dev/null @@ -1,324 +0,0 @@ -#include "fitz.h" - -extern void fz_free_array(fz_obj *array); -extern void fz_free_dict(fz_obj *dict); - -static fz_obj *fz_resolve_indirect_null(fz_obj *ref) -{ - return ref; -} - -fz_obj* (*fz_resolve_indirect)(fz_obj*) = fz_resolve_indirect_null; - -fz_obj * -fz_new_null(void) -{ - fz_obj *o = fz_malloc(sizeof(fz_obj)); - o->refs = 1; - o->kind = FZ_NULL; - return o; -} - -fz_obj * -fz_new_bool(int b) -{ - fz_obj *o = fz_malloc(sizeof(fz_obj)); - o->refs = 1; - o->kind = FZ_BOOL; - o->u.b = b; - return o; -} - -fz_obj * -fz_new_int(int i) -{ - fz_obj *o = fz_malloc(sizeof(fz_obj)); - o->refs = 1; - o->kind = FZ_INT; - o->u.i = i; - return o; -} - -fz_obj * -fz_new_real(float f) -{ - fz_obj *o = fz_malloc(sizeof(fz_obj)); - o->refs = 1; - o->kind = FZ_REAL; - o->u.f = f; - return o; -} - -fz_obj * -fz_new_string(char *str, int len) -{ - fz_obj *o = fz_malloc(offsetof(fz_obj, u.s.buf) + len + 1); - o->refs = 1; - o->kind = FZ_STRING; - o->u.s.len = len; - memcpy(o->u.s.buf, str, len); - o->u.s.buf[len] = '\0'; - return o; -} - -fz_obj * -fz_new_name(char *str) -{ - fz_obj *o = fz_malloc(offsetof(fz_obj, u.n) + strlen(str) + 1); - o->refs = 1; - o->kind = FZ_NAME; - strcpy(o->u.n, str); - return o; -} - -fz_obj * -fz_new_indirect(int num, int gen, void *xref) -{ - fz_obj *o = fz_malloc(sizeof(fz_obj)); - o->refs = 1; - o->kind = FZ_INDIRECT; - o->u.r.num = num; - o->u.r.gen = gen; - o->u.r.xref = xref; - return o; -} - -fz_obj * -fz_keep_obj(fz_obj *o) -{ - assert(o != NULL); - o->refs ++; - return o; -} - -void -fz_drop_obj(fz_obj *o) -{ - assert(o != NULL); - if (--o->refs == 0) - { - if (o->kind == FZ_ARRAY) - fz_free_array(o); - else if (o->kind == FZ_DICT) - fz_free_dict(o); - else - fz_free(o); - } -} - -int fz_is_indirect(fz_obj *obj) -{ - return obj ? obj->kind == FZ_INDIRECT : 0; -} - -int fz_is_null(fz_obj *obj) -{ - obj = fz_resolve_indirect(obj); - return obj ? obj->kind == FZ_NULL : 0; -} - -int fz_is_bool(fz_obj *obj) -{ - obj = fz_resolve_indirect(obj); - return obj ? obj->kind == FZ_BOOL : 0; -} - -int fz_is_int(fz_obj *obj) -{ - obj = fz_resolve_indirect(obj); - return obj ? obj->kind == FZ_INT : 0; -} - -int fz_is_real(fz_obj *obj) -{ - obj = fz_resolve_indirect(obj); - return obj ? obj->kind == FZ_REAL : 0; -} - -int fz_is_string(fz_obj *obj) -{ - obj = fz_resolve_indirect(obj); - return obj ? obj->kind == FZ_STRING : 0; -} - -int fz_is_name(fz_obj *obj) -{ - obj = fz_resolve_indirect(obj); - return obj ? obj->kind == FZ_NAME : 0; -} - -int fz_is_array(fz_obj *obj) -{ - obj = fz_resolve_indirect(obj); - return obj ? obj->kind == FZ_ARRAY : 0; -} - -int fz_is_dict(fz_obj *obj) -{ - obj = fz_resolve_indirect(obj); - return obj ? obj->kind == FZ_DICT : 0; -} - -int fz_to_bool(fz_obj *obj) -{ - obj = fz_resolve_indirect(obj); - if (fz_is_bool(obj)) - return obj->u.b; - return 0; -} - -int fz_to_int(fz_obj *obj) -{ - obj = fz_resolve_indirect(obj); - if (fz_is_int(obj)) - return obj->u.i; - if (fz_is_real(obj)) - return obj->u.f; - return 0; -} - -float fz_to_real(fz_obj *obj) -{ - obj = fz_resolve_indirect(obj); - if (fz_is_real(obj)) - return obj->u.f; - if (fz_is_int(obj)) - return obj->u.i; - return 0; -} - -char *fz_to_name(fz_obj *obj) -{ - obj = fz_resolve_indirect(obj); - if (fz_is_name(obj)) - return obj->u.n; - return ""; -} - -char *fz_to_str_buf(fz_obj *obj) -{ - obj = fz_resolve_indirect(obj); - if (fz_is_string(obj)) - return obj->u.s.buf; - return ""; -} - -int fz_to_str_len(fz_obj *obj) -{ - obj = fz_resolve_indirect(obj); - if (fz_is_string(obj)) - return obj->u.s.len; - return 0; -} - -int fz_to_num(fz_obj *obj) -{ - if (fz_is_indirect(obj)) - return obj->u.r.num; - return 0; -} - -int fz_to_gen(fz_obj *obj) -{ - if (fz_is_indirect(obj)) - return obj->u.r.gen; - return 0; -} - -int -fz_objcmp(fz_obj *a, fz_obj *b) -{ - int i; - - if (a == b) - return 0; - - if (!a || !b) - return 1; - - if (a->kind != b->kind) - return 1; - - switch (a->kind) - { - case FZ_NULL: - return 0; - - case FZ_BOOL: - return a->u.b - b->u.b; - - case FZ_INT: - return a->u.i - b->u.i; - - case FZ_REAL: - if (a->u.f < b->u.f) - return -1; - if (a->u.f > b->u.f) - return 1; - return 0; - - case FZ_STRING: - if (a->u.s.len < b->u.s.len) - { - if (memcmp(a->u.s.buf, b->u.s.buf, a->u.s.len) <= 0) - return -1; - return 1; - } - if (a->u.s.len > b->u.s.len) - { - if (memcmp(a->u.s.buf, b->u.s.buf, b->u.s.len) >= 0) - return 1; - return -1; - } - return memcmp(a->u.s.buf, b->u.s.buf, a->u.s.len); - - case FZ_NAME: - return strcmp(a->u.n, b->u.n); - - case FZ_INDIRECT: - if (a->u.r.num == b->u.r.num) - return a->u.r.gen - b->u.r.gen; - return a->u.r.num - b->u.r.num; - - case FZ_ARRAY: - if (a->u.a.len != b->u.a.len) - return a->u.a.len - b->u.a.len; - for (i = 0; i < a->u.a.len; i++) - if (fz_objcmp(a->u.a.items[i], b->u.a.items[i])) - return 1; - return 0; - - case FZ_DICT: - if (a->u.d.len != b->u.d.len) - return a->u.d.len - b->u.d.len; - for (i = 0; i < a->u.d.len; i++) - { - if (fz_objcmp(a->u.d.items[i].k, b->u.d.items[i].k)) - return 1; - if (fz_objcmp(a->u.d.items[i].v, b->u.d.items[i].v)) - return 1; - } - return 0; - - } - return 1; -} - -char *fz_objkindstr(fz_obj *obj) -{ - if (obj == NULL) - return ""; - switch (obj->kind) - { - case FZ_NULL: return "null"; - case FZ_BOOL: return "boolean"; - case FZ_INT: return "integer"; - case FZ_REAL: return "real"; - case FZ_STRING: return "string"; - case FZ_NAME: return "name"; - case FZ_ARRAY: return "array"; - case FZ_DICT: return "dictionary"; - case FZ_INDIRECT: return "reference"; - } - return ""; -} diff --git a/pdf/pdf_crypt.c b/pdf/pdf_crypt.c index cdf35d70..d29e756d 100644 --- a/pdf/pdf_crypt.c +++ b/pdf/pdf_crypt.c @@ -638,8 +638,8 @@ pdf_crypt_obj_imp(pdf_crypt *crypt, fz_obj *obj, unsigned char *key, int keylen) memcpy(iv, s, 16); aes_setkey_dec(&aes, key, keylen * 8); aes_crypt_cbc(&aes, AES_DECRYPT, n - 16, iv, s + 16, s); - obj->u.s.len -= 16; /* delete space used for iv */ - obj->u.s.len -= s[n - 17]; /* delete padding bytes at end */ + /* delete space used for iv and padding bytes at end */ + fz_set_str_len(obj, n - 16 - s[n - 17]); } } } diff --git a/pdf/pdf_type3.c b/pdf/pdf_type3.c index ac2c56bc..1d851ebe 100644 --- a/pdf/pdf_type3.c +++ b/pdf/pdf_type3.c @@ -1,6 +1,12 @@ #include "fitz.h" #include "mupdf.h" +static fz_error +pdf_run_glyph_func(void *xref, fz_obj *rdb, fz_buffer *contents, fz_device *dev, fz_matrix ctm) +{ + return pdf_run_glyph(xref, rdb, contents, dev, ctm); +} + fz_error pdf_load_type3_font(pdf_font_desc **fontdescp, pdf_xref *xref, fz_obj *rdb, fz_obj *dict) { @@ -117,7 +123,7 @@ pdf_load_type3_font(pdf_font_desc **fontdescp, pdf_xref *xref, fz_obj *rdb, fz_o fz_warn("no resource dictionary for type 3 font!"); fontdesc->font->t3xref = xref; - fontdesc->font->t3run = pdf_run_glyph; + fontdesc->font->t3run = pdf_run_glyph_func; /* CharProcs */ diff --git a/pdf/pdf_xref.c b/pdf/pdf_xref.c index c5943d64..60b0f2d6 100644 --- a/pdf/pdf_xref.c +++ b/pdf/pdf_xref.c @@ -683,11 +683,10 @@ pdf_debug_xref(pdf_xref *xref) printf("xref\n0 %d\n", xref->len); for (i = 0; i < xref->len; i++) { - printf("%05d: %010d %05d %c (refs=%d, stm_ofs=%d)\n", i, + printf("%05d: %010d %05d %c (stm_ofs=%d)\n", i, xref->table[i].ofs, xref->table[i].gen, xref->table[i].type ? xref->table[i].type : '-', - xref->table[i].obj ? xref->table[i].obj->refs : 0, xref->table[i].stm_ofs); } } @@ -873,7 +872,7 @@ pdf_resolve_indirect(fz_obj *ref) { if (fz_is_indirect(ref)) { - pdf_xref *xref = ref->u.r.xref; + pdf_xref *xref = fz_get_indirect_xref(ref); int num = fz_to_num(ref); int gen = fz_to_gen(ref); if (xref) diff --git a/win32/libmupdf.vcproj b/win32/libmupdf.vcproj index 6785335c..41f10f81 100644 --- a/win32/libmupdf.vcproj +++ b/win32/libmupdf.vcproj @@ -290,6 +290,10 @@ RelativePath="..\fitz\base_memory.c" > + + @@ -370,22 +374,10 @@ RelativePath="..\fitz\fitz.h" > - - - - - - -- cgit v1.2.3