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

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Sun Dec 13 22:21:15 UTC 2020


 poppler/DCTStream.cc |   66 +++++++++++++----------------
 poppler/DCTStream.h  |    1 
 poppler/GfxState.cc  |  116 ++++++++++++++++++++++++++++++++-------------------
 3 files changed, 105 insertions(+), 78 deletions(-)

New commits:
commit 0b879c21131c8c6cd5fb1a529cbb0551c8c48067
Author: viric <viric at viric.name>
Date:   Sun Dec 13 22:21:13 2020 +0000

    Faster routines for jpeg decoding
    
    linux 'perf' indicated a bottleneck in getChars

diff --git a/poppler/DCTStream.cc b/poppler/DCTStream.cc
index d43b7cc6..29287cd8 100644
--- a/poppler/DCTStream.cc
+++ b/poppler/DCTStream.cc
@@ -183,49 +183,45 @@ void DCTStream::reset()
     }
 }
 
-// we can not go with inline since gcc
-// refuses to inline because of setjmp
-#define DO_GET_CHAR                                                                                                                                                                                                                            \
-    if (current == limit) {                                                                                                                                                                                                                    \
-        if (cinfo.output_scanline < cinfo.output_height) {                                                                                                                                                                                     \
-            if (!setjmp(err.setjmp_buffer)) {                                                                                                                                                                                                  \
-                if (!jpeg_read_scanlines(&cinfo, row_buffer, 1))                                                                                                                                                                               \
-                    c = EOF;                                                                                                                                                                                                                   \
-                else {                                                                                                                                                                                                                         \
-                    current = &row_buffer[0][0];                                                                                                                                                                                               \
-                    limit = &row_buffer[0][(cinfo.output_width - 1) * cinfo.output_components] + cinfo.output_components;                                                                                                                      \
-                    c = *current;                                                                                                                                                                                                              \
-                    ++current;                                                                                                                                                                                                                 \
-                }                                                                                                                                                                                                                              \
-            } else                                                                                                                                                                                                                             \
-                c = EOF;                                                                                                                                                                                                                       \
-        } else                                                                                                                                                                                                                                 \
-            c = EOF;                                                                                                                                                                                                                           \
-    } else {                                                                                                                                                                                                                                   \
-        c = *current;                                                                                                                                                                                                                          \
-        ++current;                                                                                                                                                                                                                             \
-    }
+bool DCTStream::readLine()
+{
+    if (cinfo.output_scanline < cinfo.output_height) {
+        if (!setjmp(err.setjmp_buffer)) {
+            if (!jpeg_read_scanlines(&cinfo, row_buffer, 1))
+                return false;
+            else {
+                current = &row_buffer[0][0];
+                limit = &row_buffer[0][(cinfo.output_width - 1) * cinfo.output_components] + cinfo.output_components;
+                return true;
+            }
+        } else
+            return false;
+    } else
+        return false;
+}
 
 int DCTStream::getChar()
 {
-    int c;
+    if (current == limit)
+        if (!readLine())
+            return EOF;
 
-    DO_GET_CHAR
-
-    return c;
+    return *current++;
 }
 
 int DCTStream::getChars(int nChars, unsigned char *buffer)
 {
-    // Use volatile to prevent the compiler optimizing
-    // variables into registers. See setjmp man page.
-    volatile int i, c;
-    for (i = 0; i < nChars; ++i) {
-        DO_GET_CHAR
-        if (likely(c != EOF))
-            buffer[i] = c;
-        else
-            return i;
+    for (int i = 0; i < nChars;) {
+        if (current == limit) {
+            if (!readLine())
+                return i;
+        }
+        int left = limit - current;
+        if (nChars < left)
+            left = nChars;
+        memcpy(buffer + i, current, left);
+        current += left;
+        i += left;
     }
     return nChars;
 }
diff --git a/poppler/DCTStream.h b/poppler/DCTStream.h
index 7833d411..495ca0fc 100644
--- a/poppler/DCTStream.h
+++ b/poppler/DCTStream.h
@@ -70,6 +70,7 @@ private:
     void init();
 
     bool hasGetChars() override { return true; }
+    bool readLine();
     int getChars(int nChars, unsigned char *buffer) override;
 
     int colorXform;
diff --git a/poppler/GfxState.cc b/poppler/GfxState.cc
index 6b2644d7..4e5c7e5c 100644
--- a/poppler/GfxState.cc
+++ b/poppler/GfxState.cc
@@ -5460,7 +5460,7 @@ GfxImageColorMap::GfxImageColorMap(int bitsA, Object *decode, GfxColorSpace *col
         }
         break;
     default:
-        if (colorSpace->useGetGrayLine() || colorSpace->useGetRGBLine() || colorSpace->useGetCMYKLine() || colorSpace->useGetDeviceNLine()) {
+        if ((!decode->isNull() || maxPixel != 255) && (colorSpace->useGetGrayLine() || (colorSpace->useGetRGBLine() && !decode->isNull()) || colorSpace->useGetCMYKLine() || colorSpace->useGetDeviceNLine())) {
             byte_lookup = (unsigned char *)gmallocn((maxPixel + 1), nComps);
             useByteLookup = true;
         }
@@ -5612,7 +5612,10 @@ void GfxImageColorMap::getGrayLine(unsigned char *in, unsigned char *out, int le
         tmp_line = (unsigned char *)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];
+                unsigned char c = in[i];
+                if (byte_lookup)
+                    c = byte_lookup[c * nComps2 + j];
+                tmp_line[i * nComps2 + j] = c;
             }
         }
         colorSpace2->getGrayLine(tmp_line, out, length);
@@ -5620,12 +5623,14 @@ void GfxImageColorMap::getGrayLine(unsigned char *in, unsigned char *out, int le
         break;
 
     default:
-        inp = in;
-        for (j = 0; j < length; j++)
-            for (i = 0; i < nComps; i++) {
-                *inp = byte_lookup[*inp * nComps + i];
-                inp++;
-            }
+        if (byte_lookup) {
+            inp = in;
+            for (j = 0; j < length; j++)
+                for (i = 0; i < nComps; i++) {
+                    *inp = byte_lookup[*inp * nComps + i];
+                    inp++;
+                }
+        }
         colorSpace->getGrayLine(in, out, length);
         break;
     }
@@ -5654,7 +5659,10 @@ void GfxImageColorMap::getRGBLine(unsigned char *in, unsigned int *out, int leng
         tmp_line = (unsigned char *)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];
+                unsigned char c = in[i];
+                if (byte_lookup)
+                    c = byte_lookup[c * nComps2 + j];
+                tmp_line[i * nComps2 + j] = c;
             }
         }
         colorSpace2->getRGBLine(tmp_line, out, length);
@@ -5662,12 +5670,14 @@ void GfxImageColorMap::getRGBLine(unsigned char *in, unsigned int *out, int leng
         break;
 
     default:
-        inp = in;
-        for (j = 0; j < length; j++)
-            for (i = 0; i < nComps; i++) {
-                *inp = byte_lookup[*inp * nComps + i];
-                inp++;
-            }
+        if (byte_lookup) {
+            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;
     }
@@ -5698,7 +5708,10 @@ void GfxImageColorMap::getRGBLine(unsigned char *in, unsigned char *out, int len
         tmp_line = (unsigned char *)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];
+                unsigned char c = in[i];
+                if (byte_lookup)
+                    c = byte_lookup[c * nComps2 + j];
+                tmp_line[i * nComps2 + j] = c;
             }
         }
         colorSpace2->getRGBLine(tmp_line, out, length);
@@ -5706,12 +5719,14 @@ void GfxImageColorMap::getRGBLine(unsigned char *in, unsigned char *out, int len
         break;
 
     default:
-        inp = in;
-        for (j = 0; j < length; j++)
-            for (i = 0; i < nComps; i++) {
-                *inp = byte_lookup[*inp * nComps + i];
-                inp++;
-            }
+        if (byte_lookup) {
+            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;
     }
@@ -5743,7 +5758,10 @@ void GfxImageColorMap::getRGBXLine(unsigned char *in, unsigned char *out, int le
         tmp_line = (unsigned char *)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];
+                unsigned char c = in[i];
+                if (byte_lookup)
+                    c = byte_lookup[c * nComps2 + j];
+                tmp_line[i * nComps2 + j] = c;
             }
         }
         colorSpace2->getRGBXLine(tmp_line, out, length);
@@ -5751,12 +5769,14 @@ void GfxImageColorMap::getRGBXLine(unsigned char *in, unsigned char *out, int le
         break;
 
     default:
-        inp = in;
-        for (j = 0; j < length; j++)
-            for (i = 0; i < nComps; i++) {
-                *inp = byte_lookup[*inp * nComps + i];
-                inp++;
-            }
+        if (byte_lookup) {
+            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;
     }
@@ -5788,7 +5808,10 @@ void GfxImageColorMap::getCMYKLine(unsigned char *in, unsigned char *out, int le
         tmp_line = (unsigned char *)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];
+                unsigned char c = in[i];
+                if (byte_lookup)
+                    c = byte_lookup[c * nComps2 + j];
+                tmp_line[i * nComps2 + j] = c;
             }
         }
         colorSpace2->getCMYKLine(tmp_line, out, length);
@@ -5796,12 +5819,14 @@ void GfxImageColorMap::getCMYKLine(unsigned char *in, unsigned char *out, int le
         break;
 
     default:
-        inp = in;
-        for (j = 0; j < length; j++)
-            for (i = 0; i < nComps; i++) {
-                *inp = byte_lookup[*inp * nComps + i];
-                inp++;
-            }
+        if (byte_lookup) {
+            inp = in;
+            for (j = 0; j < length; j++)
+                for (i = 0; i < nComps; i++) {
+                    *inp = byte_lookup[*inp * nComps + i];
+                    inp++;
+                }
+        }
         colorSpace->getCMYKLine(in, out, length);
         break;
     }
@@ -5830,7 +5855,10 @@ void GfxImageColorMap::getDeviceNLine(unsigned char *in, unsigned char *out, int
         tmp_line = (unsigned char *)gmallocn(length, nComps2);
         for (int i = 0; i < length; i++) {
             for (int j = 0; j < nComps2; j++) {
-                tmp_line[i * nComps2 + j] = byte_lookup[in[i] * nComps2 + j];
+                unsigned char c = in[i];
+                if (byte_lookup)
+                    c = byte_lookup[c * nComps2 + j];
+                tmp_line[i * nComps2 + j] = c;
             }
         }
         colorSpace2->getDeviceNLine(tmp_line, out, length);
@@ -5838,12 +5866,14 @@ void GfxImageColorMap::getDeviceNLine(unsigned char *in, unsigned char *out, int
         break;
 
     default:
-        inp = in;
-        for (int j = 0; j < length; j++)
-            for (int i = 0; i < nComps; i++) {
-                *inp = byte_lookup[*inp * nComps + i];
-                inp++;
-            }
+        if (byte_lookup) {
+            inp = in;
+            for (int j = 0; j < length; j++)
+                for (int i = 0; i < nComps; i++) {
+                    *inp = byte_lookup[*inp * nComps + i];
+                    inp++;
+                }
+        }
         colorSpace->getDeviceNLine(in, out, length);
         break;
     }


More information about the poppler mailing list