src/gui/image/qimage.cpp
changeset 37 758a864f9613
parent 33 3e2da88830cd
--- a/src/gui/image/qimage.cpp	Fri Sep 17 08:34:18 2010 +0300
+++ b/src/gui/image/qimage.cpp	Mon Oct 04 01:19:32 2010 +0300
@@ -3354,7 +3354,7 @@
 
 
 // first index source, second dest
-static const Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormats] =
+static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormats] =
 {
     {
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
@@ -3761,6 +3761,22 @@
         inplace_converter_map[QImage::Format_ARGB32][QImage::Format_ARGB32_Premultiplied] = convert_ARGB_to_ARGB_PM_inplace_sse2;
     }
 #endif
+#ifdef QT_HAVE_SSSE3
+    if (features & SSSE3) {
+        extern void convert_RGB888_to_RGB32_ssse3(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags);
+        converter_map[QImage::Format_RGB888][QImage::Format_RGB32] = convert_RGB888_to_RGB32_ssse3;
+        converter_map[QImage::Format_RGB888][QImage::Format_ARGB32] = convert_RGB888_to_RGB32_ssse3;
+        converter_map[QImage::Format_RGB888][QImage::Format_ARGB32_Premultiplied] = convert_RGB888_to_RGB32_ssse3;
+    }
+#endif
+#ifdef QT_HAVE_NEON
+    if (features & NEON) {
+        extern void convert_RGB888_to_RGB32_neon(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags);
+        converter_map[QImage::Format_RGB888][QImage::Format_RGB32] = convert_RGB888_to_RGB32_neon;
+        converter_map[QImage::Format_RGB888][QImage::Format_ARGB32] = convert_RGB888_to_RGB32_neon;
+        converter_map[QImage::Format_RGB888][QImage::Format_ARGB32_Premultiplied] = convert_RGB888_to_RGB32_neon;
+    }
+#endif
 }
 
 /*!
@@ -4821,7 +4837,7 @@
         QIMAGE_SANITYCHECK_MEMORY(res);
         for (int i = 0; i < d->height; i++) {
             uint *q = (uint*)res.scanLine(i);
-            uint *p = (uint*)scanLine(i);
+            uint *p = (uint*)constScanLine(i);
             uint *end = p + d->width;
             while (p < end) {
                 *q = ((*p << 16) & 0xff0000) | ((*p >> 16) & 0xff) | (*p & 0xff00ff00);
@@ -4835,7 +4851,7 @@
         QIMAGE_SANITYCHECK_MEMORY(res);
         for (int i = 0; i < d->height; i++) {
             ushort *q = (ushort*)res.scanLine(i);
-            const ushort *p = (const ushort*)scanLine(i);
+            const ushort *p = (const ushort*)constScanLine(i);
             const ushort *end = p + d->width;
             while (p < end) {
                 *q = ((*p << 11) & 0xf800) | ((*p >> 11) & 0x1f) | (*p & 0x07e0);
@@ -4848,12 +4864,15 @@
         res = QImage(d->width, d->height, d->format);
         QIMAGE_SANITYCHECK_MEMORY(res);
         for (int i = 0; i < d->height; i++) {
-            quint8 *p = (quint8*)scanLine(i);
+            const quint8 *p = constScanLine(i);
+            quint8 *q = res.scanLine(i);
             const quint8 *end = p + d->width * sizeof(qargb8565);
             while (p < end) {
-                quint16 *q = reinterpret_cast<quint16*>(p + 1);
-                *q = ((*q << 11) & 0xf800) | ((*q >> 11) & 0x1f) | (*q & 0x07e0);
+                q[0] = p[0];
+                q[1] = (p[1] & 0xe0) | (p[2] >> 3);
+                q[2] = (p[2] & 0x07) | (p[1] << 3);
                 p += sizeof(qargb8565);
+                q += sizeof(qargb8565);
             }
         }
         break;
@@ -4862,7 +4881,7 @@
         QIMAGE_SANITYCHECK_MEMORY(res);
         for (int i = 0; i < d->height; i++) {
             qrgb666 *q = reinterpret_cast<qrgb666*>(res.scanLine(i));
-            const qrgb666 *p = reinterpret_cast<const qrgb666*>(scanLine(i));
+            const qrgb666 *p = reinterpret_cast<const qrgb666*>(constScanLine(i));
             const qrgb666 *end = p + d->width;
             while (p < end) {
                 const QRgb rgb = quint32(*p++);
@@ -4874,12 +4893,15 @@
         res = QImage(d->width, d->height, d->format);
         QIMAGE_SANITYCHECK_MEMORY(res);
         for (int i = 0; i < d->height; i++) {
-            qargb6666 *q = reinterpret_cast<qargb6666*>(res.scanLine(i));
-            const qargb6666 *p = reinterpret_cast<const qargb6666*>(scanLine(i));
-            const qargb6666 *end = p + d->width;
+            const quint8 *p = constScanLine(i);
+            const quint8 *end = p + d->width * sizeof(qargb6666);
+            quint8 *q = res.scanLine(i);
             while (p < end) {
-                const QRgb rgb = quint32(*p++);
-                *q++ = qRgba(qBlue(rgb), qGreen(rgb), qRed(rgb), qAlpha(rgb));
+                q[0] = (p[1] >> 4) | ((p[2] & 0x3) << 4) | (p[0] & 0xc0);
+                q[1] = (p[1] & 0xf) | (p[0] << 4);
+                q[2] = (p[2] & 0xfc) | ((p[0] >> 4) & 0x3);
+                p += sizeof(qargb6666);
+                q += sizeof(qargb6666);
             }
         }
         break;
@@ -4887,11 +4909,11 @@
         res = QImage(d->width, d->height, d->format);
         QIMAGE_SANITYCHECK_MEMORY(res);
         for (int i = 0; i < d->height; i++) {
-            ushort *q = (ushort*)res.scanLine(i);
-            const ushort *p = (const ushort*)scanLine(i);
-            const ushort *end = p + d->width;
+            quint16 *q = (quint16*)res.scanLine(i);
+            const quint16 *p = (const quint16*)constScanLine(i);
+            const quint16 *end = p + d->width;
             while (p < end) {
-                *q = ((*p << 10) & 0x7800) | ((*p >> 10) & 0x1f) | (*p & 0x83e0);
+                *q = ((*p << 10) & 0x7c00) | ((*p >> 10) & 0x1f) | (*p & 0x3e0);
                 p++;
                 q++;
             }
@@ -4901,12 +4923,15 @@
         res = QImage(d->width, d->height, d->format);
         QIMAGE_SANITYCHECK_MEMORY(res);
         for (int i = 0; i < d->height; i++) {
-            quint8 *p = (quint8*)scanLine(i);
+            const quint8 *p = constScanLine(i);
+            quint8 *q = res.scanLine(i);
             const quint8 *end = p + d->width * sizeof(qargb8555);
             while (p < end) {
-                quint16 *q = reinterpret_cast<quint16*>(p + 1);
-                *q = ((*q << 10) & 0x7800) | ((*q >> 10) & 0x1f) | (*q & 0x83e0);
+                q[0] = p[0];
+                q[1] = (p[1] & 0xe0) | (p[2] >> 2);
+                q[2] = (p[2] & 0x03) | ((p[1] << 2) & 0x7f);
                 p += sizeof(qargb8555);
+                q += sizeof(qargb8555);
             }
         }
         break;
@@ -4914,8 +4939,8 @@
         res = QImage(d->width, d->height, d->format);
         QIMAGE_SANITYCHECK_MEMORY(res);
         for (int i = 0; i < d->height; i++) {
-            quint8 *q = reinterpret_cast<quint8*>(res.scanLine(i));
-            const quint8 *p = reinterpret_cast<const quint8*>(scanLine(i));
+            quint8 *q = res.scanLine(i);
+            const quint8 *p = constScanLine(i);
             const quint8 *end = p + d->width * sizeof(qrgb888);
             while (p < end) {
                 q[0] = p[2];
@@ -4927,32 +4952,17 @@
         }
         break;
     case Format_RGB444:
-        res = QImage(d->width, d->height, d->format);
-        QIMAGE_SANITYCHECK_MEMORY(res);
-        for (int i = 0; i < d->height; i++) {
-            quint8 *q = reinterpret_cast<quint8*>(res.scanLine(i));
-            const quint8 *p = reinterpret_cast<const quint8*>(scanLine(i));
-            const quint8 *end = p + d->width * sizeof(qrgb444);
-            while (p < end) {
-                q[0] = (p[0] & 0xf0) | ((p[1] & 0x0f) << 8);
-                q[1] = ((p[0] & 0x0f) >> 8) | (p[1] & 0xf0);
-                q += sizeof(qrgb444);
-                p += sizeof(qrgb444);
-            }
-        }
-        break;
     case Format_ARGB4444_Premultiplied:
         res = QImage(d->width, d->height, d->format);
         QIMAGE_SANITYCHECK_MEMORY(res);
         for (int i = 0; i < d->height; i++) {
-            quint8 *q = reinterpret_cast<quint8*>(res.scanLine(i));
-            const quint8 *p = reinterpret_cast<const quint8*>(scanLine(i));
-            const quint8 *end = p + d->width * sizeof(qargb4444);
+            quint16 *q = reinterpret_cast<quint16*>(res.scanLine(i));
+            const quint16 *p = reinterpret_cast<const quint16*>(constScanLine(i));
+            const quint16 *end = p + d->width;
             while (p < end) {
-                q[0] = (p[0] & 0xf0) | ((p[1] & 0x0f) << 8);
-                q[1] = ((p[0] & 0x0f) >> 8) | (p[1] & 0xf0);
-                q += sizeof(qargb4444);
-                p += sizeof(qargb4444);
+                *q = (*p & 0xf0f0) | ((*p & 0x0f) << 8) | ((*p & 0xf00) >> 8);
+                p++;
+                q++;
             }
         }
         break;