Modified: trunk/Source/WebCore/ChangeLog (141885 => 141886)
--- trunk/Source/WebCore/ChangeLog 2013-02-05 12:41:17 UTC (rev 141885)
+++ trunk/Source/WebCore/ChangeLog 2013-02-05 12:57:01 UTC (rev 141886)
@@ -1,3 +1,29 @@
+2013-02-05 Allan Sandfeld Jensen <[email protected]>
+
+ [Qt] RGB -> BGR is wrong on big endian
+ https://bugs.webkit.org/show_bug.cgi?id=107560
+
+ Reviewed by Jocelyn Turcotte.
+
+ Replace the conversion to methods that make it clearer what is going on.
+ The routines are also optimized compared to the existing by avoiding going
+ over slow Color constructor.
+
+ Tested by existing tests in canvas and fast/canvas.
+
+ * platform/graphics/Color.cpp:
+ (WebCore::colorFromPremultipliedARGB):
+ Cleanup.
+ (WebCore::premultipliedARGBFromColor):
+ Cleanup and correct for alpha = 0.
+ * platform/graphics/Color.h:
+ (WebCore):
+ * platform/graphics/qt/ImageBufferQt.cpp:
+ (WebCore::copyColorToRGBA):
+ (WebCore::copyRGBAToColor):
+ (WebCore::getImageData):
+ (WebCore::ImageBuffer::putByteArray):
+
2013-02-05 JungJik Lee <[email protected]>
[TexMap] Use visible as initial value of backface-visibility-property.
Modified: trunk/Source/WebCore/platform/graphics/Color.cpp (141885 => 141886)
--- trunk/Source/WebCore/platform/graphics/Color.cpp 2013-02-05 12:41:17 UTC (rev 141885)
+++ trunk/Source/WebCore/platform/graphics/Color.cpp 2013-02-05 12:57:01 UTC (rev 141886)
@@ -414,31 +414,30 @@
saturation = ((max - min) / (2.0 - (max + min)));
}
-Color colorFromPremultipliedARGB(unsigned pixelColor)
+Color colorFromPremultipliedARGB(RGBA32 pixelColor)
{
- Color color;
-
- if (unsigned alpha = (pixelColor & 0xFF000000) >> 24) {
- color = Color::createUnchecked(
- ((pixelColor & 0x00FF0000) >> 16) * 255 / alpha,
- ((pixelColor & 0x0000FF00) >> 8) * 255 / alpha,
- (pixelColor & 0x000000FF) * 255 / alpha,
- alpha);
+ int alpha = alphaChannel(pixelColor);
+ if (alpha && alpha < 255) {
+ return Color::createUnchecked(
+ redChannel(pixelColor) * 255 / alpha,
+ greenChannel(pixelColor) * 255 / alpha,
+ blueChannel(pixelColor) * 255 / alpha,
+ alpha);
} else
- color = Color(pixelColor);
-
- return color;
+ return Color(pixelColor);
}
-unsigned premultipliedARGBFromColor(const Color& color)
+RGBA32 premultipliedARGBFromColor(const Color& color)
{
unsigned pixelColor;
- if (unsigned alpha = color.alpha()) {
- pixelColor = alpha << 24 |
- ((color.red() * alpha + 254) / 255) << 16 |
- ((color.green() * alpha + 254) / 255) << 8 |
- ((color.blue() * alpha + 254) / 255);
+ unsigned alpha = color.alpha();
+ if (alpha < 255) {
+ pixelColor = Color::createUnchecked(
+ (color.red() * alpha + 254) / 255,
+ (color.green() * alpha + 254) / 255,
+ (color.blue() * alpha + 254) / 255,
+ alpha).rgb();
} else
pixelColor = color.rgb();
Modified: trunk/Source/WebCore/platform/graphics/Color.h (141885 => 141886)
--- trunk/Source/WebCore/platform/graphics/Color.h 2013-02-05 12:41:17 UTC (rev 141885)
+++ trunk/Source/WebCore/platform/graphics/Color.h 2013-02-05 12:57:01 UTC (rev 141886)
@@ -182,8 +182,8 @@
return !(a == b);
}
-Color colorFromPremultipliedARGB(unsigned);
-unsigned premultipliedARGBFromColor(const Color&);
+Color colorFromPremultipliedARGB(RGBA32);
+RGBA32 premultipliedARGBFromColor(const Color&);
inline Color blend(const Color& from, const Color& to, double progress, bool blendPremultiplied = true)
{
Modified: trunk/Source/WebCore/platform/graphics/qt/ImageBufferQt.cpp (141885 => 141886)
--- trunk/Source/WebCore/platform/graphics/qt/ImageBufferQt.cpp 2013-02-05 12:41:17 UTC (rev 141885)
+++ trunk/Source/WebCore/platform/graphics/qt/ImageBufferQt.cpp 2013-02-05 12:57:01 UTC (rev 141886)
@@ -193,14 +193,19 @@
m_data.m_painter->begin(&m_data.m_pixmap);
}
-static inline quint32 convertABGRToARGB(quint32 pixel)
+static inline void copyColorToRGBA(Color& from, uchar* to)
{
- return ((pixel << 16) & 0xff0000) | ((pixel >> 16) & 0xff) | (pixel & 0xff00ff00);
+ // Copy from endian dependent 32bit ARGB to endian independent RGBA8888.
+ to[0] = from.red();
+ to[1] = from.green();
+ to[2] = from.blue();
+ to[3] = from.alpha();
}
-static inline quint32 convertARGBToABGR(quint32 pixel)
+static inline void copyRGBAToColor(const uchar* from, Color& to)
{
- return convertABGRToARGB(pixel);
+ // Copy from endian independent RGBA8888 to endian dependent 32bit ARGB.
+ to = Color::createUnchecked(from[0], from[1], from[2], from[3]);
}
template <Multiply multiplied>
@@ -211,7 +216,7 @@
return 0;
RefPtr<Uint8ClampedArray> result = Uint8ClampedArray::createUninitialized(rect.width() * rect.height() * 4);
- unsigned char* data = ""
+ uchar* resultData = result->data();
if (rect.x() < 0 || rect.y() < 0 || rect.maxX() > size.width() || rect.maxY() > size.height())
result->zeroFill();
@@ -238,27 +243,26 @@
endy = size.height();
int numRows = endy - originy;
+ const unsigned destBytesPerRow = 4 * rect.width();
+
// NOTE: For unmultiplied data, we undo the premultiplication below.
QImage image = imageData.toQImage().convertToFormat(QImage::Format_ARGB32_Premultiplied);
ASSERT(!image.isNull());
- const int bytesPerLine = image.bytesPerLine();
- const uchar* bits = image.constBits();
-
- quint32* destRows = reinterpret_cast_ptr<quint32*>(&data[desty * rect.width() * 4 + destx * 4]);
+ // The Canvas 2D Context expects RGBA order, while Qt uses 32bit QRgb (ARGB/BGRA).
for (int y = 0; y < numRows; ++y) {
- const quint32* scanLine = reinterpret_cast_ptr<const quint32*>(bits + (y + originy) * bytesPerLine);
- for (int x = 0; x < numColumns; x++) {
- QRgb pixel = scanLine[x + originx];
+ // This cast and the calls below relies on both QRgb and WebCore::RGBA32 being 32bit ARGB.
+ const unsigned* srcRow = reinterpret_cast<const unsigned*>(image.constScanLine(originy + y)) + originx;
+ uchar* destRow = resultData + (desty + y) * destBytesPerRow + destx * 4;
+ for (int x = 0; x < numColumns; x++, srcRow++, destRow += 4) {
Color pixelColor;
if (multiplied == Unmultiplied)
- pixelColor = colorFromPremultipliedARGB(Color(qRed(pixel), qGreen(pixel), qBlue(pixel), qAlpha(pixel)).rgb());
+ pixelColor = colorFromPremultipliedARGB(*srcRow);
else
- pixelColor = Color(qRed(pixel), qGreen(pixel), qBlue(pixel), qAlpha(pixel));
- destRows[x] = convertARGBToABGR(pixelColor.rgb());
+ pixelColor = Color(*srcRow);
+ copyColorToRGBA(pixelColor, destRow);
}
- destRows += rect.width();
}
return result.release();
@@ -302,25 +306,26 @@
ASSERT(endy <= m_size.height());
int numRows = endy - desty;
- unsigned srcBytesPerRow = 4 * sourceSize.width();
+ const unsigned srcBytesPerRow = 4 * sourceSize.width();
// NOTE: For unmultiplied input data, we do the premultiplication below.
QImage image(numColumns, numRows, QImage::Format_ARGB32_Premultiplied);
- uchar* bits = image.bits();
- const int bytesPerLine = image.bytesPerLine();
- const quint32* srcScanLine = reinterpret_cast_ptr<const quint32*>(source->data() + originy * srcBytesPerRow + originx * 4);
+ unsigned* destData = reinterpret_cast<unsigned*>(image.bits());
+ const uchar* srcData = source->data();
for (int y = 0; y < numRows; ++y) {
- quint32* destScanLine = reinterpret_cast_ptr<quint32*>(bits + y * bytesPerLine);
- for (int x = 0; x < numColumns; x++) {
- quint32 pixel = convertABGRToARGB(srcScanLine[x]);
+ const uchar* srcRow = srcData + (originy + y) * srcBytesPerRow + originx * 4;
+ // This cast and the calls below relies on both QRgb and WebCore::RGBA32 being 32bit ARGB.
+ unsigned* destRow = destData + y * numColumns;
+ for (int x = 0; x < numColumns; x++, srcRow += 4, destRow++) {
+ Color pixelColor;
+ copyRGBAToColor(srcRow, pixelColor);
if (multiplied == Unmultiplied)
- destScanLine[x] = premultipliedARGBFromColor(Color(pixel));
+ *destRow = premultipliedARGBFromColor(pixelColor);
else
- destScanLine[x] = pixel;
+ *destRow = pixelColor.rgb();
}
- srcScanLine += sourceSize.width();
}
bool isPainting = m_data.m_painter->isActive();