OSDN Git Service

optimize QX11Data::copyXImageToQImage() for (A)RGB32, pre-multiplied ARGB32 and RGB16
authorIvailo Monev <xakepa10@gmail.com>
Sat, 18 Dec 2021 11:01:33 +0000 (13:01 +0200)
committerIvailo Monev <xakepa10@gmail.com>
Sat, 18 Dec 2021 11:01:33 +0000 (13:01 +0200)
Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
src/gui/image/qimage.cpp
src/gui/image/qpixmap_x11.cpp
src/gui/kernel/qt_x11.cpp

index fedec54..9ae0cc7 100644 (file)
@@ -2968,46 +2968,52 @@ void QImage::setPixel(int x, int y, uint index_or_rgb)
         qWarning("setPixel: Out of memory");
         return;
     }
-    const quint32 p = index_or_rgb;
     switch(d->format) {
-    case Format_Mono:
-    case Format_MonoLSB:
-        if (Q_UNLIKELY(index_or_rgb > 1)) {
-            qWarning("QImage::setPixel: Index %d out of range", index_or_rgb);
-        } else if (format() == Format_MonoLSB) {
-            if (index_or_rgb==0)
-                *(s + (x >> 3)) &= ~(1 << (x & 7));
-            else
-                *(s + (x >> 3)) |= (1 << (x & 7));
-        } else {
-            if (index_or_rgb==0)
-                *(s + (x >> 3)) &= ~(1 << (7-(x & 7)));
-            else
-                *(s + (x >> 3)) |= (1 << (7-(x & 7)));
+        case Format_Mono:
+        case Format_MonoLSB: {
+            if (Q_UNLIKELY(index_or_rgb > 1)) {
+                qWarning("QImage::setPixel: Index %d out of range", index_or_rgb);
+            } else if (format() == Format_MonoLSB) {
+                if (index_or_rgb==0)
+                    *(s + (x >> 3)) &= ~(1 << (x & 7));
+                else
+                    *(s + (x >> 3)) |= (1 << (x & 7));
+            } else {
+                if (index_or_rgb==0)
+                    *(s + (x >> 3)) &= ~(1 << (7-(x & 7)));
+                else
+                    *(s + (x >> 3)) |= (1 << (7-(x & 7)));
+            }
+            break;
         }
-        break;
-    case Format_Indexed8:
-        if (Q_UNLIKELY(index_or_rgb >= (uint)d->colortable.size())) {
-            qWarning("QImage::setPixel: Index %d out of range", index_or_rgb);
-            return;
+        case Format_Indexed8: {
+            if (Q_UNLIKELY(index_or_rgb >= (uint)d->colortable.size())) {
+                qWarning("QImage::setPixel: Index %d out of range", index_or_rgb);
+                return;
+            }
+            s[x] = index_or_rgb;
+            break;
+        }
+        case Format_RGB32: {
+            //make sure alpha is 255, we depend on it in qdrawhelper for cases
+            // when image is set as a texture pattern on a qbrush
+            ((uint *)s)[x] = uint(255 << 24) | index_or_rgb;
+            break;
+        }
+        case Format_ARGB32:
+        case Format_ARGB32_Premultiplied: {
+            ((uint *)s)[x] = index_or_rgb;
+            break;
+        }
+        case Format_RGB16: {
+            const quint32 p = index_or_rgb;
+            ((quint16 *)s)[x] = qt_colorConvert<quint16, quint32>(p, 0);
+            break;
+        }
+        case Format_Invalid:
+        case NImageFormats: {
+            Q_ASSERT(false);
         }
-        s[x] = index_or_rgb;
-        break;
-    case Format_RGB32:
-        //make sure alpha is 255, we depend on it in qdrawhelper for cases
-        // when image is set as a texture pattern on a qbrush
-        ((uint *)s)[x] = uint(255 << 24) | index_or_rgb;
-        break;
-    case Format_ARGB32:
-    case Format_ARGB32_Premultiplied:
-        ((uint *)s)[x] = index_or_rgb;
-        break;
-    case Format_RGB16:
-        ((quint16 *)s)[x] = qt_colorConvert<quint16, quint32>(p, 0);
-        break;
-    case Format_Invalid:
-    case NImageFormats:
-        Q_ASSERT(false);
     }
 }
 
index 60937d0..e070b74 100644 (file)
@@ -801,10 +801,6 @@ QImage QX11PixmapData::toImage(const QRect &rect) const
         return image;
     }
 
