summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Jamfile3
-rw-r--r--mupdf/function.c68
-rw-r--r--test/pdffunction.c261
3 files changed, 264 insertions, 68 deletions
diff --git a/Jamfile b/Jamfile
index 0f567443..2ac988bb 100644
--- a/Jamfile
+++ b/Jamfile
@@ -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);
+}
+