// TODO: insert to head, and return head of list. static void dict_list_append(char *key, void *v, void *list) { dict_list *l = (dict_list*)list; dict_list *head = l; if (!l) return; if (l->last) l = l->last; l->key = pdf_malloc(strlen(key)+1); memcpy(l->key, key, strlen(key)+1); #if defined(HASHMAP) l->val = *((pdf_obj*)v); #elif defined(TSTC) l->val = *(pdf_obj*)((dict_entry*)v)->v; #else l->val = *((pdf_obj*)v); #endif if (!l->last) { l->last = (dict_list*)pdf_malloc(sizeof(dict_list)); l->last->key = NULL; l->next = l->last; l->next->next = l->next->last = l->last->last = NULL; head->last = l->last; } }
// returned object belongs to caller. dict_array* dict_to_array(dict *d) { dict_array *a = pdf_malloc(sizeof(dict_array)); if (!a) return a; a->cur = 0; a->items = pdf_malloc((sizeof(struct dict_item))* (d->n)); if (!a->items) return NULL; if (d && d->dict) { #if defined (HASHMAP) fprintf(stderr, "%s is not implemented", __FUNCTION__); #elif defined (TSTC) tstc_call(d->dict, 0, (tstc_f)dict_tstc_array_append, (void*)a); #else tst_print_reset(1); tst_traverse(d->dict, (tst_hook)dict_array_append, a); tst_print_reset(-1); #endif } return a; }
pdf_stream* pdf_stream_buffer_open() { pdf_buffer_stream *s; stream_buffer *buf; s = (pdf_buffer_stream*)pdf_malloc(sizeof(pdf_buffer_stream)); if (!s) return 0; memset(s, 0, sizeof(pdf_buffer_stream)); buf = (stream_buffer*)pdf_malloc(sizeof(stream_buffer)); if (!buf) return 0; memset(buf, 0, sizeof(stream_buffer)); pdf_stream_base_init((pdf_stream*)s); buf->buf = (byte*)pdf_malloc(PDF_STREAM_BUFFER_CHUNK); buf->limit = buf->buf + PDF_STREAM_BUFFER_CHUNK; buf->gcur = buf->buf; buf->ptop = buf->buf; buf->next = 0; s->buf = buf; s->active = buf; s->close = pdf_stream_buffer_close; s->write = pdf_stream_buffer_write; s->read = pdf_stream_buffer_read; s->getc = pdf_stream_buffer_getc; s->tell = pdf_stream_buffer_tell; s->seekg = pdf_stream_buffer_seekg; s->seekp = pdf_stream_buffer_seekp; s->flush = pdf_stream_buffer_flush; return (pdf_stream*)s; }
// shallow copying except when entry is a dictionary // // parameter: k: key, v: value, a: dictionary // static void dict_entry_copy(char *k, void *v, void *a) { dict_entry *e = (dict_entry *)v; pdf_obj *val; char *p; val = pdf_malloc(sizeof(pdf_obj)); #ifdef HASHMAP *val = *(pdf_obj*)v; #else *val = *(pdf_obj*)(e->v); #endif switch (val->t) { case eDict: val->value.d.dict = dict_copy(((pdf_obj*)(e->v))->value.d.dict); break; case eName: case eString: case eHexString: case eArray: break; default: break; } #ifdef HASHMAP if (pdf_keyword_find(k, strlen(k))) { p = k; } else { p = pdfname_search(k); if (!p) { // memory leak p = pdf_malloc(strlen(k)+1); memcpy(p, k, strlen(k)+1); } } #else if (pdf_keyword_find(e->k, strlen(e->k))) { p = e->k; } else { p = pdf_malloc(strlen(e->k)+1); memcpy(p, e->k, strlen(e->k)+1); } #endif dict_insert((dict*)a, p, val); }
static void pdf_stream_buffer_grow(pdf_stream *sb) { pdf_buffer_stream *s = (pdf_buffer_stream*)sb; stream_buffer *f = (stream_buffer*)pdf_malloc(sizeof(stream_buffer));; f->buf = pdf_malloc(PDF_STREAM_BUFFER_CHUNK); f->ptop = f->buf; f->gcur = f->buf; f->limit = f->buf + PDF_STREAM_BUFFER_CHUNK; f->next = 0; s->active->next = f; s->active = f; }
pdf_err pdf_info_load(pdf_obj *o, pdf_info **info) { pdf_obj *a; pdf_info *i; if (!o) return pdf_ok; *info = pdf_malloc(sizeof(pdf_info)); if (!*info) return pdf_ok; i = *info; memset(*info, 0, sizeof(pdf_info)); if (a = pdf_dict_get(o, "Title")) { i->title = pdf_obj_full_copy(a); } if (a = pdf_dict_get(o, "Author")) { i->author = pdf_obj_full_copy(a); } if (a = pdf_dict_get(o, "Subject")) { i->subject = pdf_obj_full_copy(a); } if (a = (pdf_obj*)pdf_dict_get(o, "Keywords")) { i->keywords = pdf_obj_full_copy(a); } if (a = (pdf_obj*)pdf_dict_get(o, "Creator")) { i->creator = pdf_obj_full_copy(a); } if (a = pdf_dict_get(o, "Producer")) { i->producer = pdf_obj_full_copy(a); } a = pdf_dict_get(o, "CreationDate"); if (a) {i->creationdate = pdf_malloc(a->value.s.len+1); memcpy(i->creationdate, a->value.s.buf, a->value.s.len); i->creationdate[a->value.s.len] = 0;} a = pdf_dict_get(o, "ModDate"); if (a) {i->moddate = pdf_malloc(a->value.s.len+1); memcpy(i->moddate, a->value.s.buf, a->value.s.len); i->moddate[a->value.s.len] = 0;} if (a = pdf_dict_get(o, "Trapped")) { i->trapped = pdf_obj_full_copy(a); } return pdf_ok; }
pdf_stream* pdf_stream_file_open(char *ofile) { pdf_stream *s; FILE *f; #ifdef DEBUG printf("Writing %s..\n", ofile); #endif f = fopen(ofile, "wb"); if (!f) return 0; s = pdf_malloc(sizeof(pdf_stream)); if (!s) return 0; memset(s, 0, sizeof(pdf_stream)); pdf_stream_base_init(s); s->state = (void*) f; s->close = pdf_stream_file_close; s->write = pdf_stream_file_write; s->read = pdf_stream_file_read; s->tell = pdf_stream_file_tell; s->seekg = pdf_stream_file_seek; s->seekp = pdf_stream_file_seek; s->flush = pdf_stream_file_flush; return s; }
pdf_extgstate* pdf_extgstate_load(pdf_obj *o) { pdf_extgstate *g; if (!o || (o->t != eDict && o->t != eRef)) return NULL; g = pdf_malloc(sizeof(pdf_extgstate)); if (!g) return NULL; memset(g, 0, sizeof(pdf_extgstate)); // Todo: check default value g->LW = pdf_to_float(pdf_dict_get(o, "LW")); g->LC = pdf_to_int(pdf_dict_get(o, "LC")); g->LJ = pdf_to_int(pdf_dict_get(o, "LJ")); g->ML = pdf_to_float(pdf_dict_get(o, "ML")); pdf_to_float_array(pdf_dict_get(o, "D"), g->D); g->RI = pdf_to_string(pdf_dict_get(o, "RI")); g->OP = pdf_to_int(pdf_dict_get(o, "OP")); g->OPM = pdf_to_int(pdf_dict_get(o, "OPM")); g->op = pdf_to_int(pdf_dict_get(o, "op")); g->BM = pdf_dict_get(o, "BM"); g->SA = pdf_to_int(pdf_dict_get(o, "SA")); // font // bg g->CA = pdf_to_float(pdf_dict_get(o, "CA")); g->ca = pdf_to_float(pdf_dict_get(o, "ca")); g->AIS = pdf_to_int(pdf_dict_get(o, "AIS")); g->TK = pdf_to_int(pdf_dict_get(o, "TK")); return g; }
pdf_map * pdf_map_create() { pdf_map * m = pdf_malloc(sizeof(pdf_map)); if (m) memset(m, 0, sizeof(pdf_map)); return m; }
static void dict_array_append(char *key, void *v, dict_array* a) { a->items[a->cur].key = pdf_malloc(strlen(key)+1); memcpy(a->items[a->cur].key, key, strlen(key)+1); a->items[a->cur].val = *((pdf_obj*)v); a->cur += 1; }
void pdf_dict_insert_name(dict *d, char *k, char *n) { pdf_obj *val; pdf_obj key = pdf_key_to_obj(k); val = pdf_malloc(sizeof(pdf_obj)); val->t = eKey; *val = pdf_key_to_obj(n); dict_insert(d, (char*)key.value.k, (void*)val); }
static void dict_tstc_array_append(char *k, void *v, void* arr) { dict_entry *e = (dict_entry*)v; char *key = e->k; dict_array * a = (dict_array*)arr; a->items[a->cur].key = pdf_malloc(strlen(key)+1); memcpy(a->items[a->cur].key, key, strlen(key)+1); a->items[a->cur].val = *((pdf_obj*)(e->v)); a->cur += 1; }
pdf_interp_state * pdf_interpreter_new(pdf_device *dev, pdfcrypto_priv* encrypt) { pdf_interp_state *i = pdf_malloc(sizeof(pdf_interp_state)); if (i) { memset(i, 0, sizeof(pdf_interp_state)); i->dev = dev; i->crypto = encrypt; } return i; }
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; }
dict* dict_new(int n) { dict * d = pdf_malloc(sizeof(dict)); if (d) { #if defined(HASHMAP) d->dict = hash_map_new(n); #else d->dict = NULL; #endif d->n = 0; d->stream = 0; } return d; }
static inline pdf_group* pdf_group_load(pdf_obj *o) { pdf_group *g; if (!o) return NULL; g = pdf_malloc(sizeof(pdf_group)); if (!g) return NULL; memset(g, 0, sizeof(pdf_group)); g->cs = pdf_dict_get(o, "CS"); g->i = pdf_to_int(pdf_dict_get(o, "I")); g->k = pdf_to_int(pdf_dict_get(o, "K")); return g; }
pdf_annots* pdf_annots_load(pdf_obj* o) { pdf_annots *a=NULL, *first=NULL, *last = NULL; int i; pdf_obj *x, *t; o = pdf_array_get(o); if (!o) return NULL; for (i = 0; i < pdf_to_arraylen(o); i++) { t = pdf_get_array_item(o, i); pdf_obj_resolve(t); if (!t || t->t != eDict) continue; a = pdf_malloc(sizeof(pdf_annots)); if (!a) return NULL; memset(a, 0, sizeof(pdf_annots)); // default border a->border[0] = 0, a->border[1] = 0, a->border[2] = 1; // load annotation node a->subtype = pdf_annots_type(pdf_dict_get(t, "Subtype")); a->rect = pdf_rect_get(pdf_dict_get(t, "Rect")); if ((x = pdf_dict_get(t, "Border"))) { a->border[0] = pdf_to_float(pdf_get_array_item(x, 0)); a->border[1] = pdf_to_float(pdf_get_array_item(x, 1)); a->border[2] = pdf_to_float(pdf_get_array_item(x, 2)); if (pdf_to_arraylen(x) > 3) { pdf_obj *y = pdf_get_array_item(x, 3); a->border[3] = pdf_to_float(pdf_get_array_item(y, 0)); a->border[4] = pdf_to_float(pdf_get_array_item(y, 1)); } } // make linked list if (last) last->next = a; if (i == 0) { first = a; } last = a; } return first; }
decode_params * pdf_decode_params_load(pdf_obj *obj) { decode_params *dp = pdf_malloc(sizeof(decode_params)); if (!obj) return 0; if (!dp) return 0; memset(dp, 0, sizeof(decode_params)); dp->predictor = pdf_to_int(pdf_dict_get(obj, "Predictor")); dp->colors = pdf_to_int(pdf_dict_get(obj, "Colors")); dp->bitspercomponent = pdf_to_int(pdf_dict_get(obj, "BitsPerComponent")); dp->columns = pdf_to_int(pdf_dict_get(obj, "Columns")); dp->earlychange = pdf_to_int(pdf_dict_get(obj, "EarlyChange")); return dp; }
dict_entry* dict_entry_new(void *v, char *k) { dict_entry *e; e = pdf_malloc(sizeof(dict_entry)); if (!e) return 0; if (pdf_keyword_find(k, strlen(k))) { e->f = entry_no_free; e->k = k; } else { e->f = entry_name_free; e->k = k; } e->v = v; return e; }
pdf_resources* pdf_resources_load(pdf_obj *o) { pdf_resources *r; if (!o) return NULL; r = pdf_malloc(sizeof(pdf_resources)); if (!r) return NULL; r->extgstate = pdf_dict_get(o, "ExtGState"); r->colorspace = pdf_dict_get(o, "ColorSpace"); r->pattern = pdf_dict_get(o, "Pattern"); r->shading = pdf_dict_get(o, "Shading"); r->xobject = pdf_dict_get(o, "XObject"); r->font = pdf_dict_get(o, "Font"); r->procset = pdf_dict_get(o, "ProcSet"); r->properties = pdf_dict_get(o, "Properties"); return r; }
pdf_stream* pdf_rawstream_new(sub_stream *ss) { pdf_filter *raw; pdf_stream *s; raw = pdf_rawfilter_new(ss); s = pdf_malloc(sizeof(pdf_stream)); s->ffilter = raw; 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; return s; }
pdf_device* pdf_dev_text_new(FILE *out) { pdf_device *d; d = pdf_malloc(sizeof(pdf_device)); if (!d) return d; memset(d, 0, sizeof(pdf_device)); d->dest.f = out; d->doc_begin = pdf_dev_text_doc_begin; d->doc_end = pdf_dev_text_doc_end; d->page_begin = pdf_dev_text_page_begin; d->page_end = pdf_dev_text_page_end; d->fill_char = pdf_dev_text_char_show; d->stroke_char = pdf_dev_text_char_show; d->path_fill = pdf_dev_text_path_fill; d->path_stroke = pdf_dev_text_path_stroke; d->color_set = pdf_dev_text_color_set; d->path_add = pdf_dev_text_path_add; return d; }
// 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_encrypt_load(pdf_obj *o, pdf_encrypt **encrypt) { pdf_obj *a; pdf_encrypt *e; if (!o) return pdf_ok; pdf_obj_resolve(o); if (!o) return pdf_ok; *encrypt = pdf_malloc(sizeof(pdf_encrypt)); if (!*encrypt) return pdf_mem_err; memset(*encrypt, 0, sizeof(pdf_encrypt)); e = *encrypt; e->v = 0; a = pdf_dict_get(o, "Filter"); if (a) { pdf_obj_resolve(a); (*encrypt)->filter = pdf_malloc(strlen(a->value.k)+1); memcpy((*encrypt)->filter, a->value.k, strlen(a->value.k)); (*encrypt)->filter[strlen(a->value.k)] = 0; } a = pdf_dict_get(o, "SubFilter"); if (a) { pdf_obj_resolve(a); (*encrypt)->subfilter = pdf_malloc(strlen(a->value.k)+1); memcpy((*encrypt)->subfilter, a->value.k, strlen(a->value.k)); (*encrypt)->subfilter[strlen(a->value.k)] = 0; } a = pdf_dict_get(o, "V"); if (a) { (*encrypt)->v = pdf_to_int(a); } e->length = 40; a = pdf_dict_get(o, "Length"); if (a) { (*encrypt)->length = pdf_to_int(a); } if (e->v == 4) { pdf_obj *cf = pdf_dict_get(o, "CF"); if (cf) { a = pdf_dict_get(o, "StmF"); if (a) { pdf_obj_resolve(a); pdf_cf_load(e, cf, a->value.k, &e->stmf); } a = pdf_dict_get(o, "StrF"); if (a) { pdf_obj_resolve(a); pdf_cf_load(e, cf, a->value.k, &e->strf); } a = pdf_dict_get(o, "EFF"); if (a) { pdf_obj_resolve(a); pdf_cf_load(e, cf, a->value.k, &e->eff); } } } // standard encryption dictionary (items) a = pdf_dict_get(o, "R"); if (a) { (*encrypt)->r = pdf_to_int(a); } a = pdf_dict_get(o, "O"); // owner password if (a) { // should verify length to 32 bytes pdf_obj_resolve(a); memcpy((*encrypt)->o, a->value.s.buf, a->value.s.len); } a = pdf_dict_get(o, "U"); // user password if (a) { // should verify length to 32 bytes pdf_obj_resolve(a); memcpy((*encrypt)->u, a->value.s.buf, a->value.s.len); } a = pdf_dict_get(o, "P"); // permission flags if (a) { (*encrypt)->p = pdf_to_int(a); } a = pdf_dict_get(o, "EncryptMetadata"); if (a) { pdf_obj_resolve(a); (*encrypt)->encrypt_metadata = a->value.b; } return pdf_ok; }
pdf_err pdf_page_load(pdf_doc *doc, pdf_obj *o, pdf_page **page) { pdf_page *p; pdf_obj *mediabox; pdf_obj *v; if (o->t != eRef) return pdf_syntax_err; *page = pdf_malloc(sizeof(pdf_page)); p = *page; memset(p, 0, sizeof(pdf_page)); p->ref = *o; // parse tree dict p->parent = pdf_dict_get(o, "Parent"); mediabox = pdf_dict_get(o, "MediaBox"); if (mediabox) p->mediabox = pdf_rect_get(mediabox); else { gs_rect *r = doc->get_mediabox(doc); if (r) p->mediabox = *r; } p->resources = pdf_resources_load(pdf_dict_get(o, "Resources")); // optionals p->contents = pdf_dict_get(o, "Contents"); v = (pdf_obj*)pdf_dict_get(o, "Rotate"); if (v) { p->rotate = v->value.i; if (p->rotate < 0) p->rotate = 360 - ((-p->rotate) % 360); if (p->rotate >= 360) p->rotate = p->rotate % 360; p->rotate = 90*((p->rotate + 45)/90); if (p->rotate > 360) p->rotate = 0; if (p->rotate == 90 || p->rotate == 270) { float x = p->mediabox.y1; p->mediabox.y1 = p->mediabox.x1; p->mediabox.x1 = x; } } p->group = pdf_group_load(pdf_dict_get(o, "Group")); p->cropbox = pdf_dict_get(o, "CropBox"); p->bleedbox = pdf_dict_get(o, "BleedBox"); p->trimbox = pdf_dict_get(o, "TrimBox"); p->artbox = pdf_dict_get(o, "ArtBox"); p->boxcolorinfo = pdf_dict_get(o, "BoxColorInfo"); p->thumb = pdf_dict_get(o, "Thumb"); p->b = pdf_dict_get(o, "b"); p->dur = pdf_to_float(pdf_dict_get(o, "Dur")); p->trans = pdf_dict_get(o, "Trans"); p->annots = pdf_annots_load(pdf_dict_get(o, "Annots")); p->aa = pdf_dict_get(o, "AA"); p->metadata = pdf_dict_get(o, "Metadata"); p->pieceinfo = pdf_dict_get(o, "PieceInfo"); p->structparents = pdf_to_int(pdf_dict_get(o, "StructParents")); p->id = pdf_to_int(pdf_dict_get(o, "ID")); p->pz = pdf_to_float(pdf_dict_get(o, "PZ")); p->separationinfo = pdf_dict_get(o, "SeparationInfo"); p->tabs = pdf_dict_get(o, "Tabs"); p->templateinstantiated = pdf_dict_get(o, "TemplateInstantiated"); p->pressteps = pdf_dict_get(o, "PresSteps"); p->userunit = pdf_to_float(pdf_dict_get(o, "UserUnit")); p->vp = pdf_dict_get(o, "VP"); // required depends p->lastmodified = pdf_dict_get(o, "LastModified"); return pdf_ok; }
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; }
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; }