[poppler] poppler/GfxState.cc poppler/GfxState.h poppler/SplashOutputDev.cc

Albert Astals Cid aacid at kemper.freedesktop.org
Thu Mar 24 13:05:37 PDT 2011


 poppler/GfxState.cc        |  248 ++++++++++++++++++++++++++++++++++++++++++---
 poppler/GfxState.h         |   22 +++
 poppler/SplashOutputDev.cc |   43 +------
 3 files changed, 265 insertions(+), 48 deletions(-)

New commits:
commit e9350899e77c28452c48b56349ad7758b3fd47ba
Author: Albert Astals Cid <aacid at kde.org>
Date:   Thu Mar 24 20:09:18 2011 +0000

    Introduce splash-friendly getRGBLine functions
    
    So it does not need to pack and unpack the color again and again

diff --git a/poppler/GfxState.cc b/poppler/GfxState.cc
index 8db57b2..893540f 100644
--- a/poppler/GfxState.cc
+++ b/poppler/GfxState.cc
@@ -528,6 +528,23 @@ void GfxDeviceGrayColorSpace::getRGBLine(Guchar *in, unsigned int *out,
     out[i] = (in[i] << 16) | (in[i] << 8) | (in[i] << 0);
 }
 
+void GfxDeviceGrayColorSpace::getRGBLine(Guchar *in, Guchar *out, int length) {
+  for (int i = 0; i < length; i++) {
+    *out++ = in[i];
+    *out++ = in[i];
+    *out++ = in[i];
+  }
+}
+
+void GfxDeviceGrayColorSpace::getRGBXLine(Guchar *in, Guchar *out, int length) {
+  for (int i = 0; i < length; i++) {
+    *out++ = in[i];
+    *out++ = in[i];
+    *out++ = in[i];
+    *out++ = 255;
+  }
+}
+
 void GfxDeviceGrayColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
   cmyk->c = cmyk->m = cmyk->y = 0;
   cmyk->k = clip01(gfxColorComp1 - color->c[0]);
@@ -791,6 +808,22 @@ void GfxDeviceRGBColorSpace::getRGBLine(Guchar *in, unsigned int *out,
     out[i] = (p[0] << 16) | (p[1] << 8) | (p[2] << 0);
 }
 
+void GfxDeviceRGBColorSpace::getRGBLine(Guchar *in, Guchar *out, int length) {
+  for (int i = 0; i < length; i++) {
+    *out++ = *in++;
+    *out++ = *in++;
+    *out++ = *in++;
+  }
+}
+
+void GfxDeviceRGBColorSpace::getRGBXLine(Guchar *in, Guchar *out, int length) {
+  for (int i = 0; i < length; i++) {
+    *out++ = *in++;
+    *out++ = *in++;
+    *out++ = *in++;
+    *out++ = 255;
+  }
+}
 void GfxDeviceRGBColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
   GfxColorComp c, m, y, k;
 
@@ -1086,23 +1119,52 @@ void GfxDeviceCMYKColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
   rgb->b = clip01(dblToCol(b));
 }
 
+static inline void GfxDeviceCMYKColorSpacegetRGBLineHelper(Guchar *&in, double &r, double &g, double &b)
+{
+  double c, m, y, k, c1, m1, y1, k1;
+  
+  c = byteToDbl(*in++);
+  m = byteToDbl(*in++);
+  y = byteToDbl(*in++);
+  k = byteToDbl(*in++);
+  c1 = 1 - c;
+  m1 = 1 - m;
+  y1 = 1 - y;
+  k1 = 1 - k;
+  cmykToRGBMatrixMultiplication(c, m, y, k, c1, m1, y1, k1, r, g, b);
+}
+
 void GfxDeviceCMYKColorSpace::getRGBLine(Guchar *in, unsigned int *out, int length)
 {
-  double c, m, y, k, c1, m1, y1, k1, r, g, b;
+  double r, g, b;
+  for (int i = 0; i < length; i++) {
+    GfxDeviceCMYKColorSpacegetRGBLineHelper(in, r, g, b);
+    *out++ = (dblToByte(clip01(r)) << 16) | (dblToByte(clip01(g)) << 8) | dblToByte(clip01(b));
+  }
+}
+
+void GfxDeviceCMYKColorSpace::getRGBLine(Guchar *in, Guchar *out, int length)
+{
+  double r, g, b;
   
-  Guchar *inp = in;
   for (int i = 0; i < length; i++) {
-    c = byteToDbl(*inp++);
-    m = byteToDbl(*inp++);
-    y = byteToDbl(*inp++);
-    k = byteToDbl(*inp++);
-    c1 = 1 - c;
-    m1 = 1 - m;
-    y1 = 1 - y;
-    k1 = 1 - k;
-    cmykToRGBMatrixMultiplication(c, m, y, k, c1, m1, y1, k1, r, g, b);
+    GfxDeviceCMYKColorSpacegetRGBLineHelper(in, r, g, b);
+    *out++ = dblToByte(clip01(r));
+    *out++ = dblToByte(clip01(g));
+    *out++ = dblToByte(clip01(b));
+  }
+}
+
+void GfxDeviceCMYKColorSpace::getRGBXLine(Guchar *in, Guchar *out, int length)
+{
+  double r, g, b;
   
-    *out++ = (dblToByte(clip01(r)) << 16) | (dblToByte(clip01(g)) << 8) | dblToByte(clip01(b));
+  for (int i = 0; i < length; i++) {
+    GfxDeviceCMYKColorSpacegetRGBLineHelper(in, r, g, b);
+    *out++ = dblToByte(clip01(r));
+    *out++ = dblToByte(clip01(g));
+    *out++ = dblToByte(clip01(b));
+    *out++ = 255;
   }
 }
 