-    if (format == QImage::Format_Mono || format == QImage::Format_MonoLSB) {
-        image.setColorTable(monoColorTable());
-    }
-
     if (x11_mask) {
         QImage alpha;
         if (rect.contains(QRect(0, 0, w, h))) {
index a9a25dc..8ae8776 100644 (file)
@@ -97,7 +97,6 @@ void QX11Data::copyQImageToXImage(const QImage &image, XImage *ximage)
         }
     }
 #else
-
     const int w = image.width();
     const int h = image.height();
     switch(image.format()) {
@@ -181,11 +180,57 @@ void QX11Data::copyQImageToXImage(const QImage &image, XImage *ximage)
 void QX11Data::copyXImageToQImage(XImage *ximage, QImage &image)
 {
     Q_ASSERT(ximage);
-
-    for (int h = 0; h < ximage->height; h++) {
-        for (int w = 0; w < ximage->width; w++) {
-            const unsigned long xpixel = XGetPixel(ximage, w, h);
-            image.setPixel(w, h, xpixel);
+    Q_ASSERT(ximage->width == image.width);
+    Q_ASSERT(ximage->height == image.height);
+
+    switch (image.format()) {
+        case QImage::Format_RGB32: {
+            uchar *imagedata = image.bits();
+            const int imagebpl = image.bytesPerLine();
+            for (int h = 0; h < ximage->height; h++) {
+                uchar* imageline = QFAST_SCAN_LINE(imagedata, imagebpl, h);
+                for (int w = 0; w < ximage->width; w++) {
+                    const uint xpixel = XGetPixel(ximage, w, h);
+                    //make sure alpha is 255, we depend on it in qdrawhelper for cases
+                    // when image is set as a texture pattern on a qbrush
+                    ((uint *)imageline)[w] = uint(255 << 24) | xpixel;
+                }
+            }
+            break;
+        }
+        case QImage::Format_ARGB32:
+        case QImage::Format_ARGB32_Premultiplied: {
+            uchar *imagedata = image.bits();
+            const int imagebpl = image.bytesPerLine();
+            for (int h = 0; h < ximage->height; h++) {
+                uchar* imageline = QFAST_SCAN_LINE(imagedata, imagebpl, h);
+                for (int w = 0; w < ximage->width; w++) {
+                    const uint xpixel = XGetPixel(ximage, w, h);
+                    ((uint *)imageline)[w] = xpixel;
+                }
+            }
+            break;
+        }
+        case QImage::Format_RGB16: {
+            uchar *imagedata = image.bits();
+            const int imagebpl = image.bytesPerLine();
+            for (int h = 0; h < ximage->height; h++) {
+                uchar* imageline = QFAST_SCAN_LINE(imagedata, imagebpl, h);
+                for (int w = 0; w < ximage->width; w++) {
+                    const quint32 xpixel = XGetPixel(ximage, w, h);
+                    ((quint16 *)imageline)[w] = qt_colorConvert<quint16, quint32>(xpixel, 0);
+                }
+            }
+            break;
+        }
+        default: {
+            for (int h = 0; h < ximage->height; h++) {
+                for (int w = 0; w < ximage->width; w++) {
+                    const unsigned long xpixel = XGetPixel(ximage, w, h);
+                    image.setPixel(w, h, xpixel);
+                }
+            }
+            break;
         }
     }
 }