[poppler] Branch 'xpdf303merge' - 10 commits - poppler/CharCodeToUnicode.cc poppler/CharCodeToUnicode.h splash/SplashMath.h splash/SplashScreen.cc splash/SplashScreen.h splash/SplashXPath.cc splash/SplashXPath.h

Albert Astals Cid aacid at kemper.freedesktop.org
Wed Aug 31 16:09:52 PDT 2011


 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 <aacid at kde.org>
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 <aacid at kde.org>
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 <aacid at kde.org>
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 <aacid at kde.org>
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 <aacid at kde.org>
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 <aacid at kde.org>
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 <aacid at kde.org>
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 <aacid at kde.org>
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 <aacid at kde.org>
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 <aacid at kde.org>
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


More information about the poppler mailing list