@@ -1651,6 +1713,47 @@ void GfxICCBasedColorSpace::getRGBLine(Guchar *in, unsigned int *out,
 #endif
 }
 
+void GfxICCBasedColorSpace::getRGBLine(Guchar *in, Guchar *out, int length) {
+#ifdef USE_CMS
+  if (lineTransform != 0) {
+    Guchar* tmp = (Guchar *)gmallocn(3 * length, sizeof(Guchar));
+    lineTransform->doTransform(in, tmp, length);
+    Guchar *current = tmp;
+    for (int i = 0; i < length; ++i) {
+        *out++ = *current++;
+        *out++ = *current++;
+        *out++ = *current++;
+    }
+    gfree(tmp);
+  } else {
+    alt->getRGBLine(in, out, length);
+  }
+#else
+  alt->getRGBLine(in, out, length);
+#endif
+}
+
+void GfxICCBasedColorSpace::getRGBXLine(Guchar *in, Guchar *out, int length) {
+#ifdef USE_CMS
+  if (lineTransform != 0) {
+    Guchar* tmp = (Guchar *)gmallocn(3 * length, sizeof(Guchar));
+    lineTransform->doTransform(in, tmp, length);
+    Guchar *current = tmp;
+    for (int i = 0; i < length; ++i) {
+        *out++ = *current++;
+        *out++ = *current++;
+        *out++ = *current++;
+        *out++ = 255;
+    }
+    gfree(tmp);
+  } else {
+    alt->getRGBXLine(in, out, length);
+  }
+#else
+  alt->getRGBXLine(in, out, length);
+#endif
+}
+
 void GfxICCBasedColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
 #ifdef USE_CMS
   if (transform != NULL && displayPixelType == PT_CMYK) {
@@ -1871,6 +1974,38 @@ void GfxIndexedColorSpace::getRGBLine(Guchar *in, unsigned int *out, int length)
   gfree (line);
 }
 
+void GfxIndexedColorSpace::getRGBLine(Guchar *in, Guchar *out, int length)
+{
+  Guchar *line;
+  int i, j, n;
+
+  n = base->getNComps();
+  line = (Guchar *) gmallocn (length, n);
+  for (i = 0; i < length; i++)
+    for (j = 0; j < n; j++)
+      line[i * n + j] = lookup[in[i] * n + j];
+
+  base->getRGBLine(line, out, length);
+
+  gfree (line);
+}
+
+void GfxIndexedColorSpace::getRGBXLine(Guchar *in, Guchar *out, int length)
+{
+  Guchar *line;
+  int i, j, n;
+
+  n = base->getNComps();
+  line = (Guchar *) gmallocn (length, n);
+  for (i = 0; i < length; i++)
+    for (j = 0; j < n; j++)
+      line[i * n + j] = lookup[in[i] * n + j];
+
+  base->getRGBXLine(line, out, length);
+
+  gfree (line);
+}
+
 void GfxIndexedColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
   GfxColor color2;
 
@@ -4888,6 +5023,95 @@ void GfxImageColorMap::getRGBLine(Guchar *in, unsigned int *out, int length) {
 
 }
 
