[poppler] 2 commits - qt4/src qt5/src splash/SplashBitmap.cc splash/SplashBitmap.h
Albert Astals Cid
aacid at kemper.freedesktop.org
Thu Aug 27 13:58:18 PDT 2015
qt4/src/poppler-page.cc | 42 ++++++++++++++---------------------------
qt5/src/poppler-page.cc | 42 ++++++++++++++---------------------------
splash/SplashBitmap.cc | 49 +++++++++++++++++++++++++++++++++++++-----------
splash/SplashBitmap.h | 11 ++++++++--
4 files changed, 77 insertions(+), 67 deletions(-)
New commits:
commit 6e469dbe239714b478488af5ff73046e6a46a908
Author: Adam Reichold <adam.reichold at t-online.de>
Date: Sun Aug 16 21:05:38 2015 +0200
Change default Qt frontend image format
Change the default image format used by the Qt frontends to XBGR/RGB32
which allows efficient blending and pixmap conversion via Qt. Also use
the premultiplied conversion for IgnorePaperColor to elide a further
copy for pixmap conversion.
diff --git a/qt4/src/poppler-page.cc b/qt4/src/poppler-page.cc
index e965ee8..16a18f1 100644
--- a/qt4/src/poppler-page.cc
+++ b/qt4/src/poppler-page.cc
@@ -327,11 +327,7 @@ QImage Page::renderToImage(double xres, double yres, int x, int y, int w, int h,
bgColor[2] = m_page->parentDoc->paperColor.red();
}
- SplashColorMode colorMode = splashModeRGB8;
-
- const bool ignorePaperColor = m_page->parentDoc->m_hints & Document::IgnorePaperColor;
- if (ignorePaperColor) colorMode = splashModeXBGR8;
-
+ SplashColorMode colorMode = splashModeXBGR8;
#if SPLASH_CMYK
if (overprintPreview) colorMode = splashModeDeviceN8;
#endif
@@ -340,6 +336,8 @@ QImage Page::renderToImage(double xres, double yres, int x, int y, int w, int h,
if (m_page->parentDoc->m_hints & Document::ThinLineShape) thinLineMode = splashThinLineShape;
if (m_page->parentDoc->m_hints & Document::ThinLineSolid) thinLineMode = splashThinLineSolid;
+ const bool ignorePaperColor = m_page->parentDoc->m_hints & Document::IgnorePaperColor;
+
SplashOutputDev splash_output(
colorMode, 4,
gFalse,
@@ -367,45 +365,31 @@ QImage Page::renderToImage(double xres, double yres, int x, int y, int w, int h,
// If we use DeviceN8, convert to XBGR8.
// If requested, also transfer Splash's internal alpha channel.
- if (overprintPreview || ignorePaperColor) {
- const SplashBitmap::ConversionMode mode = ignorePaperColor
- ? SplashBitmap::conversionAlpha
- : SplashBitmap::conversionOpaque;
-
- if (bitmap->convertToXBGR(mode)) {
- SplashColorPtr data = bitmap->getDataPtr();
-
- if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
- // Convert byte order from RGBX to XBGR.
- for (int i = 0; i < bh; ++i) {
- for (int j = 0; j < bw; ++j) {
- SplashColorPtr pixel = &data[i * brs + j];
-
- qSwap(pixel[0], pixel[3]);
- qSwap(pixel[1], pixel[2]);
- }
- }
- }
+ const SplashBitmap::ConversionMode mode = ignorePaperColor
+ ? SplashBitmap::conversionAlphaPremultiplied
+ : SplashBitmap::conversionOpaque;
- // Construct a Qt image sharing the raw bitmap data.
- img = QImage(data, bw, bh, brs, QImage::Format_ARGB32).copy();
- }
- } else {
+ const QImage::Format format = ignorePaperColor
+ ? QImage::Format_ARGB32_Premultiplied
+ : QImage::Format_RGB32;
+
+ if (bitmap->convertToXBGR(mode)) {
SplashColorPtr data = bitmap->getDataPtr();
if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
- // Convert byte order from BGR to RGB.
+ // Convert byte order from RGBX to XBGR.
for (int i = 0; i < bh; ++i) {
for (int j = 0; j < bw; ++j) {
SplashColorPtr pixel = &data[i * brs + j];
- qSwap(pixel[0], pixel[2]);
+ qSwap(pixel[0], pixel[3]);
+ qSwap(pixel[1], pixel[2]);
}
}
}
// Construct a Qt image sharing the raw bitmap data.
- img = QImage(data, bw, bh, brs, QImage::Format_RGB888).copy();
+ img = QImage(data, bw, bh, brs, format).copy();
}
#endif
break;
diff --git a/qt5/src/poppler-page.cc b/qt5/src/poppler-page.cc
index 58cea3a..3832861 100644
--- a/qt5/src/poppler-page.cc
+++ b/qt5/src/poppler-page.cc
@@ -327,11 +327,7 @@ QImage Page::renderToImage(double xres, double yres, int x, int y, int w, int h,
bgColor[2] = m_page->parentDoc->paperColor.red();
}
- SplashColorMode colorMode = splashModeRGB8;
-
- const bool ignorePaperColor = m_page->parentDoc->m_hints & Document::IgnorePaperColor;
- if (ignorePaperColor) colorMode = splashModeXBGR8;
-
+ SplashColorMode colorMode = splashModeXBGR8;
#if SPLASH_CMYK
if (overprintPreview) colorMode = splashModeDeviceN8;
#endif
@@ -340,6 +336,8 @@ QImage Page::renderToImage(double xres, double yres, int x, int y, int w, int h,
if (m_page->parentDoc->m_hints & Document::ThinLineShape) thinLineMode = splashThinLineShape;
if (m_page->parentDoc->m_hints & Document::ThinLineSolid) thinLineMode = splashThinLineSolid;
+ const bool ignorePaperColor = m_page->parentDoc->m_hints & Document::IgnorePaperColor;
+
SplashOutputDev splash_output(
colorMode, 4,
gFalse,
@@ -367,45 +365,31 @@ QImage Page::renderToImage(double xres, double yres, int x, int y, int w, int h,
// If we use DeviceN8, convert to XBGR8.
// If requested, also transfer Splash's internal alpha channel.
- if (overprintPreview || ignorePaperColor) {
- const SplashBitmap::ConversionMode mode = ignorePaperColor
- ? SplashBitmap::conversionAlpha
- : SplashBitmap::conversionOpaque;
-
- if (bitmap->convertToXBGR(mode)) {
- SplashColorPtr data = bitmap->takeData();
-
- if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
- // Convert byte order from RGBX to XBGR.
- for (int i = 0; i < bh; ++i) {
- for (int j = 0; j < bw; ++j) {
- SplashColorPtr pixel = &data[i * brs + j];
-
- qSwap(pixel[0], pixel[3]);
- qSwap(pixel[1], pixel[2]);
- }
- }
- }
+ const SplashBitmap::ConversionMode mode = ignorePaperColor
+ ? SplashBitmap::conversionAlphaPremultiplied
+ : SplashBitmap::conversionOpaque;
- // Construct a Qt image holding (and also owning) the raw bitmap data.
- img = QImage(data, bw, bh, brs, QImage::Format_ARGB32, gfree, data);
- }
- } else {
+ const QImage::Format format = ignorePaperColor
+ ? QImage::Format_ARGB32_Premultiplied
+ : QImage::Format_RGB32;
+
+ if (bitmap->convertToXBGR(mode)) {
SplashColorPtr data = bitmap->takeData();
if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
- // Convert byte order from BGR to RGB.
+ // Convert byte order from RGBX to XBGR.
for (int i = 0; i < bh; ++i) {
for (int j = 0; j < bw; ++j) {
SplashColorPtr pixel = &data[i * brs + j];
- qSwap(pixel[0], pixel[2]);
+ qSwap(pixel[0], pixel[3]);
+ qSwap(pixel[1], pixel[2]);
}
}
}
// Construct a Qt image holding (and also owning) the raw bitmap data.
- img = QImage(data, bw, bh, brs, QImage::Format_RGB888, gfree, data);
+ img = QImage(data, bw, bh, brs, format, gfree, data);
}
#endif
break;
commit 56fc0bb2f20adfd89835f3132bfef3033fdcd80d
Author: Adam Reichold <adam.reichold at t-online.de>
Date: Sun Aug 16 21:01:52 2015 +0200
Add premultiplied alpha channel to SplashBitmap
This extends the convertToXBGR method so that it can either
* leave the alpha channel of the bitmap data opaque,
* copy the alpha channel into the bitmap data,
* transfer the alpha channel into the bitmap data and
perform premultiplication on the bitmap data.
diff --git a/qt4/src/poppler-page.cc b/qt4/src/poppler-page.cc
index 292f960..e965ee8 100644
--- a/qt4/src/poppler-page.cc
+++ b/qt4/src/poppler-page.cc
@@ -368,7 +368,11 @@ QImage Page::renderToImage(double xres, double yres, int x, int y, int w, int h,
// If we use DeviceN8, convert to XBGR8.
// If requested, also transfer Splash's internal alpha channel.
if (overprintPreview || ignorePaperColor) {
- if (bitmap->convertToXBGR(ignorePaperColor)) {
+ const SplashBitmap::ConversionMode mode = ignorePaperColor
+ ? SplashBitmap::conversionAlpha
+ : SplashBitmap::conversionOpaque;
+
+ if (bitmap->convertToXBGR(mode)) {
SplashColorPtr data = bitmap->getDataPtr();
if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
diff --git a/qt5/src/poppler-page.cc b/qt5/src/poppler-page.cc
index 8e071c1..58cea3a 100644
--- a/qt5/src/poppler-page.cc
+++ b/qt5/src/poppler-page.cc
@@ -368,7 +368,11 @@ QImage Page::renderToImage(double xres, double yres, int x, int y, int w, int h,
// If we use DeviceN8, convert to XBGR8.
// If requested, also transfer Splash's internal alpha channel.
if (overprintPreview || ignorePaperColor) {
- if (bitmap->convertToXBGR(ignorePaperColor)) {
+ const SplashBitmap::ConversionMode mode = ignorePaperColor
+ ? SplashBitmap::conversionAlpha
+ : SplashBitmap::conversionOpaque;
+
+ if (bitmap->convertToXBGR(mode)) {
SplashColorPtr data = bitmap->takeData();
if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
diff --git a/splash/SplashBitmap.cc b/splash/SplashBitmap.cc
index c905c97..7c14b31 100644
--- a/splash/SplashBitmap.cc
+++ b/splash/SplashBitmap.cc
@@ -461,7 +461,7 @@ void SplashBitmap::getRGBLine(int yl, SplashColorPtr line) {
}
}
-void SplashBitmap::getXBGRLine(int yl, SplashColorPtr line, bool useAlpha) {
+void SplashBitmap::getXBGRLine(int yl, SplashColorPtr line, ConversionMode conversionMode) {
SplashColor col;
double c, m, y, k, c1, m1, y1, k1, r, g, b;
@@ -501,16 +501,34 @@ void SplashBitmap::getXBGRLine(int yl, SplashColorPtr line, bool useAlpha) {
y1 = 1 - y;
k1 = 1 - k;
cmykToRGBMatrixMultiplication(c, m, y, k, c1, m1, y1, k1, r, g, b);
- *line++ = dblToByte(clip01(b));
- *line++ = dblToByte(clip01(g));
- *line++ = dblToByte(clip01(r));
- *line++ = useAlpha ? getAlpha(x, yl) : 255;
+
+ if (conversionMode == conversionAlphaPremultiplied) {
+ const double a = getAlpha(x, yl) / 255.0;
+
+ *line++ = dblToByte(clip01(b * a));
+ *line++ = dblToByte(clip01(g * a));
+ *line++ = dblToByte(clip01(r * a));
+ } else {
+ *line++ = dblToByte(clip01(b));
+ *line++ = dblToByte(clip01(g));
+ *line++ = dblToByte(clip01(r));
+ }
+
+ if (conversionMode != conversionOpaque) {
+ *line++ = getAlpha(x, yl);
+ } else {
+ *line++ = 255;
+ }
}
}
-GBool SplashBitmap::convertToXBGR(bool useAlpha) {
+static inline Guchar div255(int x) {
+ return (Guchar)((x + (x >> 8) + 0x80) >> 8);
+}
+
+GBool SplashBitmap::convertToXBGR(ConversionMode conversionMode) {
if (mode == splashModeXBGR8) {
- if (useAlpha) {
+ if (conversionMode != conversionOpaque) {
// Copy the alpha channel into the fourth component so that XBGR becomes ABGR.
const SplashColorPtr dbegin = data;
const SplashColorPtr dend = data + rowSize * height;
@@ -518,11 +536,20 @@ GBool SplashBitmap::convertToXBGR(bool useAlpha) {
Guchar *const abegin = alpha;
Guchar *const aend = alpha + width * height;
- SplashColorPtr d = dbegin + 3;
+ SplashColorPtr d = dbegin;
Guchar *a = abegin;
- for(; d < dend && a < aend; d += 4, a += 1) {
- *d = *a;
+ if (conversionMode == conversionAlphaPremultiplied) {
+ for (; d < dend && a < aend; d += 4, a += 1) {
+ d[0] = div255(d[0] * *a);
+ d[1] = div255(d[1] * *a);
+ d[2] = div255(d[2] * *a);
+ d[3] = *a;
+ }
+ } else {
+ for (d += 3; d < dend && a < aend; d += 4, a += 1) {
+ *d = *a;
+ }
}
}
@@ -534,7 +561,7 @@ GBool SplashBitmap::convertToXBGR(bool useAlpha) {
if (newdata != NULL) {
for (int y = 0; y < height; y++) {
unsigned char *row = newdata + y * newrowSize;
- getXBGRLine(y, row, useAlpha);
+ getXBGRLine(y, row, conversionMode);
}
if (rowSize < 0) {
gfree(data + (height - 1) * rowSize);
diff --git a/splash/SplashBitmap.h b/splash/SplashBitmap.h
index 9fa7613..4417af7 100644
--- a/splash/SplashBitmap.h
+++ b/splash/SplashBitmap.h
@@ -76,11 +76,18 @@ public:
SplashError writeImgFile(SplashImageFileFormat format, FILE *f, int hDPI, int vDPI, const char *compressionString = "");
SplashError writeImgFile(ImgWriter *writer, FILE *f, int hDPI, int vDPI);
- GBool convertToXBGR(bool useAlpha = false);
+ enum ConversionMode
+ {
+ conversionOpaque,
+ conversionAlpha,
+ conversionAlphaPremultiplied
+ };
+
+ GBool convertToXBGR(ConversionMode conversionMode = conversionOpaque);
void getPixel(int x, int y, SplashColorPtr pixel);
void getRGBLine(int y, SplashColorPtr line);
- void getXBGRLine(int y, SplashColorPtr line, bool useAlpha = false);
+ void getXBGRLine(int y, SplashColorPtr line, ConversionMode conversionMode = conversionOpaque);
#if SPLASH_CMYK
void getCMYKLine(int y, SplashColorPtr line);
#endif
More information about the poppler
mailing list