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 <[email protected]> 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; } _______________________________________________ poppler mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/poppler