+void GfxImageColorMap::getRGBLine(Guchar *in, Guchar *out, int length) {
+  int i, j;
+  Guchar *inp, *tmp_line;
+
+  if (!useRGBLine()) {
+    GfxRGB rgb;
+
+    inp = in;
+    for (i = 0; i < length; i++) {
+      getRGB (inp, &rgb);
+      *out++ = colToByte(rgb.r);
+      *out++ = colToByte(rgb.g);
+      *out++ = colToByte(rgb.b);
+      inp += nComps;
+    }
+    return;
+  }
+
+  switch (colorSpace->getMode()) {
+  case csIndexed:
+  case csSeparation:
+    tmp_line = (Guchar *) gmallocn (length, nComps2);
+    for (i = 0; i < length; i++) {
+      for (j = 0; j < nComps2; j++) {
+	tmp_line[i * nComps2 + j] = byte_lookup[in[i] * nComps2 + j];
+      }
+    }
+    colorSpace2->getRGBLine(tmp_line, out, length);
+    gfree (tmp_line);
+    break;
+
+  default:
+    inp = in;
+    for (j = 0; j < length; j++)
+      for (i = 0; i < nComps; i++) {
+	*inp = byte_lookup[*inp * nComps + i];
+	inp++;
+      }
+    colorSpace->getRGBLine(in, out, length);
+    break;
+  }
+
+}
+
+void GfxImageColorMap::getRGBXLine(Guchar *in, Guchar *out, int length) {
+  int i, j;
+  Guchar *inp, *tmp_line;
+
+  if (!useRGBLine()) {
+    GfxRGB rgb;
+
+    inp = in;
+    for (i = 0; i < length; i++) {
+      getRGB (inp, &rgb);
+      *out++ = colToByte(rgb.r);
+      *out++ = colToByte(rgb.g);
+      *out++ = colToByte(rgb.b);
+      *out++ = 255;
+      inp += nComps;
+    }
+    return;
+  }
+
+  switch (colorSpace->getMode()) {
+  case csIndexed:
+  case csSeparation:
+    tmp_line = (Guchar *) gmallocn (length, nComps2);
+    for (i = 0; i < length; i++) {
+      for (j = 0; j < nComps2; j++) {
+	tmp_line[i * nComps2 + j] = byte_lookup[in[i] * nComps2 + j];
+      }
+    }
+    colorSpace2->getRGBXLine(tmp_line, out, length);
+    gfree (tmp_line);
+    break;
+
+  default:
+    inp = in;
+    for (j = 0; j < length; j++)
+      for (i = 0; i < nComps; i++) {
+	*inp = byte_lookup[*inp * nComps + i];
+	inp++;
+      }
+    colorSpace->getRGBXLine(in, out, length);
+    break;
+  }
+
+}
+
 void GfxImageColorMap::getCMYK(Guchar *x, GfxCMYK *cmyk) {
   GfxColor color;
   int i;
diff --git a/poppler/GfxState.h b/poppler/GfxState.h
index 19594ed..099b41c 100644
--- a/poppler/GfxState.h
+++ b/poppler/GfxState.h
@@ -199,12 +199,14 @@ public:
   virtual void getGray(GfxColor *color, GfxGray *gray) = 0;
   virtual void getRGB(GfxColor *color, GfxRGB *rgb) = 0;
   virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk) = 0;
-  virtual void getGrayLine(Guchar * /*in*/, Guchar * /*out*/, int /*length*/) {}
-  virtual void getRGBLine(Guchar * /*in*/, unsigned int * /*out*/, int /*length*/) {}
+  virtual void getGrayLine(Guchar * /*in*/, Guchar * /*out*/, int /*length*/) { error(-1, "GfxColorSpace::getGrayLine this should not happen"); }
+  virtual void getRGBLine(Guchar * /*in*/, unsigned int * /*out*/, int /*length*/) { error(-1, "GfxColorSpace::getRGBLine (first variant) this should not happen"); }
+  virtual void getRGBLine(Guchar * /*in*/, Guchar * /*out*/, int /*length*/) {  error(-1, "GfxColorSpace::getRGBLine (second variant) this should not happen"); }
+  virtual void getRGBXLine(Guchar * /*in*/, Guchar * /*out*/, int /*length*/) {  error(-1, "GfxColorSpace::getRGBXLine this should not happen"); }
 
-  // Does this ColorSpace use getRGBLine?
+  // Does this ColorSpace support getRGBLine?
   virtual GBool useGetRGBLine() { return gFalse; }
-  // Does this ColorSpace use getGrayLine?
+  // Does this ColorSpace support getGrayLine?
   virtual GBool useGetGrayLine() { return gFalse; }
 
   // Return the number of color components.
@@ -257,6 +259,8 @@ public:
   virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
   virtual void getGrayLine(Guchar *in, Guchar *out, int length);
   virtual void getRGBLine(Guchar *in, unsigned int *out, int length);
+  virtual void getRGBLine(Guchar *in, Guchar *out, int length);
+  virtual void getRGBXLine(Guchar *in, Guchar *out, int length);
 
   virtual GBool useGetRGBLine() { return gTrue; }
   virtual GBool useGetGrayLine() { return gTrue; }
