X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=pdf2swf%2Fxpdf%2FFunction.cc;h=f6996412a8bbb60965c531bfb3f45ef1fc427b4d;hb=51b0cb1e76475df853a3e9c8c8430fff9b971ab3;hp=64ea60c1902e6bbbcc8b7e3e3b0ef21ceb993fa6;hpb=3df3a8d12d7a516579a4eae276b077c015df0f70;p=swftools.git diff --git a/pdf2swf/xpdf/Function.cc b/pdf2swf/xpdf/Function.cc index 64ea60c..f699641 100644 --- a/pdf2swf/xpdf/Function.cc +++ b/pdf2swf/xpdf/Function.cc @@ -2,15 +2,16 @@ // // Function.cc // -// Copyright 2001-2002 Glyph & Cog, LLC +// Copyright 2001-2003 Glyph & Cog, LLC // //======================================================================== -#ifdef __GNUC__ +#include + +#ifdef USE_GCC_PRAGMAS #pragma implementation #endif -#include #include #include #include @@ -184,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; @@ -227,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()) { @@ -263,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() && @@ -295,7 +304,7 @@ SampledFunction::SampledFunction(Object *funcObj, Dict *dict) { nSamples = n; for (i = 0; i < m; ++i) nSamples *= sampleSize[i]; - samples = (double *)gmalloc(nSamples * sizeof(double)); + samples = (double *)gmallocn(nSamples, sizeof(double)); buf = 0; bits = 0; bitMask = (1 << sampleBits) - 1; @@ -341,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 *)gmalloc(nSamples * sizeof(double)); + 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 @@ -379,24 +385,22 @@ void SampledFunction::transform(double *in, double *out) { // pull 2^m values out of the sample array for (j = 0; j < (1<= 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<>= 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]) { @@ -411,7 +415,6 @@ void SampledFunction::transform(double *in, double *out) { ExponentialFunction::ExponentialFunction(Object *funcObj, Dict *dict) { Object obj1, obj2; - GBool hasN; int i; ok = gFalse; @@ -424,23 +427,14 @@ ExponentialFunction::ExponentialFunction(Object *funcObj, Dict *dict) { error(-1, "Exponential function with more than one input"); goto err1; } - hasN = hasRange; - - //----- default values - for (i = 0; i < funcMaxOutputs; ++i) { - c0[i] = 0; - c1[i] = 1; - } //----- C0 if (dict->lookup("C0", &obj1)->isArray()) { - if (!hasN) { - n = obj1.arrayGetLength(); - hasN = gTrue; - } else if (obj1.arrayGetLength() != n) { + if (hasRange && obj1.arrayGetLength() != n) { error(-1, "Function's C0 array is wrong length"); goto err2; } + n = obj1.arrayGetLength(); for (i = 0; i < n; ++i) { obj1.arrayGet(i, &obj2); if (!obj2.isNum()) { @@ -450,15 +444,19 @@ ExponentialFunction::ExponentialFunction(Object *funcObj, Dict *dict) { c0[i] = obj2.getNum(); obj2.free(); } + } else { + if (hasRange && n != 1) { + error(-1, "Function's C0 array is wrong length"); + goto err2; + } + n = 1; + c0[0] = 0; } obj1.free(); //----- C1 if (dict->lookup("C1", &obj1)->isArray()) { - if (!hasN) { - n = obj1.arrayGetLength(); - hasN = gTrue; - } else if (obj1.arrayGetLength() != n) { + if (obj1.arrayGetLength() != n) { error(-1, "Function's C1 array is wrong length"); goto err2; } @@ -471,6 +469,12 @@ ExponentialFunction::ExponentialFunction(Object *funcObj, Dict *dict) { c1[i] = obj2.getNum(); obj2.free(); } + } else { + if (n != 1) { + error(-1, "Function's C1 array is wrong length"); + goto err2; + } + c1[0] = 1; } obj1.free(); @@ -482,13 +486,6 @@ ExponentialFunction::ExponentialFunction(Object *funcObj, Dict *dict) { e = obj1.getNum(); obj1.free(); - // this isn't supposed to happen, but I've run into (broken) PDF - // files where it does - if (!hasN) { - error(-1, "Exponential function does not define number of output values"); - n = 1; - } - ok = gTrue; return; @@ -559,9 +556,9 @@ StitchingFunction::StitchingFunction(Object *funcObj, Dict *dict) { goto err1; } k = obj1.arrayGetLength(); - funcs = (Function **)gmalloc(k * sizeof(Function *)); - bounds = (double *)gmalloc((k + 1) * sizeof(double)); - encode = (double *)gmalloc(2 * k * sizeof(double)); + funcs = (Function **)gmallocn(k, sizeof(Function *)); + bounds = (double *)gmallocn(k + 1, sizeof(double)); + encode = (double *)gmallocn(2 * k, sizeof(double)); for (i = 0; i < k; ++i) { funcs[i] = NULL; } @@ -622,12 +619,16 @@ StitchingFunction::StitchingFunction(Object *funcObj, Dict *dict) { } StitchingFunction::StitchingFunction(StitchingFunction *func) { + int i; + k = func->k; - funcs = (Function **)gmalloc(k * sizeof(Function *)); - memcpy(funcs, func->funcs, k * sizeof(Function *)); - bounds = (double *)gmalloc((k + 1) * sizeof(double)); + funcs = (Function **)gmallocn(k, sizeof(Function *)); + for (i = 0; i < k; ++i) { + funcs[i] = func->funcs[i]->copy(); + } + bounds = (double *)gmallocn(k + 1, sizeof(double)); memcpy(bounds, func->bounds, (k + 1) * sizeof(double)); - encode = (double *)gmalloc(2 * k * sizeof(double)); + encode = (double *)gmallocn(2 * k, sizeof(double)); memcpy(encode, func->encode, 2 * k * sizeof(double)); ok = gTrue; } @@ -635,9 +636,11 @@ StitchingFunction::StitchingFunction(StitchingFunction *func) { StitchingFunction::~StitchingFunction() { int i; - for (i = 0; i < k; ++i) { - if (funcs[i]) { - delete funcs[i]; + if (funcs) { + for (i = 0; i < k; ++i) { + if (funcs[i]) { + delete funcs[i]; + } } } gfree(funcs); @@ -916,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; @@ -990,6 +997,7 @@ PostScriptFunction::PostScriptFunction(Object *funcObj, Dict *dict) { str = funcObj->getStream(); //----- parse the function + codeString = new GString(); str->reset(); if (!(tok = getToken(str)) || tok->cmp("{")) { error(-1, "Expected '{' at start of PostScript function"); @@ -1015,12 +1023,14 @@ PostScriptFunction::PostScriptFunction(Object *funcObj, Dict *dict) { PostScriptFunction::PostScriptFunction(PostScriptFunction *func) { memcpy(this, func, sizeof(PostScriptFunction)); - code = (PSObject *)gmalloc(codeSize * sizeof(PSObject)); + 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) { @@ -1095,14 +1105,14 @@ GBool PostScriptFunction::parseCode(Stream *str, int *codePtr) { if (!parseCode(str, codePtr)) { return gFalse; } + delete tok; + if (!(tok = getToken(str))) { + error(-1, "Unexpected end of PostScript function stream"); + return gFalse; + } } else { elsePtr = -1; } - delete tok; - if (!(tok = getToken(str))) { - error(-1, "Unexpected end of PostScript function stream"); - return gFalse; - } if (!tok->cmp("if")) { if (elsePtr >= 0) { error(-1, "Got 'if' operator with two blocks in PostScript function"); @@ -1174,6 +1184,9 @@ GString *PostScriptFunction::getToken(Stream *str) { s = new GString(); do { c = str->getChar(); + if (c != EOF) { + codeString->append(c); + } } while (c != EOF && isspace(c)); if (c == '{' || c == '}') { s->append((char)c); @@ -1185,6 +1198,7 @@ GString *PostScriptFunction::getToken(Stream *str) { break; } str->getChar(); + codeString->append(c); } } else { while (1) { @@ -1194,6 +1208,7 @@ GString *PostScriptFunction::getToken(Stream *str) { break; } str->getChar(); + codeString->append(c); } } return s; @@ -1202,7 +1217,7 @@ GString *PostScriptFunction::getToken(Stream *str) { void PostScriptFunction::resizeCode(int newSize) { if (newSize >= codeSize) { codeSize += 64; - code = (PSObject *)grealloc(code, codeSize * sizeof(PSObject)); + code = (PSObject *)greallocn(code, codeSize, sizeof(PSObject)); } } @@ -1247,7 +1262,7 @@ void PostScriptFunction::exec(PSStack *stack, int codePtr) { } else { b2 = stack->popBool(); b1 = stack->popBool(); - stack->pushReal(b1 && b2); + stack->pushBool(b1 && b2); } break; case psOpAtan: @@ -1314,8 +1329,8 @@ void PostScriptFunction::exec(PSStack *stack, int codePtr) { stack->roll(2, 1); break; case psOpExp: - r2 = stack->popInt(); - r1 = stack->popInt(); + r2 = stack->popNum(); + r1 = stack->popNum(); stack->pushReal(pow(r1, r2)); break; case psOpFalse: @@ -1427,7 +1442,7 @@ void PostScriptFunction::exec(PSStack *stack, int codePtr) { if (stack->topIsInt()) { stack->pushInt(~stack->popInt()); } else { - stack->pushReal(!stack->popBool()); + stack->pushBool(!stack->popBool()); } break; case psOpOr: @@ -1438,7 +1453,7 @@ void PostScriptFunction::exec(PSStack *stack, int codePtr) { } else { b2 = stack->popBool(); b1 = stack->popBool(); - stack->pushReal(b1 || b2); + stack->pushBool(b1 || b2); } break; case psOpPop: @@ -1456,7 +1471,7 @@ void PostScriptFunction::exec(PSStack *stack, int codePtr) { } break; case psOpSin: - stack->pushReal(cos(stack->popNum())); + stack->pushReal(sin(stack->popNum())); break; case psOpSqrt: stack->pushReal(sqrt(stack->popNum())); @@ -1489,7 +1504,7 @@ void PostScriptFunction::exec(PSStack *stack, int codePtr) { } else { b2 = stack->popBool(); b1 = stack->popBool(); - stack->pushReal(b1 ^ b2); + stack->pushBool(b1 ^ b2); } break; case psOpIf: