diff options
| author | jghali <jghali@11d20701-8431-0410-a711-e3c959e3b870> | 2012-04-11 21:44:50 +0000 |
|---|---|---|
| committer | jghali <jghali@11d20701-8431-0410-a711-e3c959e3b870> | 2012-04-11 21:44:50 +0000 |
| commit | f714516a5030f6a4ce93768c47f63bca777dba39 (patch) | |
| tree | fd17ad89d38c33539acf2164179dd06e43d3b577 /scribus/scimage.cpp | |
| parent | f126c81ff6cb6d2bf5a17e9e706d3dbec262dd53 (diff) | |
| download | scribus-f714516a5030f6a4ce93768c47f63bca777dba39.tar.gz scribus-f714516a5030f6a4ce93768c47f63bca777dba39.tar.xz scribus-f714516a5030f6a4ce93768c47f63bca777dba39.zip | |
#$10510: PNGs with alpha/transparency render incorrectly in acroread when image resolution is changed
git-svn-id: svn://scribus.net/branches/Version14x/Scribus@17430 11d20701-8431-0410-a711-e3c959e3b870
Diffstat (limited to 'scribus/scimage.cpp')
| -rw-r--r-- | scribus/scimage.cpp | 201 |
1 files changed, 201 insertions, 0 deletions
diff --git a/scribus/scimage.cpp b/scribus/scimage.cpp index 905f1e7..6c789eb 100644 --- a/scribus/scimage.cpp +++ b/scribus/scimage.cpp @@ -1565,6 +1565,17 @@ bool ScImage::writePSImageToFilter(ScStreamFilter* filter, const QByteArray& mas void ScImage::scaleImage(int nwidth, int nheight) { + int depth = this->depth(); + if (depth == 32) + { + scaleImage32bpp(nwidth, nheight); + return; + } + scaleImageGeneric(nwidth, nheight); +} + +void ScImage::scaleImage32bpp(int nwidth, int nheight) +{ QImage dst(nwidth, nheight, QImage::Format_ARGB32); QRgb* xelrow = 0; QRgb* tempxelrow = 0; @@ -1581,6 +1592,14 @@ void ScImage::scaleImage(int nwidth, int nheight) long* gs; long* bs; int rowswritten = 0; + + int depth = this->depth(); + if (depth != 32) + { + QImage::operator=(QImage::scaled(nwidth, nheight, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); + return; + } + cols = width(); rows = height(); newcols = dst.width(); @@ -1771,6 +1790,188 @@ void ScImage::scaleImage(int nwidth, int nheight) return; } +void ScImage::scaleImageGeneric(int nwidth, int nheight) +{ + unsigned char* xelrow = 0; + unsigned char* tempxelrow = 0; + register unsigned char* xP; + register unsigned char* nxP; + int rows, cols, rowsread, newrows, newcols; + register int row, col, needtoreadrow; + const uchar maxval = 255; + double xscale, yscale; + long sxscale, syscale; + register long fracrowtofill, fracrowleft; + long* ps; + int rowswritten = 0; + + int depth = this->depth(); + Format imgFormat = this->format(); + bool execScaled = (depth == 1 || depth == 4 || depth == 16); + execScaled |= (imgFormat == QImage::Format_ARGB8565_Premultiplied); + execScaled |= (imgFormat == QImage::Format_RGB666); + execScaled |= (imgFormat == QImage::Format_ARGB6666_Premultiplied); + execScaled |= (imgFormat == QImage::Format_ARGB8555_Premultiplied); + if (execScaled) + { + QImage::operator=(QImage::scaled(nwidth, nheight, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); + return; + } + + QImage dst(nwidth, nheight, this->format()); + int nChannels = this->depth() / 8; + + cols = width(); + rows = height(); + newcols = dst.width(); + newrows = dst.height(); + long SCALE; + long HALFSCALE; + if (cols > 4096) + { + SCALE = 4096; + HALFSCALE = 2048; + } + else + { + int fac = 4096; + while ((cols * fac) > 4096) + { + fac /= 2; + } + SCALE = fac * cols; + HALFSCALE = fac * cols / 2; + } + xscale = (double) newcols / (double) cols; + yscale = (double) newrows / (double) rows; + sxscale = (long)(xscale * SCALE); + syscale = (long)(yscale * SCALE); + if ( newrows != rows ) /* shortcut Y scaling if possible */ + tempxelrow = new unsigned char[cols * nChannels]; + ps = new long[cols]; + + for (int chIndex = 0; chIndex < nChannels; ++chIndex) + { + xelrow = 0; + rowsread = rowswritten = 0; + fracrowleft = syscale; + needtoreadrow = 1; + for (col = 0; col < cols; ++col) + ps[col] = HALFSCALE; + fracrowtofill = SCALE; + for (row = 0; row < newrows; ++row) + { + if (newrows == rows) + tempxelrow = xelrow = scanLine(rowsread++); + else + { + while (fracrowleft < fracrowtofill) + { + if (needtoreadrow && rowsread < rows) + xelrow = scanLine(rowsread++); + for (col = 0, xP = xelrow + chIndex; col < cols; ++col, xP += nChannels) + ps[col] += fracrowleft * (*xP); + fracrowtofill -= fracrowleft; + fracrowleft = syscale; + needtoreadrow = 1; + } + if (needtoreadrow && rowsread < rows) + { + xelrow = scanLine(rowsread++); + needtoreadrow = 0; + } + register long p = 0; + xP = xelrow + chIndex; + nxP = tempxelrow + chIndex; + for (col = 0; col < cols; ++col, xP += nChannels, nxP += nChannels) + { + p = ps[col] + fracrowtofill * (*xP); + p /= SCALE; + if ( p > maxval ) p = maxval; + *nxP = (unsigned char) p; + ps[col] = HALFSCALE; + } + fracrowleft -= fracrowtofill; + if ( fracrowleft == 0 ) + { + fracrowleft = syscale; + needtoreadrow = 1; + } + fracrowtofill = SCALE; + } + if (newcols == cols) + { + memcpy(dst.scanLine(rowswritten++), tempxelrow, newcols * nChannels); + } + else + { + register long p; + register long fraccoltofill, fraccolleft = 0; + register int needcol; + nxP = dst.scanLine(rowswritten++) + chIndex; + fraccoltofill = SCALE; + p = HALFSCALE; + needcol = 0; + for (col = 0, xP = tempxelrow + chIndex; col < cols; ++col, xP += nChannels) + { + fraccolleft = sxscale; + while ( fraccolleft >= fraccoltofill ) + { + if ( needcol ) + { + nxP += nChannels; + p = HALFSCALE; + } + p += fraccoltofill * ( *xP ); + p /= SCALE; + if ( p > maxval ) p = maxval; + *nxP = (unsigned char) p; + fraccolleft -= fraccoltofill; + fraccoltofill = SCALE; + needcol = 1; + } + if (fraccolleft > 0) + { + if (needcol) + { + nxP += nChannels; + p = HALFSCALE; + needcol = 0; + } + p += fraccolleft * (*xP); + fraccoltofill -= fraccolleft; + } + } + if (fraccoltofill > 0) + { + xP -= nChannels; + p += fraccolleft * (*xP); + } + if (!needcol) + { + p /= SCALE; + if ( p > maxval ) p = maxval; + *nxP = (unsigned char) p; + } + } + } + } + if (newrows != rows && tempxelrow)// Robust, tempxelrow might be 0 1 day + delete [] tempxelrow; + if (ps) // Avoid purify complaint + delete [] ps; + + int scanWidth = dst.width() * nChannels; + QImage::operator=(QImage(nwidth, nheight, this->format())); + for( int yi=0; yi < dst.height(); ++yi ) + { + uchar *s = (dst.scanLine( yi )); + uchar *d = (scanLine( yi )); + memcpy(d, s, scanWidth); + } + return; +} + bool ScImage::getAlpha(QString fn, int page, QByteArray& alpha, bool PDF, bool pdf14, int gsRes, int scaleXSize, int scaleYSize) { bool gotAlpha = false; |
