Commit b9fab511 authored by Albert Astals Cid's avatar Albert Astals Cid

Function.cc|h merges from xpdf 3.01

parent c6e02422
......@@ -6,6 +6,7 @@
* poppler/FontInfo.cc
* poppler/Page.cc:
* poppler/PSOutputDev.cc: Changes needed due to Annot changes
* poppler/Function.[cc|h]: Merge from xpdf 3.01
2005-10-05 Kristian Høgsberg <krh@redhat.com>
......
......@@ -12,7 +12,6 @@
#pragma implementation
#endif
#include <locale.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
......@@ -186,7 +185,7 @@ void IdentityFunction::transform(double *in, double *out) {
SampledFunction::SampledFunction(Object *funcObj, Dict *dict) {
Stream *str;
int nSamples, sampleBits;
int sampleBits;
double sampleMul;
Object obj1, obj2;
Guint buf, bitMask;
......@@ -229,6 +228,10 @@ SampledFunction::SampledFunction(Object *funcObj, Dict *dict) {
obj2.free();
}
obj1.free();
idxMul[0] = n;
for (i = 1; i < m; ++i) {
idxMul[i] = idxMul[i-1] * sampleSize[i-1];
}
//----- BitsPerSample
if (!dict->lookup("BitsPerSample", &obj1)->isInt()) {
......@@ -265,6 +268,10 @@ SampledFunction::SampledFunction(Object *funcObj, Dict *dict) {
}
}
obj1.free();
for (i = 0; i < m; ++i) {
inputMul[i] = (encode[i][1] - encode[i][0]) /
(domain[i][1] - domain[i][0]);
}
//----- Decode
if (dict->lookup("Decode", &obj1)->isArray() &&
......@@ -343,37 +350,34 @@ SampledFunction::~SampledFunction() {
}
SampledFunction::SampledFunction(SampledFunction *func) {
int nSamples, i;
memcpy(this, func, sizeof(SampledFunction));
nSamples = n;
for (i = 0; i < m; ++i) {
nSamples *= sampleSize[i];
}
samples = (double *)gmallocn(nSamples, sizeof(double));
memcpy(samples, func->samples, nSamples * sizeof(double));
}
void SampledFunction::transform(double *in, double *out) {
double x;
int e[2][funcMaxInputs];
double efrac[funcMaxInputs];
double s0[1 << funcMaxInputs], s1[1 << funcMaxInputs];
int i, j, k, idx;
int e[funcMaxInputs][2];
double efrac0[funcMaxInputs];
double efrac1[funcMaxInputs];
double s[1 << funcMaxInputs];
int i, j, k, idx, t;
// map input values into sample array
for (i = 0; i < m; ++i) {
x = ((in[i] - domain[i][0]) / (domain[i][1] - domain[i][0])) *
(encode[i][1] - encode[i][0]) + encode[i][0];
x = (in[i] - domain[i][0]) * inputMul[i] + encode[i][0];
if (x < 0) {
x = 0;
} else if (x > sampleSize[i] - 1) {
x = sampleSize[i] - 1;
}
e[0][i] = (int)floor(x);
e[1][i] = (int)ceil(x);
efrac[i] = x - e[0][i];
e[i][0] = (int)x;
if ((e[i][1] = e[i][0] + 1) >= sampleSize[i]) {
// this happens if in[i] = domain[i][1]
e[i][1] = e[i][0];
}
efrac1[i] = x - e[i][0];
efrac0[i] = 1 - efrac1[i];
}
// for each output, do m-linear interpolation
......@@ -381,24 +385,22 @@ void SampledFunction::transform(double *in, double *out) {
// pull 2^m values out of the sample array
for (j = 0; j < (1<<m); ++j) {
idx = 0;
for (k = m - 1; k >= 0; --k) {
idx = idx * sampleSize[k] + e[(j >> k) & 1][k];
idx = i;
for (k = 0, t = j; k < m; ++k, t >>= 1) {
idx += idxMul[k] * (e[k][t & 1]);
}
idx = idx * n + i;
s0[j] = samples[idx];
s[j] = samples[idx];
}
// do m sets of interpolations
for (j = 0; j < m; ++j) {
for (k = 0; k < (1 << (m - j)); k += 2) {
s1[k >> 1] = (1 - efrac[j]) * s0[k] + efrac[j] * s0[k+1];
for (j = 0, t = (1<<m); j < m; ++j, t >>= 1) {
for (k = 0; k < t; k += 2) {
s[k >> 1] = efrac0[j] * s[k] + efrac1[j] * s[k+1];
}
memcpy(s0, s1, (1 << (m - j - 1)) * sizeof(double));
}
// map output value to range
out[i] = s0[0] * (decode[i][1] - decode[i][0]) + decode[i][0];
out[i] = s[0] * (decode[i][1] - decode[i][0]) + decode[i][0];
if (out[i] < range[i][0]) {
out[i] = range[i][0];
} else if (out[i] > range[i][1]) {
......@@ -917,10 +919,14 @@ double PSStack::popNum() {
void PSStack::copy(int n) {
int i;
if (sp + n > psStackSize) {
error(-1, "Stack underflow in PostScript function");
return;
}
if (!checkOverflow(n)) {
return;
}
for (i = sp + n - 1; i <= sp; ++i) {
for (i = sp + n - 1; i >= sp; --i) {
stack[i - n] = stack[i];
}
sp -= n;
......@@ -991,6 +997,7 @@ PostScriptFunction::PostScriptFunction(Object *funcObj, Dict *dict) {
str = funcObj->getStream();
//----- parse the function
codeString = new GooString();
str->reset();
if (!(tok = getToken(str)) || tok->cmp("{")) {
error(-1, "Expected '{' at start of PostScript function");
......@@ -1018,10 +1025,12 @@ PostScriptFunction::PostScriptFunction(PostScriptFunction *func) {
memcpy(this, func, sizeof(PostScriptFunction));
code = (PSObject *)gmallocn(codeSize, sizeof(PSObject));
memcpy(code, func->code, codeSize * sizeof(PSObject));
codeString = func->codeString->copy();
}
PostScriptFunction::~PostScriptFunction() {
gfree(code);
delete codeString;
}
void PostScriptFunction::transform(double *in, double *out) {
......@@ -1072,11 +1081,7 @@ GBool PostScriptFunction::parseCode(Stream *str, int *codePtr) {
resizeCode(*codePtr);
if (isReal) {
code[*codePtr].type = psReal;
{
char *theLocale = setlocale(LC_NUMERIC, "C");
code[*codePtr].real = atof(tok->getCString());
setlocale(LC_NUMERIC, theLocale);
}
} else {
code[*codePtr].type = psInt;
code[*codePtr].intg = atoi(tok->getCString());
......@@ -1179,6 +1184,9 @@ GooString *PostScriptFunction::getToken(Stream *str) {
s = new GooString();
do {
c = str->getChar();
if (c != EOF) {
codeString->append(c);
}
} while (c != EOF && isspace(c));
if (c == '{' || c == '}') {
s->append((char)c);
......@@ -1190,6 +1198,7 @@ GooString *PostScriptFunction::getToken(Stream *str) {
break;
}
str->getChar();
codeString->append(c);
}
} else {
while (1) {
......@@ -1199,6 +1208,7 @@ GooString *PostScriptFunction::getToken(Stream *str) {
break;
}
str->getChar();
codeString->append(c);
}
}
return s;
......
......@@ -43,10 +43,24 @@ public:
virtual Function *copy() = 0;
// Return the function type:
// -1 : identity
// 0 : sampled
// 2 : exponential
// 3 : stitching
// 4 : PostScript
virtual int getType() = 0;
// Return size of input and output tuples.
int getInputSize() { return m; }
int getOutputSize() { return n; }
double getDomainMin(int i) { return domain[i][0]; }
double getDomainMax(int i) { return domain[i][1]; }
double getRangeMin(int i) { return range[i][0]; }
double getRangeMax(int i) { return range[i][1]; }
GBool getHasRange() { return hasRange; }
// Transform an input tuple into an output tuple.
virtual void transform(double *in, double *out) = 0;
......@@ -72,6 +86,7 @@ public:
IdentityFunction();
virtual ~IdentityFunction();
virtual Function *copy() { return new IdentityFunction(); }
virtual int getType() { return -1; }
virtual void transform(double *in, double *out);
virtual GBool isOk() { return gTrue; }
......@@ -88,9 +103,17 @@ public:
SampledFunction(Object *funcObj, Dict *dict);
virtual ~SampledFunction();
virtual Function *copy() { return new SampledFunction(this); }
virtual int getType() { return 0; }
virtual void transform(double *in, double *out);
virtual GBool isOk() { return ok; }
int getSampleSize(int i) { return sampleSize[i]; }
double getEncodeMin(int i) { return encode[i][0]; }
double getEncodeMax(int i) { return encode[i][1]; }
double getDecodeMin(int i) { return decode[i][0]; }
double getDecodeMax(int i) { return decode[i][1]; }
double *getSamples() { return samples; }
private:
SampledFunction(SampledFunction *func);
......@@ -101,7 +124,11 @@ private:
encode[funcMaxInputs][2];
double // min and max values for range decoder
decode[funcMaxOutputs][2];
double // input multipliers
inputMul[funcMaxInputs];
int idxMul[funcMaxInputs]; // sample array index multipliers
double *samples; // the samples
int nSamples; // size of the samples array
GBool ok;
};
......@@ -115,9 +142,14 @@ public:
ExponentialFunction(Object *funcObj, Dict *dict);
virtual ~ExponentialFunction();
virtual Function *copy() { return new ExponentialFunction(this); }
virtual int getType() { return 2; }
virtual void transform(double *in, double *out);
virtual GBool isOk() { return ok; }
double *getC0() { return c0; }
double *getC1() { return c1; }
double getE() { return e; }
private:
ExponentialFunction(ExponentialFunction *func);
......@@ -138,9 +170,15 @@ public:
StitchingFunction(Object *funcObj, Dict *dict);
virtual ~StitchingFunction();
virtual Function *copy() { return new StitchingFunction(this); }
virtual int getType() { return 3; }
virtual void transform(double *in, double *out);
virtual GBool isOk() { return ok; }
int getNumFuncs() { return k; }
Function *getFunc(int i) { return funcs[i]; }
double *getBounds() { return bounds; }
double *getEncode() { return encode; }
private:
StitchingFunction(StitchingFunction *func);
......@@ -162,9 +200,12 @@ public:
PostScriptFunction(Object *funcObj, Dict *dict);
virtual ~PostScriptFunction();
virtual Function *copy() { return new PostScriptFunction(this); }
virtual int getType() { return 4; }
virtual void transform(double *in, double *out);
virtual GBool isOk() { return ok; }
GooString *getCodeString() { return codeString; }
private:
PostScriptFunction(PostScriptFunction *func);
......@@ -173,6 +214,7 @@ private:
void resizeCode(int newSize);
void exec(PSStack *stack, int codePtr);
GooString *codeString;
PSObject *code;
int codeSize;
GBool ok;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment