poppler/CharCodeToUnicode.cc | 123 ++++++++++++++++++++++++++++++++++--------- poppler/CharCodeToUnicode.h | 4 + splash/SplashMath.h | 10 +++ splash/SplashScreen.cc | 89 ++++++++++--------------------- splash/SplashScreen.h | 14 ++++ splash/SplashXPath.cc | 5 - splash/SplashXPath.h | 1 7 files changed, 155 insertions(+), 91 deletions(-)
New commits: commit df942e25bff9b014bde0ff69c8a01fa3c1963015 Author: Albert Astals Cid <[email protected]> Date: Thu Sep 1 01:08:10 2011 +0200 xpdf303: More parsing flexibility diff --git a/poppler/CharCodeToUnicode.cc b/poppler/CharCodeToUnicode.cc index 4792db7..4befdc8 100644 --- a/poppler/CharCodeToUnicode.cc +++ b/poppler/CharCodeToUnicode.cc @@ -291,13 +291,12 @@ void CharCodeToUnicode::parseCMap1(int (*getCharFunc)(void *), void *data, int nBits) { PSTokenizer *pst; char tok1[256], tok2[256], tok3[256]; - int nDigits, n1, n2, n3; + int n1, n2, n3; CharCode i; CharCode maxCode, code1, code2; GooString *name; FILE *f; - nDigits = nBits / 4; maxCode = (nBits == 8) ? 0xff : (nBits == 16) ? 0xffff : 0xffffffff; pst = new PSTokenizer(getCharFunc, data); pst->getToken(tok1, sizeof(tok1), &n1); @@ -325,13 +324,10 @@ void CharCodeToUnicode::parseCMap1(int (*getCharFunc)(void *), void *data, error(errSyntaxWarning, -1, "Illegal entry in bfchar block in ToUnicode CMap"); break; } - if (!(n1 == 2 + nDigits && tok1[0] == '<' && tok1[n1 - 1] == '>' && + if (!(tok1[0] == '<' && tok1[n1 - 1] == '>' && tok2[0] == '<' && tok2[n2 - 1] == '>')) { - if (!(n1 == 4 + nDigits && tok1[0] == '<' && tok1[n1 - 1] == '>' && tok1[1] == '0' && tok1[2] == '0' && - tok2[0] == '<' && tok2[n2 - 1] == '>')) { - error(errSyntaxWarning, -1, "Illegal entry in bfchar block in ToUnicode CMap"); - continue; - } + error(errSyntaxWarning, -1, "Illegal entry in bfchar block in ToUnicode CMap"); + continue; } tok1[n1 - 1] = tok2[n2 - 1] = '\0'; if (!parseHex(tok1 + 1, n1 - 2, &code1)) { @@ -357,10 +353,8 @@ void CharCodeToUnicode::parseCMap1(int (*getCharFunc)(void *), void *data, error(errSyntaxWarning, -1, "Illegal entry in bfrange block in ToUnicode CMap"); break; } - if (!(((n1 == 2 + nDigits && tok1[0] == '<' && tok1[n1 - 1] == '>') || - (n1 == 4 + nDigits && tok1[0] == '<' && tok1[n1 - 1] == '>' && tok1[1] == '0' && tok1[2] == '0')) && - ((n2 == 2 + nDigits && tok2[0] == '<' && tok2[n2 - 1] == '>') || - (n2 == 4 + nDigits && tok2[0] == '<' && tok2[n2 - 1] == '>' && tok1[1] == '0' && tok1[2] == '0')))) { + if (!(tok1[0] == '<' && tok1[n1 - 1] == '>' && + tok2[0] == '<' && tok2[n2 - 1] == '>')) { error(errSyntaxWarning, -1, "Illegal entry in bfrange block in ToUnicode CMap"); continue; } commit 5305dfc5702e8004e5ae35697c6aebd0b1a5c96e Author: Albert Astals Cid <[email protected]> Date: Thu Sep 1 01:05:02 2011 +0200 xpdf303: Make sure codes are inside the range diff --git a/poppler/CharCodeToUnicode.cc b/poppler/CharCodeToUnicode.cc index cc69b8a..4792db7 100644 --- a/poppler/CharCodeToUnicode.cc +++ b/poppler/CharCodeToUnicode.cc @@ -293,11 +293,12 @@ void CharCodeToUnicode::parseCMap1(int (*getCharFunc)(void *), void *data, char tok1[256], tok2[256], tok3[256]; int nDigits, n1, n2, n3; CharCode i; - CharCode code1, code2; + CharCode maxCode, code1, code2; GooString *name; FILE *f; nDigits = nBits / 4; + maxCode = (nBits == 8) ? 0xff : (nBits == 16) ? 0xffff : 0xffffffff; pst = new PSTokenizer(getCharFunc, data); pst->getToken(tok1, sizeof(tok1), &n1); while (pst->getToken(tok2, sizeof(tok2), &n2)) { @@ -337,6 +338,10 @@ void CharCodeToUnicode::parseCMap1(int (*getCharFunc)(void *), void *data, error(errSyntaxWarning, -1, "Illegal entry in bfchar block in ToUnicode CMap"); continue; } + if (code1 > maxCode) { + error(errSyntaxWarning, -1, + "Invalid entry in bfchar block in ToUnicode CMap"); + } addMapping(code1, tok2 + 1, n2 - 2, 0); } pst->getToken(tok1, sizeof(tok1), &n1); @@ -365,6 +370,16 @@ void CharCodeToUnicode::parseCMap1(int (*getCharFunc)(void *), void *data, error(errSyntaxWarning, -1, "Illegal entry in bfrange block in ToUnicode CMap"); continue; } + if (code1 > maxCode || code2 > maxCode) { + error(errSyntaxWarning, -1, + "Invalid entry in bfrange block in ToUnicode CMap"); + if (code1 > maxCode) { + code1 = maxCode; + } + if (code2 > maxCode) { + code2 = maxCode; + } + } if (!strcmp(tok3, "[")) { i = 0; while (pst->getToken(tok1, sizeof(tok1), &n1) && commit 45212483572c68abd612b5c62b21cbb545e10143 Author: Albert Astals Cid <[email protected]> Date: Thu Sep 1 01:01:13 2011 +0200 xpdf303: change mapLen growing stragegy diff --git a/poppler/CharCodeToUnicode.cc b/poppler/CharCodeToUnicode.cc index 5f2b9d6..cc69b8a 100644 --- a/poppler/CharCodeToUnicode.cc +++ b/poppler/CharCodeToUnicode.cc @@ -411,7 +411,10 @@ void CharCodeToUnicode::addMapping(CharCode code, char *uStr, int n, } if (code >= mapLen) { oldLen = mapLen; - mapLen = (code + 256) & ~255; + mapLen = mapLen ? 2 * mapLen : 256; + if (code >= mapLen) { + mapLen = (code + 256) & ~255; + } if (unlikely(code >= mapLen)) { error(errSyntaxWarning, -1, "Illegal code value in CharCodeToUnicode::addMapping"); return; commit 75d70f190e97f69047cdbe97a872a936788392d9 Author: Albert Astals Cid <[email protected]> Date: Thu Sep 1 01:00:23 2011 +0200 xpdf303: Limit code to 0xffffff diff --git a/poppler/CharCodeToUnicode.cc b/poppler/CharCodeToUnicode.cc index e34f71f..5f2b9d6 100644 --- a/poppler/CharCodeToUnicode.cc +++ b/poppler/CharCodeToUnicode.cc @@ -404,6 +404,11 @@ void CharCodeToUnicode::addMapping(CharCode code, char *uStr, int n, Unicode u; int j; + if (code > 0xffffff) { + // This is an arbitrary limit to avoid integer overflow issues. + // (I've seen CMaps with mappings for <ffffffff>.) + return; + } if (code >= mapLen) { oldLen = mapLen; mapLen = (code + 256) & ~255; commit b4180a187f9246b6390df112e5536ead9ef9bcbe Author: Albert Astals Cid <[email protected]> Date: Thu Sep 1 00:59:09 2011 +0200 xpdf303: Use parseHex instead of sscanf diff --git a/poppler/CharCodeToUnicode.cc b/poppler/CharCodeToUnicode.cc index d88891e..e34f71f 100644 --- a/poppler/CharCodeToUnicode.cc +++ b/poppler/CharCodeToUnicode.cc @@ -188,7 +188,7 @@ CharCodeToUnicode *CharCodeToUnicode::parseUnicodeToUnicode( while (getLine(buf, sizeof(buf), f)) { ++line; if (!(tok = strtok_r(buf, " \t\r\n", &tokptr)) || - sscanf(tok, "%x", &u0) != 1) { + !parseHex(tok, strlen(tok), &u0)) { error(errSyntaxWarning, -1, "Bad line ({0:d}) in unicodeToUnicode file '{1:t}'", line, fileName); continue; @@ -200,7 +200,7 @@ CharCodeToUnicode *CharCodeToUnicode::parseUnicodeToUnicode( uBufSize += 8; uBuf = (Unicode *)greallocn(uBuf, uBufSize, sizeof(Unicode)); } - if (sscanf(tok, "%x", &uBuf[n]) != 1) { + if (!parseHex(tok, strlen(tok), &uBuf[n])) { error(errSyntaxWarning, -1, "Bad line ({0:d}) in unicodeToUnicode file '{1:t}'", line, fileName); break; @@ -333,7 +333,7 @@ void CharCodeToUnicode::parseCMap1(int (*getCharFunc)(void *), void *data, } } tok1[n1 - 1] = tok2[n2 - 1] = '\0'; - if (sscanf(tok1 + 1, "%x", &code1) != 1) { + if (!parseHex(tok1 + 1, n1 - 2, &code1)) { error(errSyntaxWarning, -1, "Illegal entry in bfchar block in ToUnicode CMap"); continue; } @@ -360,8 +360,8 @@ void CharCodeToUnicode::parseCMap1(int (*getCharFunc)(void *), void *data, continue; } tok1[n1 - 1] = tok2[n2 - 1] = '\0'; - if (sscanf(tok1 + 1, "%x", &code1) != 1 || - sscanf(tok2 + 1, "%x", &code2) != 1) { + if (!parseHex(tok1 + 1, n1 - 2, &code1) || + !parseHex(tok2 + 1, n2 - 2, &code2)) { error(errSyntaxWarning, -1, "Illegal entry in bfrange block in ToUnicode CMap"); continue; } @@ -402,7 +402,6 @@ void CharCodeToUnicode::addMapping(CharCode code, char *uStr, int n, int offset) { CharCode oldLen, i; Unicode u; - char uHex[5]; int j; if (code >= mapLen) { @@ -419,7 +418,7 @@ void CharCodeToUnicode::addMapping(CharCode code, char *uStr, int n, } } if (n <= 4) { - if (sscanf(uStr, "%x", &u) != 1) { + if (!parseHex(uStr, n, &u)) { error(errSyntaxWarning, -1, "Illegal entry in ToUnicode CMap"); return; } @@ -435,10 +434,9 @@ void CharCodeToUnicode::addMapping(CharCode code, char *uStr, int n, sMap[sMapLen].len = n / 4; sMap[sMapLen].u = (Unicode*)gmallocn(sMap[sMapLen].len, sizeof(Unicode)); for (j = 0; j < sMap[sMapLen].len; ++j) { - strncpy(uHex, uStr + j*4, 4); - uHex[4] = '\0'; - if (sscanf(uHex, "%x", &sMap[sMapLen].u[j]) != 1) { + if (!parseHex(uStr + j*4, 4, &sMap[sMapLen].u[j])) { error(errSyntaxWarning, -1, "Illegal entry in ToUnicode CMap"); + return; } } sMap[sMapLen].u[sMap[sMapLen].len - 1] += offset; commit 121f648f233adcdc631c7e29d67b60baa922e29a Author: Albert Astals Cid <[email protected]> Date: Thu Sep 1 00:28:40 2011 +0200 Add helper parseHex function diff --git a/poppler/CharCodeToUnicode.cc b/poppler/CharCodeToUnicode.cc index 903aa17..d88891e 100644 --- a/poppler/CharCodeToUnicode.cc +++ b/poppler/CharCodeToUnicode.cc @@ -73,6 +73,41 @@ static int getCharFromFile(void *data) { //------------------------------------------------------------------------ +static int hexCharVals[256] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0x + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 1x + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 2x + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, // 3x + -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 4x + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 5x + -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 6x + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 7x + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 8x + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 9x + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // Ax + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // Bx + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // Cx + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // Dx + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // Ex + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 // Fx +}; + +// Parse a <len>-byte hex string <s> into *<val>. Returns false on +// error. +static GBool parseHex(char *s, int len, Guint *val) { + int i, x; + + *val = 0; + for (i = 0; i < len; ++i) { + x = hexCharVals[s[i] & 0xff]; + if (x < 0) { + return gFalse; + } + *val = (*val << 4) + x; + } + return gTrue; +} + //------------------------------------------------------------------------ CharCodeToUnicode *CharCodeToUnicode::makeIdentityMapping() { commit be0436ace671070bab4304efee607f40c959bc55 Author: Albert Astals Cid <[email protected]> Date: Thu Sep 1 00:26:57 2011 +0200 xpdf303: CharCodeToUnicode::makeIdentityMapping & friends diff --git a/poppler/CharCodeToUnicode.cc b/poppler/CharCodeToUnicode.cc index b4f2f18..903aa17 100644 --- a/poppler/CharCodeToUnicode.cc +++ b/poppler/CharCodeToUnicode.cc @@ -73,6 +73,12 @@ static int getCharFromFile(void *data) { //------------------------------------------------------------------------ +//------------------------------------------------------------------------ + +CharCodeToUnicode *CharCodeToUnicode::makeIdentityMapping() { + return new CharCodeToUnicode(); +} + CharCodeToUnicode *CharCodeToUnicode::parseCIDToUnicode(GooString *fileName, GooString *collection) { FILE *f; @@ -405,6 +411,18 @@ void CharCodeToUnicode::addMapping(CharCode code, char *uStr, int n, } } +CharCodeToUnicode::CharCodeToUnicode() { + tag = NULL; + map = NULL; + mapLen = 0; + sMap = NULL; + sMapLen = sMapSize = 0; + refCnt = 1; +#if MULTITHREADED + gInitMutex(&mutex); +#endif +} + CharCodeToUnicode::CharCodeToUnicode(GooString *tagA) { CharCode i; @@ -489,6 +507,9 @@ GBool CharCodeToUnicode::match(GooString *tagA) { void CharCodeToUnicode::setMapping(CharCode c, Unicode *u, int len) { int i, j; + if (!map) { + return; + } if (len == 1) { map[c] = u[0]; } else { @@ -519,6 +540,10 @@ void CharCodeToUnicode::setMapping(CharCode c, Unicode *u, int len) { int CharCodeToUnicode::mapToUnicode(CharCode c, Unicode **u) { int i; + if (!map) { + *u[0] = (Unicode)c; + return 1; + } if (c >= mapLen) { return 0; } diff --git a/poppler/CharCodeToUnicode.h b/poppler/CharCodeToUnicode.h index 3fdbf0f..edc53f2 100644 --- a/poppler/CharCodeToUnicode.h +++ b/poppler/CharCodeToUnicode.h @@ -48,6 +48,9 @@ class CharCodeToUnicode { friend class UnicodeToCharCode; public: + // Create an identity mapping (Unicode = CharCode). + static CharCodeToUnicode *makeIdentityMapping(); + // Read the CID-to-Unicode mapping for <collection> from the file // specified by <fileName>. Sets the initial reference count to 1. // Returns NULL on failure. @@ -96,6 +99,7 @@ private: void parseCMap1(int (*getCharFunc)(void *), void *data, int nBits); void addMapping(CharCode code, char *uStr, int n, int offset); + CharCodeToUnicode(); CharCodeToUnicode(GooString *tagA); CharCodeToUnicode(GooString *tagA, Unicode *mapA, CharCode mapLenA, GBool copyMap, commit 5dd94447b14db1894f06ad0590187dae7575e33a Author: Albert Astals Cid <[email protected]> Date: Thu Sep 1 00:15:59 2011 +0200 xpdf303: Remove unused constructor diff --git a/splash/SplashXPath.cc b/splash/SplashXPath.cc index c51c908..d3ed03b 100644 --- a/splash/SplashXPath.cc +++ b/splash/SplashXPath.cc @@ -65,11 +65,6 @@ inline void SplashXPath::transform(SplashCoord *matrix, // SplashXPath //------------------------------------------------------------------------ -SplashXPath::SplashXPath() { - segs = NULL; - length = size = 0; -} - SplashXPath::SplashXPath(SplashPath *path, SplashCoord *matrix, SplashCoord flatness, GBool closeSubpaths) { SplashPathHint *hint; diff --git a/splash/SplashXPath.h b/splash/SplashXPath.h index 64c4796..6b0dd4f 100644 --- a/splash/SplashXPath.h +++ b/splash/SplashXPath.h @@ -70,7 +70,6 @@ public: protected: - SplashXPath(); SplashXPath(SplashXPath *xPath); void transform(SplashCoord *matrix, SplashCoord xi, SplashCoord yi, SplashCoord *xo, SplashCoord *yo); commit d00d56e4a46e8534378534de0d94ce0551d75d84 Author: Albert Astals Cid <[email protected]> Date: Thu Sep 1 00:11:49 2011 +0200 xpdf303: Speedup SplashScreen By using << instead of * and by putting some functions on the header so they can be inlined diff --git a/splash/SplashScreen.cc b/splash/SplashScreen.cc index 40f2466..d741246 100644 --- a/splash/SplashScreen.cc +++ b/splash/SplashScreen.cc @@ -78,41 +78,38 @@ SplashScreen::SplashScreen(SplashScreenParams *params) { void SplashScreen::createMatrix() { - Guchar u, black, white; - int i; + Guchar u; + int black, white, i; SplashScreenParams *params = screenParams; + // size must be a power of 2, and at least 2 + for (size = 2, log2Size = 1; size < params->size; size <<= 1, ++log2Size) ; + switch (params->type) { case splashScreenDispersed: - // size must be a power of 2 - for (size = 1; size < params->size; size <<= 1) ; mat = (Guchar *)gmallocn(size * size, sizeof(Guchar)); buildDispersedMatrix(size/2, size/2, 1, size/2, 1); break; case splashScreenClustered: - // size must be even - size = (params->size >> 1) << 1; - if (size < 2) { - size = 2; - } mat = (Guchar *)gmallocn(size * size, sizeof(Guchar)); buildClusteredMatrix(); break; case splashScreenStochasticClustered: // size must be at least 2*r - if (params->size < 2 * params->dotRadius) { - size = 2 * params->dotRadius; - } else { - size = params->size; + while (size < (params->dotRadius << 1)) { + size <<= 1; + ++log2Size; } mat = (Guchar *)gmallocn(size * size, sizeof(Guchar)); buildSCDMatrix(params->dotRadius); break; } + + sizeM1 = size - 1; // do gamma correction and compute minVal/maxVal minVal = 255; @@ -131,9 +128,9 @@ void SplashScreen::createMatrix() u = splashRound((SplashCoord)255.0 * splashPow((SplashCoord)mat[i] / 255.0, params->gamma)); if (u < black) { - u = black; + u = (Guchar)black; } else if (u >= white) { - u = white; + u = (Guchar)white; } mat[i] = u; if (u < minVal) { @@ -148,7 +145,7 @@ void SplashScreen::buildDispersedMatrix(int i, int j, int val, int delta, int offset) { if (delta == 0) { // map values in [1, size^2] --> [1, 255] - mat[i * size + j] = 1 + (254 * (val - 1)) / (size * size - 1); + mat[(i << log2Size) + j] = 1 + (254 * (val - 1)) / (size * size - 1); } else { buildDispersedMatrix(i, j, val, delta / 2, 4*offset); @@ -172,7 +169,7 @@ void SplashScreen::buildClusteredMatrix() { // initialize the threshold matrix for (y = 0; y < size; ++y) { for (x = 0; x < size; ++x) { - mat[y * size + x] = 0; + mat[(y << log2Size) + x] = 0; } } @@ -204,14 +201,12 @@ void SplashScreen::buildClusteredMatrix() { } // build the threshold matrix - minVal = 1; - maxVal = 0; x1 = y1 = 0; // make gcc happy for (i = 0; i < size * size2; ++i) { d = -1; for (y = 0; y < size; ++y) { for (x = 0; x < size2; ++x) { - if (mat[y * size + x] == 0 && + if (mat[(y << log2Size) + x] == 0 && dist[y * size2 + x] > d) { x1 = x; y1 = y; @@ -221,12 +216,12 @@ void SplashScreen::buildClusteredMatrix() { } // map values in [0, 2*size*size2-1] --> [1, 255] val = 1 + (254 * (2*i)) / (2*size*size2 - 1); - mat[y1 * size + x1] = val; + mat[(y1 << log2Size) + x1] = val; val = 1 + (254 * (2*i+1)) / (2*size*size2 - 1); if (y1 < size2) { - mat[(y1 + size2) * size + x1 + size2] = val; + mat[((y1 + size2) << log2Size) + x1 + size2] = val; } else { - mat[(y1 - size2) * size + x1 + size2] = val; + mat[((y1 - size2) << log2Size) + x1 + size2] = val; } } @@ -294,7 +289,7 @@ void SplashScreen::buildSCDMatrix(int r) { grid = (char *)gmallocn(size * size, sizeof(char)); for (y = 0; y < size; ++y) { for (x = 0; x < size; ++x) { - grid[y*size + x] = 0; + grid[(y << log2Size) + x] = 0; } } @@ -305,7 +300,7 @@ void SplashScreen::buildSCDMatrix(int r) { for (i = 0; i < size * size; ++i) { x = pts[i].x; y = pts[i].y; - if (!grid[y*size + x]) { + if (!grid[(y << log2Size) + x]) { if (dotsLen == dotsSize) { dotsSize *= 2; dots = (SplashScreenPoint *)greallocn(dots, dotsSize, @@ -319,10 +314,10 @@ void SplashScreen::buildSCDMatrix(int r) { if (tmpl[yy*(r+1) + xx]) { x0 = (x + xx) % size; x1 = (x - xx + size) % size; - grid[y0*size + x0] = 1; - grid[y0*size + x1] = 1; - grid[y1*size + x0] = 1; - grid[y1*size + x1] = 1; + grid[(y0 << log2Size) + x0] = 1; + grid[(y0 << log2Size) + x1] = 1; + grid[(y1 << log2Size) + x0] = 1; + grid[(y1 << log2Size) + x1] = 1; } } } @@ -346,8 +341,8 @@ void SplashScreen::buildSCDMatrix(int r) { dMin = d; } } - region[y*size + x] = iMin; - dist[y*size + x] = dMin; + region[(y << log2Size) + x] = iMin; + dist[(y << log2Size) + x] = dMin; } } @@ -356,7 +351,7 @@ void SplashScreen::buildSCDMatrix(int r) { n = 0; for (y = 0; y < size; ++y) { for (x = 0; x < size; ++x) { - if (region[y*size + x] == i) { + if (region[(y << log2Size) + x] == i) { pts[n].x = x; pts[n].y = y; pts[n].dist = distance(dots[i].x, dots[i].y, x, y); @@ -367,7 +362,7 @@ void SplashScreen::buildSCDMatrix(int r) { std::sort(pts, pts + n, cmpDistancesFunctor()); for (j = 0; j < n; ++j) { // map values in [0 .. n-1] --> [255 .. 1] - mat[pts[j].y * size + pts[j].x] = 255 - (254 * j) / (n - 1); + mat[(pts[j].y << log2Size) + pts[j].x] = 255 - (254 * j) / (n - 1); } } @@ -381,6 +376,8 @@ void SplashScreen::buildSCDMatrix(int r) { SplashScreen::SplashScreen(SplashScreen *screen) { screenParams = screen->screenParams; size = screen->size; + sizeM1 = screen->sizeM1; + log2Size = screen->log2Size; mat = (Guchar *)gmallocn(size * size, sizeof(Guchar)); memcpy(mat, screen->mat, size * size * sizeof(Guchar)); minVal = screen->minVal; @@ -390,29 +387,3 @@ SplashScreen::SplashScreen(SplashScreen *screen) { SplashScreen::~SplashScreen() { gfree(mat); } - -int SplashScreen::test(int x, int y, Guchar value) { - int xx, yy; - - if (mat == NULL) createMatrix(); - - if (value < minVal) { - return 0; - } - if (value >= maxVal) { - return 1; - } - if ((xx = x % size) < 0) { - xx = -xx; - } - if ((yy = y % size) < 0) { - yy = -yy; - } - return value < mat[yy * size + xx] ? 0 : 1; -} - -GBool SplashScreen::isStatic(Guchar value) { - if (mat == NULL) createMatrix(); - - return value < minVal || value >= maxVal; -} diff --git a/splash/SplashScreen.h b/splash/SplashScreen.h index fe3b5c8..a7fc455 100644 --- a/splash/SplashScreen.h +++ b/splash/SplashScreen.h @@ -27,6 +27,8 @@ #include "SplashTypes.h" +#include <stdlib.h> + //------------------------------------------------------------------------ // SplashScreen //------------------------------------------------------------------------ @@ -42,12 +44,18 @@ public: // Return the computed pixel value (0=black, 1=white) for the gray // level <value> at (<x>, <y>). - int test(int x, int y, Guchar value); + int test(int x, int y, Guchar value) { + int xx, yy; + if (mat == NULL) createMatrix(); + xx = x & sizeM1; + yy = y & sizeM1; + return value < mat[(yy << log2Size) + xx] ? 0 : 1; + } // Returns true if value is above the white threshold or below the // black threshold, i.e., if the corresponding halftone will be // solid white or black. - GBool isStatic(Guchar value); + GBool isStatic(Guchar value) { if (mat == NULL) createMatrix(); return value < minVal || value >= maxVal; } private: void createMatrix(); @@ -61,6 +69,8 @@ private: SplashScreenParams *screenParams; // params to create the other members Guchar *mat; // threshold matrix int size; // size of the threshold matrix + int sizeM1; // size - 1 + int log2Size; // log2(size) Guchar minVal; // any pixel value below minVal generates // solid black Guchar maxVal; // any pixel value above maxVal generates commit 5e8debf96ab1bb9db31a0332a482d08c181d52ea Author: Albert Astals Cid <[email protected]> Date: Wed Aug 31 23:56:52 2011 +0200 xpdf303: Add splashCheckDet helper diff --git a/splash/SplashMath.h b/splash/SplashMath.h index 272c90c..0749c78 100644 --- a/splash/SplashMath.h +++ b/splash/SplashMath.h @@ -114,4 +114,14 @@ static inline SplashCoord splashDist(SplashCoord x0, SplashCoord y0, #endif } +static inline GBool splashCheckDet(SplashCoord m11, SplashCoord m12, + SplashCoord m21, SplashCoord m22, + SplashCoord epsilon) { +#if USE_FIXEDPOINT + return FixedPoint::checkDet(m11, m12, m21, m22, epsilon); +#else + return fabs(m11 * m22 - m12 * m21) >= epsilon; +#endif +} + #endif _______________________________________________ poppler mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/poppler
