diff options
-rw-r--r-- | Jamfile | 3 | ||||
-rw-r--r-- | mupdf/function.c | 68 | ||||
-rw-r--r-- | test/pdffunction.c | 261 |
3 files changed, 264 insertions, 68 deletions
@@ -131,6 +131,7 @@ Main pdfclean : test/pdfclean.c ; Main pdfdebug : test/pdfdebug.c ; Main pdfmerge : test/pdfmerge.c ; Main pdfrip : test/pdfrip.c ; +Main pdffunction : test/pdffunction.c ; -LinkLibraries pdfclean pdfdebug pdfmerge pdfrip : libmupdf libfitz ; +LinkLibraries pdfclean pdfdebug pdfmerge pdfrip pdffunction : libmupdf libfitz ; diff --git a/mupdf/function.c b/mupdf/function.c index 5efb28fd..1a96600a 100644 --- a/mupdf/function.c +++ b/mupdf/function.c @@ -435,67 +435,6 @@ pop(psstack *st) /* End Stack Impl */ /************************************************************************/ -/* From Numerial recipes */ -static fz_error * -spline(float x[], float y[], int n, float yp1, float ypn, float y2[]) -{ - int i,k; - float p,qn,sig,un,*u; - - u = fz_malloc(n*sizeof(float)); - if(!u) - return fz_outofmem; - - if (yp1 > 0.99e30) - y2[0]=u[0]=0.0; - else { - y2[0] = -0.5; - u[0]=(3.0/(x[1]-x[0]))*((y[1]-y[0])/(x[1]-x[0])-yp1); - } - for (i=1;i<n-1;i++) { - sig=(x[i]-x[i-1])/(x[i+1]-x[i-1]); - p=sig*y2[i-1]+2.0; - y2[i]=(sig-1.0)/p; - u[i]=(y[i+1]-y[i])/(x[i+1]-x[i]) - (y[i]-y[i-1])/(x[i]-x[i-1]); - u[i]=(6.0*u[i]/(x[i+1]-x[i-1])-sig*u[i-1])/p; - } - if (ypn > 0.99e30) - qn=un=0.0; - else { - qn=0.5; - un=(3.0/(x[n-1]-x[n-2]))*(ypn-(y[n-1]-y[n-2])/(x[n-1]-x[n-2])); - } - y2[n-1]=(un-qn*u[n-2])/(qn*y2[n-2]+1.0); - for (k=n-2;k>=0;k--) - y2[k]=y2[k]*y2[k+1]+u[k]; - - fz_free(u); - return nil; -} - -static fz_error * -splint(float xa[], float ya[], float y2a[], int n, float x, float *y) -{ - int k; - int klo=0; - int khi=n-1; - float h,b,a; - - while (khi-klo > 1) { - k=(khi+klo) >> 1; - if (xa[k] > x) khi=k; - else klo=k; - } - h=xa[khi]-xa[klo]; - if (h == 0.0) return fz_throw("Bad xa input to routine splint"); - a=(xa[khi]-x)/h; - b=(x-xa[klo])/h; - *y=a*ya[klo]+b*ya[khi]+((a*a*a-a)*y2a[klo] - +(b*b*b-b)*y2a[khi])*(h*h)/6.0; - - return nil; -} - static fz_error * loadsamplefunc(pdf_function *func, pdf_xref *xref, fz_obj *dict, int oid, int gid) { @@ -842,7 +781,7 @@ cleanup: static fz_error * loadstitchingfunc(pdf_function *func, pdf_xref *xref, fz_obj *dict) { - fz_error *err; + fz_error *err = nil; fz_obj *tmpobj; fz_obj *funcobj; fz_obj *numobj; @@ -980,8 +919,6 @@ parsecode(pdf_function *func, fz_file *stream, int *codeptr) int buflen = sizeof(buf) / sizeof(buf[0]); int len; int token; - char *p; - int isReal; int opPtr, elsePtr; int a, b, mid, cmp; @@ -1098,8 +1035,6 @@ loadpostscriptfunc(pdf_function *func, pdf_xref *xref, fz_obj *dict, int oid, int gid) { fz_error *err = nil; - fz_obj *tmpobj; - unsigned char *streamsamples = nil; int codeptr; /* read postcript from stream */ @@ -1509,7 +1444,6 @@ pdf_loadfunction(pdf_function **func, pdf_xref *xref, fz_obj *obj) fz_error *err = nil; fz_obj *objfunc = nil; fz_obj *tmpobj; - fz_obj *functype; pdf_function *newfunc = nil; int tmp; int i; diff --git a/test/pdffunction.c b/test/pdffunction.c new file mode 100644 index 00000000..73d01cbb --- /dev/null +++ b/test/pdffunction.c @@ -0,0 +1,261 @@ +#include <fitz.h> +#include <mupdf.h> + +static char *password = ""; +static int dodecode = 0; +static int dorepair = 0; +static int doprintxref = 0; + +typedef struct psobj_s psobj; + +struct pdf_function_s +{ + unsigned short type; /* 0=sample 2=exponential 3=stitching 4=postscript */ + int m; /* number of input values */ + int n; /* number of output values */ + float *domain; /* even index : min value, odd index : max value */ + float *range; /* even index : min value, odd index : max value */ + union + { + struct { + unsigned short bps; + unsigned short order; + int *size; /* the num of samples in each input dimension */ + float *encode; + float *decode; + int *samples; + } sa; + struct { + float n; + float *c0; + float *c1; + } e; + struct { + int k; + pdf_function **funcs; + float *bounds; + float *encode; + } st; + struct { + psobj *code; + int cap; + } p; + }u; +}; + +void usage() +{ + fprintf(stderr, "usage: pdffunction [-drxs] [-u password] file.pdf oid [input ...]\n"); + exit(1); +} + +static int safecol = 0; + +void printsafe(unsigned char *buf, int n) +{ + int i; + for (i = 0; i < n; i++) { + if (buf[i] == '\r' || buf[i] == '\n') { + printf("\n"); + safecol = 0; + } + else if (buf[i] < 32 || buf[i] > 126) { + printf("."); + safecol ++; + } + else { + printf("%c", buf[i]); + safecol ++; + } + if (safecol == 79) { + printf("\n"); + safecol = 0; + } + } +} + +void decodestream(pdf_xref *xref, int oid, int gid) +{ + fz_error *error; + unsigned char buf[512]; + + safecol = 0; + + error = pdf_openstream(xref, oid, gid); + if (error) fz_abort(error); + + while (1) + { + int n = fz_read(xref->stream, buf, sizeof buf); + if (n == 0) + break; + if (n < 0) + fz_abort(fz_ferror(xref->stream)); + printsafe(buf, n); + } + + pdf_closestream(xref); +} + +void copystream(pdf_xref *xref, int oid, int gid) +{ + fz_error *error; + unsigned char buf[512]; + + safecol = 0; + + error = pdf_openrawstream(xref, oid, gid); + if (error) fz_abort(error); + + while (1) + { + int n = fz_read(xref->stream, buf, sizeof buf); + if (n == 0) + break; + if (n < 0) + fz_abort(fz_ferror(xref->stream)); + printsafe(buf, n); + } + + pdf_closestream(xref); +} + +void printobject(pdf_xref *xref, int oid, int gid) +{ + fz_error *error; + fz_obj *obj; + + error = pdf_loadobject(&obj, xref, oid, gid); + if (error) fz_abort(error); + + printf("%d %d obj\n", oid, gid); + fz_debugobj(obj); + printf("\n"); + + if (xref->table[oid].stmofs) { + printf("stream\n"); + if (dodecode) + decodestream(xref, oid, gid); + else + copystream(xref, oid, gid); + printf("endstream\n"); + } + + printf("endobj\n"); + + fz_dropobj(obj); +} + +int main(int argc, char **argv) +{ + fz_error *error; + char *filename; + pdf_xref *xref; + int c; + + while ((c = getopt(argc, argv, "drxopu:")) != -1) + { + switch (c) + { + case 'd': + dodecode ++; + break; + case 'r': + dorepair ++; + break; + case 'x': + doprintxref ++; + break; + case 'u': + password = optarg; + break; + default: + usage(); + } + } + + if (argc - optind == 0) + usage(); + + filename = argv[optind++]; + + if (dorepair) + error = pdf_repairpdf(&xref, filename); + else + error = pdf_openpdf(&xref, filename); + if (error) + fz_abort(error); + + error = pdf_decryptpdf(xref); + if (error) + fz_abort(error); + + if (xref->crypt) + { + error = pdf_setpassword(xref->crypt, password); + if (error) fz_abort(error); + } + + if (optind == argc) + { + printf("trailer\n"); + fz_debugobj(xref->trailer); + printf("\n"); + } + else + { + int oid = atoi(argv[optind++]); + if(optind == argc) + printobject(xref, oid, 0); + else + { + float *in = nil, *out = nil; + pdf_function *func; + fz_obj *funcobj; + int i; + + /* type 0 and type 4 funcs must be indirect to read stream */ + error = fz_newindirect(&funcobj,oid,0); + if(error) fz_abort(error); + error = pdf_loadfunction(&func,xref,funcobj); + if(error) fz_abort(error); + in = fz_malloc(func->m * sizeof(float)); + out = fz_malloc(func->n * sizeof(float)); + + if(!in || !out) + fz_abort(fz_outofmem); + + for(i = 0; optind < argc; optind++, i++) + { + if(i >= func->m) + fz_abort(fz_throw("too much input values")); + + in[i] = atof(argv[optind]); + } + + if(i < func->m) + fz_abort(fz_throw("too few input values")); + + error = pdf_evalfunction(func, in, func->m, out, func->n); + if(error) fz_abort(error); + + for(i = 0; i < func->n; ++i) + fprintf(stderr, "output[%d] : %f\n", i, out[i]); + + fz_dropobj(funcobj); + pdf_freefunc(func); + } + } + + for ( ; optind < argc; optind++) + { + printobject(xref, atoi(argv[optind]), 0); + printf("\n"); + } + + if (doprintxref) + pdf_debugpdf(xref); + + pdf_closepdf(xref); +} + |