void pdf_doc_trailer_free(pdf_trailer * tr) { // really done while (tr) { pdf_trailer *last; if (tr->info) { pdf_info_free(tr->info); pdf_free(tr->info); } if (tr->encrypt) { pdf_encrypt_free(tr->encrypt); } if (tr->id[0]) pdf_free(tr->id[0]); if (tr->id[1]) pdf_free(tr->id[1]); last = tr->last; pdf_free(tr); tr = last; } }
// Remove a single obj void pdf_obj_delete(pdf_obj *o) { if (!o) return; switch(o->t) { case eDict: dict_free(o->value.d.dict); break; case eString: case eHexString: pdf_free(o->value.s.buf); break; case eName: #ifndef HASHMAP pdf_free(o->value.k); #endif break; case eArray: free_array(o); break; default: break; } }
pdf_stream* pdf_ostream_filtered_open(pdf_filterkind f, int n, int g, void *priv) { pdf_stream_filtered *s; pdf_filter *filt; s = (pdf_stream_filtered*)pdf_malloc(sizeof(pdf_stream_filtered)); if (!s) return 0; memset(s, 0, sizeof(pdf_stream_filtered)); s->write = pdf_ostream_filtered_write; s->close = pdf_ostream_filtered_close; s->flush = pdf_ostream_filtered_flush; switch (f) { case FlateEncode: if (pdf_deflate_new(&filt) != pdf_ok) { pdf_free(s); s = 0; break; } s->filter = filt; break; case RC4Encrypt: if (pdf_filter_rc4_e_new(&filt, n, g, priv) != pdf_ok) { pdf_free(s); s = 0; } else { s->filter = filt; } break; break; case AESEncrypt: if (pdf_filter_aes_e_new(&filt, n, g, priv) != pdf_ok) { pdf_free(s); s = 0; } else { s->filter = filt; } break; default: break; } return (pdf_stream*)s; }
void pdf_doc_done(pdf_doc *d) { int i; if (!d) return; for (i = 0; i < d->count; i++) { pdf_page_free(d->pages[i]); } pdf_doc_trailer_free(d->trailer); pdf_free(d->pages); pdf_ocproperties_free(d->ocproperties); pdf_free(d); }
static int pdf_stream_buffer_close(pdf_stream *bs) { pdf_buffer_stream *s = (pdf_buffer_stream*)bs; stream_buffer *p = s->buf; while (p) { stream_buffer *t = p->next; pdf_free(p->buf); pdf_free(p); p = t; } return 0; }
pdf_err pdf_extgstate_free(pdf_extgstate*g) { if (!g) return pdf_ok; pdf_free(g); return pdf_ok; }
void entry_name_free(void *e) { if (e) pdf_free(e); else printf("!?\n"); }
// public api pdf_err pdf_resources_free(pdf_resources *r) { if (!r) return pdf_ok; pdf_free(r); return pdf_ok; }
static void dict_free_val(char *key, void *val, void *x) { extern void pdf_obj_delete(void *); pdf_obj_delete(val); if (val) pdf_free(val); }
void pdf_interpreter_free(pdf_interp_state *i) { if (i) { pdf_font_free(i->font); pdf_free(i); } }
int pdf_stream_close(pdf_stream *s) { int stat; stat = s->close(s); pdf_free(s); return stat; }
void pdf_map_delete(pdf_map *m) { pdf_map *t = m; while (m) { t = m->next; pdf_free(m); m = t; } }
static int pdf_ostream_filtered_close(pdf_stream *sf) { pdf_stream_filtered *s = (pdf_stream_filtered*)sf; pdf_filter *f = s->filter; f->close(f, 0); pdf_free(f); s->filter = 0; return 0; }
pdf_err pdf_annots_free(pdf_annots *a) { pdf_annots *t; while (a) { t = a->next; pdf_free(a); a = t; } return pdf_ok; }
pdf_err pdf_stream_free(pdf_stream *s, int flag) { pdf_filter *f; if (!s) return pdf_ok; if (s->length) { f = s->ffilter; PDF_FILTER_CLOSE(f, flag); } pdf_free(s); return pdf_ok; }
void dict_free(dict* d) { if (d) { if (d->dict) { #ifdef TSTC tstc_call(d->dict, 0, dict_entry_free, 0); tstc_free(d->dict); #elif defined (HASHMAP) extern void pdf_obj_delete(void *); hash_map_entry *e; hash_map_iterator *i = hash_map_front(d->dict); while (!hash_map_iterator_at_end(i)) { e = hash_map_iterator_get(i); pdf_obj_delete(e->v); pdf_free(e->v); hash_map_iterator_next(i); } hash_map_iterator_free(i); hash_map_free(d->dict); #else tst_print_reset(1); tst_traverse(d->dict, dict_free_val, NULL); tst_cleanup(d->dict); tst_print_reset(-1); #endif } if (d->stream) { pdf_free(d->stream); } pdf_free(d); } return; }
void dict_entry_free(char *k, void *v, void *a) { dict_entry *e = (dict_entry*)v; if (e) { e->f(e->k); if (e->v) { dict_free_val(0, e->v, 0); } pdf_free(e); } }
void free_array(pdf_obj *o) { if (o && o->t == eArray) { int i; for (i = 0; i < o->value.a.len; i++) { pdf_obj_delete(&o->value.a.items[i]); } if (o->value.a.len) pdf_free(o->value.a.items); //else if (o->value.a.items) // pdf_free(o->value.a.items); } }
int pdf_obj_insert(int n, int gen, void *d) { pdf_map *m = pdf_map_insert(n, gen); pdf_obj *o = NULL; if (o = pdf_obj_find(n, gen)) { char buf[128]; sprintf(buf, "Duplicated object (%d,%d) is found, old one is removed!\n", n, gen); DMSG(buf); pdf_obj_delete(o); pdf_free(o); } bpt_insert(m->head, n, d); return 0; }
static void pdf_encrypt_free(pdf_encrypt *encrypt) { if (!encrypt) return; if (encrypt->filter) pdf_free(encrypt->filter); if (encrypt->subfilter) pdf_free(encrypt->subfilter); if (encrypt->stmf) pdf_free(encrypt->stmf); if (encrypt->strf) pdf_free(encrypt->strf); if (encrypt->eff) pdf_free(encrypt->eff); // to free CF if (encrypt->cf) pdf_free(encrypt->cf); // free this pdf_free(encrypt); }
static void pdf_info_free(pdf_info *info) { if (!info) return; if (info->title) { pdf_obj_delete(info->title); free(info->title); } if (info->author) { pdf_obj_delete(info->author); pdf_free(info->author); } if (info->subject) { pdf_obj_delete(info->subject); pdf_free(info->subject); } if (info->keywords) { pdf_obj_delete(info->keywords); pdf_free(info->keywords); } if (info->creator) { pdf_obj_delete(info->creator); pdf_free(info->creator); } if (info->producer) { pdf_obj_delete(info->producer); pdf_free(info->producer); } if (info->trapped) { pdf_obj_delete(info->trapped); pdf_free(info->trapped); } if (info->creationdate) pdf_free(info->creationdate); if (info->moddate) pdf_free(info->moddate); }
pdf_err pdf_page_free(pdf_page *page) { if (!page) return pdf_ok; if (page->resources) { pdf_resources_free(page->resources); } if (page->annots) { pdf_annots_free(page->annots); } if (page->group) { pdf_group_free(page->group); } pdf_free(page); return pdf_ok; }
void pdf_obj_free() { pdf_map * m = parser_inst->map;//&a_pdf_map; pdf_map *i = m; if (!parser_inst && !parser_inst->map) return; for (; i != 0; i = i->next) { /* delete obj tree nodes */ bpt_delete_node(i->head, (leaf_action)pdf_obj_delete); } i = m; for (; i!=0; i=i->next) { /* delete obj tree */ bpt_destroy(i->head); pdf_free(i->head); } }
// returned object belongs to caller. // Experimental: using list as target by imitating "LISP" style. dict_list* dict_to_list(dict *d) { dict_list *l = pdf_malloc(sizeof(dict_list)); l->next = l->last = NULL; l->val.t = eLimit; if (d && d->dict) { #ifdef TSTC char buf[1024]; tstc_call(d->dict, buf, dict_list_append, l); #elif defined (HASHMAP) hash_map_iterator *i = hash_map_front(d->dict); hash_map_entry *e; while (!hash_map_iterator_at_end(i)) { e = hash_map_iterator_get(i); dict_list_append((char*)e->k, e->v, l); hash_map_iterator_next(i); } hash_map_iterator_free(i); #else tst_print_reset(1); tst_traverse(d->dict, (tst_hook)dict_list_append, l); tst_print_reset(-1); #endif } if (l->val.t == eLimit) { pdf_free(l); l = NULL; } return l; }
pdf_err pdf_group_free(pdf_group *g) { pdf_free(g); return pdf_ok; }
pdf_err pdf_istream_filtered_load(pdf_obj* o, void *crypto, int numobj, int numgen, pdf_stream **stm) { pdf_err e = pdf_ok; pdf_filter *last = NULL, *raw = NULL, *crypt = NULL; pdf_stream *s = 0; sub_stream *ss; pdf_obj *x, *xx; int m, mm; decode_params *dp = 0; *stm = 0; if (o && o->t == eRef) { numobj = o->value.r.num; numgen = o->value.r.gen; } else if (o->t != eDict && o->t != eString) { return pdf_not_ok; } pdf_obj_resolve(o); if (!o) { return pdf_not_ok; } // fill stream info if (o->t == eDict) { int length; pdf_obj *len_obj = pdf_dict_get(o, "Length"); pdf_obj *_decode_params = 0; if (!len_obj) { fprintf(stderr, "%s\n", "Invalid stream."); return pdf_not_ok; } length = pdf_to_int(len_obj); s = pdf_malloc(sizeof(pdf_stream)); if (!s) goto fail; memset(s, 0, sizeof(pdf_stream)); s->length = length; if (length == 0) { // zero lenght stream, just return return pdf_stream_zero_length; } // make raw filter /// internal struct. raw stream object ss = o->value.d.dict->stream; if (!ss) goto fail; ss->len = s->length; _decode_params = pdf_dict_get(o, "DecodeParms"); if (_decode_params) { dp = pdf_decode_params_load(_decode_params); } } else if (o->t == eString) { s = pdf_malloc(sizeof(pdf_stream)); if (!s) goto fail; memset(s, 0, sizeof(pdf_stream)); s->length = o->value.s.len; // make string raw filter ss = string_stream_new(o->value.s.buf, 0, o->value.s.len, 0, 0); } else goto fail; raw = pdf_rawfilter_new(ss); // chain crypto filter if (crypto) { if (which_algo(crypto) == eAESV2) { // need initial_vector unsigned char iv[16]; int n; n = (raw->read)(raw, iv, 16); crypt = pdf_cryptofilter_new(crypto, numobj, numgen, iv); } else { crypt = pdf_cryptofilter_new(crypto, numobj, numgen, NULL); } if (!crypt) goto fail; crypt->next = raw; } if (o->t == eString) { last = (crypt)?crypt:raw; goto done; } // chain the rest x = pdf_dict_get(o, "Filter"); last = (crypt)?crypt:raw; if (!x) { goto done; } else { if (x->t == eArray) { mm = x->value.a.len; xx = x->value.a.items; } else if (obj_is_name(x)) { mm = 1; xx = x; } } for (m = 0; m < mm; m++, xx++) { pdf_filterkind t = Raw; pdf_filter *f; if (!obj_is_name(xx)) { break; } t = pdf_filter_find(xx->value.k); if (t == Limit) { fprintf(stderr, "Unkown filter type: %s\n", xx->value.k); continue; } // make the filter switch (t) { case FlateDecode: case LZWDecode: case ASCII85Decode: case ASCIIHexDecode: f = pdf_filter_new(t, last); if (!f) { if (s) pdf_free(s); if (crypt) PDF_FILTER_CLOSE(crypt, 0); // do not free in_mem stream return pdf_io_err; } /* chain decoding params filter */ if (dp && dp->predictor > 1 && (t == FlateDecode || t == LZWDecode)) { f = pdf_filter_predictor_new(dp, f); } // make the header of chain if (!last) { last = f; s->ffilter = f; } else { #if 0 f->next = last; #endif last = f; } break; default: fprintf(stderr, "filter type: %s is not implemented\n", xx->value.k); e = pdf_not_ok; break; } } if (dp) pdf_free(dp); done: s->ffilter = last; s->close = pdf_istream_filtered_close; s->write = pdf_istream_filtered_write; s->read = pdf_istream_filtered_read; s->getc = pdf_istream_filtered_getc; s->tell = pdf_istream_filtered_tell; s->flush = pdf_stream_base_flush; s->seekp = pdf_stream_base_seekp; s->seekg = pdf_stream_base_seekg; *stm = s; return e; fail: if (s) pdf_free(s); if (raw) raw->close(raw, 1); if (dp) pdf_free(dp); return pdf_not_ok; }
pdf_obj * pdf_info_create(pdf_info *i) { pdf_obj *o = pdf_dict_new(0); dict *d; char buf[128]; pdf_obj *date_obj; if (!o) return 0; d = o->value.d.dict; if (i && i->title) { pdf_dict_insert_obj(d, "Title", i->title); } if (i && i->author) { pdf_dict_insert_obj(d, "Author", i->author); } if (i && i->subject) { pdf_dict_insert_obj(d, "Subject", i->subject); } if (i && i->keywords) { pdf_dict_insert_obj(d, "Keywords", i->keywords); } if (!i || !i->producer) { pdf_dict_insert_string(d, "Producer", "PegDF", strlen("PegDF")); } else { pdf_dict_insert_obj(d, "Producer", i->producer); } if (!i || !i->creator) { pdf_dict_insert_string(d, "Creator", "PegDF", strlen("PegDF")); } else { pdf_dict_insert_obj(d, "Creator", i->creator); } date_obj = pdf_datestring_create(); if (!i || !i->creationdate) { if (date_obj) pdf_dict_insert_obj(d, "CreationDate", date_obj); } else { pdf_dict_insert_string(d, "CreationDate", i->creationdate, strlen(i->creationdate)); } if (date_obj) { pdf_dict_insert_obj(d, "ModDate", date_obj); } if (date_obj) { pdf_obj_delete(date_obj); pdf_free(date_obj); } if (i && i->trapped) { pdf_dict_insert_obj(d, "Trapped", i->trapped); } return o; }
pdf_doc* pdf_doc_load(pdf_trailer *trailer) { pdf_obj *a, *d, *c, *kids, *oc; pdf_doc *doc; pdf_doc_private *pdoc; int count; if (!trailer) return NULL; d = trailer->root_obj; if (!d || d->t != eRef) return NULL; a = pdf_dict_get(d, "Pages"); if (!a) return NULL; count = pdf_to_int(pdf_dict_get(a, "Count")); if (!count) return NULL; pdoc = doc = pdf_malloc(sizeof(pdf_doc_private)); if (!doc) return NULL; memset(doc, 0, sizeof(pdf_doc)); doc->root_ref = d->value.r.num; if (a->t == eRef) doc->pages_ref = a->value.r.num; doc->count = count; c = pdf_dict_get(a, "MediaBox"); if (c) { pdoc->mediabox = pdf_rect_get(c); doc->get_mediabox = pdf_doc_get_mediabox; } else { doc->get_mediabox = null_val; } kids = pdf_dict_get(a, "Kids"); if (!kids || (kids->t != eArray && kids->t != eRef)) { pdf_free(doc); return NULL; } doc->pages = pdf_malloc(sizeof(pdf_page*) * doc->count); memset(doc->pages, 0, (sizeof(pdf_page*) * doc->count)); doc->pageidx = 0; // optional content oc = pdf_dict_get(d, "OCProperties"); if (oc) { doc->ocproperties = pdf_ocproperties_load(oc); } doc->version = pdf_dict_get(d, "Version"); doc->extentions = pdf_dict_get(d, "Extentions"); doc->pagelabels = pdf_dict_get(d, "PageLabels"); doc->names = pdf_dict_get(d, "Names"); doc->dests = pdf_dict_get(d, "Dests"); doc->viewerpreferences = pdf_dict_get(d, "ViewerPreferences"); doc->pagelayout = pdf_dict_get(d, "PageLayout"); doc->pagemode = pdf_dict_get(d, "PageMode"); doc->outlines = pdf_dict_get(d, "Outlines"); doc->threads = pdf_dict_get(d, "Threads"); doc->openaction = pdf_dict_get(d, "OpenAction"); doc->aa = pdf_dict_get(d, "AA"); doc->uri = pdf_dict_get(d, "URI"); doc->acroform = pdf_dict_get(d, "AcroForm"); doc->metadata = pdf_dict_get(d, "Metadata"); doc->structtreeroot = pdf_dict_get(d, "StructTreeRoot"); doc->markinfo = pdf_dict_get(d, "MarkInfo"); doc->lang = pdf_dict_get(d, "Lang"); doc->spiderinfo = pdf_dict_get(d, "SpiderInfo"); doc->outputintents = pdf_dict_get(d, "OutputIntents"); doc->pieceinfo = pdf_dict_get(d, "PieceInfo"); doc->perms = pdf_dict_get(d, "Perms"); doc->legal = pdf_dict_get(d, "Legal"); doc->requirements = pdf_dict_get(d, "Requirements"); doc->collection = pdf_dict_get(d, "Collection"); a = pdf_dict_get(d, "NeedsRendering"); if (a) { doc->needsrendering = pdf_to_int(pdf_dict_get(d, "NeedsRendering")); } // pdf_page_tree_load(doc, kids); /// shuffle in some auxillary info /// doc->trailer = trailer; doc->encrypt = trailer->encrypt; //doc->info = trailer->info; // pass info as member of doc //doc->encrypt = trailer->encrypt; // pass encrypt //trailer->encrypt = NULL; // TODO: move it out return doc; }