@@ -324,6 +328,8 @@ public:
   virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
   virtual void getGrayLine(Guchar *in, Guchar *out, int length);
   virtual void getRGBLine(Guchar *in, unsigned int *out, int length);
+  virtual void getRGBLine(Guchar *in, Guchar *out, int length);
+  virtual void getRGBXLine(Guchar *in, Guchar *out, int length);
 
   virtual GBool useGetRGBLine() { return gTrue; }
   virtual GBool useGetGrayLine() { return gTrue; }
@@ -394,6 +400,8 @@ public:
   virtual void getRGB(GfxColor *color, GfxRGB *rgb);
   virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
   virtual void getRGBLine(Guchar *in, unsigned int *out, int length);
+  virtual void getRGBLine(Guchar *, Guchar *out, int length);
+  virtual void getRGBXLine(Guchar *in, Guchar *out, int length);
   virtual GBool useGetRGBLine() { return gTrue; }
 
   virtual int getNComps() { return 4; }
@@ -468,6 +476,8 @@ public:
   virtual void getRGB(GfxColor *color, GfxRGB *rgb);
   virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
   virtual void getRGBLine(Guchar *in, unsigned int *out, int length);
+  virtual void getRGBLine(Guchar *in, Guchar *out, int length);
+  virtual void getRGBXLine(Guchar *in, Guchar *out, int length);
 
   virtual GBool useGetRGBLine();
 
@@ -511,6 +521,8 @@ public:
   virtual void getRGB(GfxColor *color, GfxRGB *rgb);
   virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
   virtual void getRGBLine(Guchar *in, unsigned int *out, int length);
+  virtual void getRGBLine(Guchar *in, Guchar *out, int length);
+  virtual void getRGBXLine(Guchar *in, Guchar *out, int length);
 
   virtual GBool useGetRGBLine() { return gTrue; }
 
@@ -1073,6 +1085,8 @@ public:
   void getGray(Guchar *x, GfxGray *gray);
   void getRGB(Guchar *x, GfxRGB *rgb);
   void getRGBLine(Guchar *in, unsigned int *out, int length);
+  void getRGBLine(Guchar *in, Guchar *out, int length);
+  void getRGBXLine(Guchar *in, Guchar *out, int length);
   void getGrayLine(Guchar *in, Guchar *out, int length);
   void getCMYK(Guchar *x, GfxCMYK *cmyk);
   void getColor(Guchar *x, GfxColor *color);
diff --git a/poppler/SplashOutputDev.cc b/poppler/SplashOutputDev.cc
index fd4c8a7..baa0ef9 100644
--- a/poppler/SplashOutputDev.cc
+++ b/poppler/SplashOutputDev.cc
@@ -2429,40 +2429,19 @@ GBool SplashOutputDev::imageSrc(void *data, SplashColorPtr colorLine,
 	imgData->colorMap->getGray(p, &gray);
 	*q++ = colToByte(gray);
       }
-	break;
-	case splashModeXBGR8:
+      break;
     case splashModeRGB8:
     case splashModeBGR8:
-      if (!imgData->colorMap->useRGBLine())
-      {
-        GfxRGB rgb;
-        for (x = 0, p = imgData->imgStr->getLine(), q = colorLine;
-           x < imgData->width;
-           ++x, p += nComps) {
-          imgData->colorMap->getRGB(p, &rgb);
-          *q++ = colToByte(rgb.r);
-          *q++ = colToByte(rgb.g);
-          *q++ = colToByte(rgb.b);
-          if (imgData->colorMode == splashModeXBGR8) *q++ = 255;
-        }
-      }
-      else
-      {
-        p = imgData->imgStr->getLine();
-        q = colorLine;
-        unsigned int* line = (unsigned int *)gmallocn(imgData->width, sizeof(unsigned int));
-
-        imgData->colorMap->getRGBLine(p, line, imgData->width);
-        for (x = 0; x < imgData->width; ++x) {
-            *q++ = (line[x] >> 16) & 255;
-            *q++ = (line[x] >> 8) & 255;
-            *q++ = (line[x]) & 255;
-            if (imgData->colorMode == splashModeXBGR8) {
-                *q++ = 255;
-            }
-        }
-        gfree(line);
-      }
+      p = imgData->imgStr->getLine();
+      q = colorLine;
+
+      imgData->colorMap->getRGBLine(p, colorLine, imgData->width);
+      break;
+    case splashModeXBGR8:
+      p = imgData->imgStr->getLine();
+      q = colorLine;
+
+      imgData->colorMap->getRGBXLine(p, colorLine, imgData->width);
       break;
 #if SPLASH_CMYK
     case splashModeCMYK8:


More information about the poppler mailing list