ref: b798de6161b15e503d838d1794eab1d8bc5d1760
dir: /eval.c/
#include <u.h> #include <libc.h> #include "pdf.h" static Object * evalobjstm(Pdf *pdf, Xref *x) { Object *ostm, *o; Stream *s; Xref *xstm; int i, off, nobj, first, index; ostm = nil; s = nil; o = &null; /* x is pointing at ObjStm, need to eval it to the actual object */ for(i = 0; i < pdf->nxref && pdf->xref[i].id != x->objstm; i++); if(i >= pdf->nxref){ werrstr("no object id %d in xref", x->objstm); goto err; } xstm = &pdf->xref[i]; if(Sseek(pdf->s, xstm->off, 0) != xstm->off){ werrstr("xref seek failed"); goto err; } if((ostm = pdfobj(pdf, pdf->s, 0)) == nil) goto err; first = -1; if((nobj = dictint(ostm, "N")) < 1 || (first = dictint(ostm, "First")) < 0){ werrstr("invalid ObjStm: nobj=%d first=%d", nobj, first); goto err; } if((s = Sopen(ostm)) == nil) goto err; for(i = 0; i < nobj; i++){ Sgeti(s, &index); Sgeti(s, &off); if(x->id == index){ off += first; if(Sseek(s, off, 0) != off){ werrstr("xref obj seek failed"); goto err; } if((o = pdfobj(pdf, s, 0)) == nil) goto err; o = pdfeval(o); break; } } Sclose(s); /* FIXME "Extends" */ return o; err: pdfobjfree(ostm); Sclose(s); return &null; } Object * pdfevaloff(Object *o, int off) { Object *d; if(o == nil) return &null; if(o->type != Oindir) return o; if(o->indir.o != nil) return o->indir.o; if(Sseek(o->pdf->s, off, 0) != off){ werrstr("evaloff: seek failed"); return &null; } if((d = pdfobj(o->pdf, o->pdf->s, 0)) == nil){ werrstr("evaloff: %r [at %p]", (void*)off); return &null; } o->indir.o = d; return d; } Object * pdfeval(Object *o) { Object *d; Xref *x; int i; if(o == nil) return &null; if(o->type != Oindir) return o; if(o->indir.o != nil) return o->indir.o; for(x = nil, i = 0; i < o->pdf->nxref; i++){ x = &o->pdf->xref[i]; if(x->id == o->indir.id) break; } if(i >= o->pdf->nxref){ werrstr("eval: no object id %d in xref", o->indir.id); return &null; } if(x->objstm > 0){ if((d = evalobjstm(o->pdf, x)) == &null) werrstr("eval: ObjStm: %r"); o->indir.o = d; return d; } if(Sseek(o->pdf->s, x->off, 0) != x->off){ werrstr("eval: xref seek failed"); return &null; } if((d = pdfobj(o->pdf, o->pdf->s, 0)) == nil){ werrstr("eval: %r [at %p]", (void*)x->off); return &null; } o->indir.o = d; return d; }