Ignore:
Timestamp:
Feb 11, 2010, 11:19:06 PM (16 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.6.1 sources.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/gui/painting/qblendfunctions.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information ([email protected])
     4** All rights reserved.
     5** Contact: Nokia Corporation ([email protected])
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you
     37** @nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    4444
    4545QT_BEGIN_NAMESPACE
    46 
    47 
    48 // This ifdef is made with the best of intention. GCC fails to
    49 // optimzie the code properly so the bytemul approach is the fastest
    50 // it gets. Both on ARM and on MSVC the code is optimized to be better
    51 // than the bytemul approach...  On the other hand... This code is
    52 // almost never run on i386 so it may be downright silly to have this
    53 // piece of code here...
    54 #if defined (Q_CC_GNU) && (defined (QT_ARCH_I386) || defined (QT_ARCH_X86_64))
    55 #  define QT_BLEND_USE_BYTEMUL
    56 #endif
    57 
    58 // #define QT_DEBUG_DRAW
    59 
    60 static const qreal aliasedCoordinateDelta = 0.5 - 0.015625;
    6146
    6247struct SourceOnlyAlpha
     
    120105};
    121106
     107
     108
     109
     110
     111
     112
     113
     114
     115
     116
     117
     118
     119
     120
     121
     122
     123
     124
     125
     126
     127
     128
     129
     130
     131
     132
     133
     134
     135
     136
     137
    122138struct Blend_ARGB32_on_RGB16_SourceAlpha {
    123139    inline void write(quint16 *dst, quint32 src) {
     
    154170void qt_scale_image_16bit(uchar *destPixels, int dbpl,
    155171                          const uchar *srcPixels, int sbpl,
    156                           const QRectF &target,
     172                          const QRectF &target,
    157173                          const QRectF &srcRect,
    158174                          const QRect &clip,
    159175                          T blender)
    160176{
    161     const QRectF targetRect = target.translated(aliasedCoordinateDelta,
    162                                                 aliasedCoordinateDelta);
    163 
    164177    qreal sx = targetRect.width() / (qreal) srcRect.width();
    165178    qreal sy = targetRect.height() / (qreal) srcRect.height();
     
    211224    int w = tx2 - tx1;
    212225
    213     const int dstx = int((tx1 + 0.5 - qMin(targetRect.left(), targetRect.right())) * ix);
    214     const int dsty = int((ty1 + 0.5 - qMin(targetRect.top(), targetRect.bottom())) * iy);
    215 
    216     quint32 basex = quint32((sx < 0 ? srcRect.right() : srcRect.left()) * 65536) + dstx;
    217     quint32 srcy = quint32((sy < 0 ? srcRect.bottom() : srcRect.top()) * 65536) + dsty;
     226
     227    quint32 basex;
     228    quint32 srcy;
     229
     230    if (sx < 0) {
     231        int dstx = qFloor((tx1 + qreal(0.5) - targetRect.right()) * ix) + 1;
     232        basex = quint32(srcRect.right() * 65536) + dstx;
     233    } else {
     234        int dstx = qCeil((tx1 + qreal(0.5) - targetRect.left()) * ix) - 1;
     235        basex = quint32(srcRect.left() * 65536) + dstx;
     236    }
     237    if (sy < 0) {
     238        int dsty = qFloor((ty1 + qreal(0.5) - targetRect.bottom()) * iy) + 1;
     239        srcy = quint32(srcRect.bottom() * 65536) + dsty;
     240    } else {
     241        int dsty = qCeil((ty1 + qreal(0.5) - targetRect.top()) * iy) - 1;
     242        srcy = quint32(srcRect.top() * 65536) + dsty;
     243    }
    218244
    219245    quint16 *dst = ((quint16 *) (destPixels + ty1 * dbpl)) + tx1;
     
    256282}
    257283
     284
     285
     286
     287
     288
     289
     290
     291
     292
     293
     294
     295
     296
     297
     298
     299
     300
     301
     302
     303
     304
     305
     306
     307
     308
     309
    258310void qt_scale_image_argb32_on_rgb16(uchar *destPixels, int dbpl,
    259311                                    const uchar *srcPixels, int sbpl,
     
    287339{
    288340#ifdef QT_DEBUG_DRAW
    289     printf("qt_blend_argb16_on_rgb16: dst=(%p, %d), src=(%p, %d), dim=(%d, %d) alpha=%d\n",
     341    printf("qt_blend_rgb16_on_rgb16: dst=(%p, %d), src=(%p, %d), dim=(%d, %d) alpha=%d\n",
    290342           dst, dbpl, src, sbpl, w, h, const_alpha);
    291343#endif
     
    336388        const uchar *srcEnd = src + srcOffset;
    337389        while (src < srcEnd) {
    338 #if defined(QT_ARCH_ARM) || defined(QT_ARCH_POWERPC) || (defined(QT_ARCH_WINDOWSCE) && !defined(_X86_))
    339             // non-16-bit aligned memory access is not possible on PowerPC &
    340             // ARM <v6 (QT_ARCH_ARMV6)
     390#if defined(QT_ARCH_ARM) || defined(QT_ARCH_POWERPC) || ))
     391            // non-16-bit aligned memory access is not possible on PowerPC
     392            // ARM <v6 (QT_ARCH_ARMV6)
    341393            quint16 spix = (quint16(src[2])<<8) + src[1];
    342394#else
     
    348400                *dst = spix;
    349401            } else if (alpha != 0) {
    350 #ifdef QT_BLEND_USE_BYTEMUL
    351                 // truncate green channel to avoid overflow
    352                 *dst = (alphaFunc.bytemul(spix) & 0xffdf)
    353                        + (quint16) qrgb565(*dst).byte_mul(qrgb565::ialpha(alpha));
    354 #else
    355402                quint16 dpix = *dst;
    356403                quint32 sia = 255 - alpha;
     
    364411                quint32 siab = db * sia;
    365412
    366                 quint32 rr = ((siar + (siar>>8) + (0x80 << 11)) >> 8) & 0xf800;
    367                 quint32 rg = ((siag + (siag>>8) + (0x80 <<  5)) >> 8) & 0x07e0;
    368                 quint32 rb = ((siab + (siab>>8) + (0x80 >>  3)) >> 8);
     413                quint32 rr = ((siar + (siar>>8) + (0x80 << )) >> 8) & 0xf800;
     414                quint32 rg = ((siag + (siag>>8) + (0x80 <<  )) >> 8) & 0x07e0;
     415                quint32 rb = ((siab + (siab>>8) + (0x80 >>  3)) >> 8);
    369416
    370417                *dst = alphaFunc.bytemul(spix) + rr + rg + rb;
    371 #endif
    372418            }
    373419
     
    436482
    437483    quint16 *dst = (quint16 *) destPixels;
    438     int dstExtraStride = dbpl / 2 - w;
    439 
    440     const quint32 *src = (const quint32 *) srcPixels;
    441     int srcExtraStride = sbpl / 4 - w;
     484    quint32 *src = (quint32 *) srcPixels;
    442485
    443486    for (int y=0; y<h; ++y) {
    444         int length = w;
    445         const int dstAlign = ((quintptr)dst) & 0x3;
    446         if (dstAlign) {
    447             const quint8 alpha = qAlpha(*src);
    448             if (alpha) {
    449                 quint16 s = convert_argb32_to_rgb16(*src);
    450                 if (alpha < 255)
    451                     s += BYTE_MUL_RGB16(*dst, 255 - alpha);
    452                 *dst = s;
    453             }
    454             ++dst;
    455             ++src;
    456             --length;
    457         }
    458 
    459         const int length32 = length >> 1;
    460         const int srcAlign = ((quintptr)src) & 0x3;
    461         if (length32) {
    462             if (srcAlign) {
    463                 for (int i = 0; i < length32; ++i) {
    464                     quint32 *dest32 = reinterpret_cast<quint32*>(dst);
    465                     const quint8 a1 = qAlpha(src[0]);
    466                     const quint8 a2 = qAlpha(src[1]);
    467                     quint32 s;
    468 
    469                     if (!a1 && !a2) {
    470                         src += 2;
    471                         dst +=2;
    472                         continue;
    473                     }
    474 
    475                     s = convert_argb32_to_rgb16(src[0])
    476                         | (convert_argb32_to_rgb16(src[1]) << 16);
    477 
    478                     if (a1 == a2) {
    479                         if (a1 < 255) {
    480                             const quint8 sa = ((255 - a1)+1) >> 3;
    481                             s += BYTE_MUL_RGB16_32(*dest32, sa);
    482                         }
    483                     } else {
    484                         if (a1 < 255)
    485                             s += BYTE_MUL_RGB16(dst[0], 255 - a1);
    486                         if (a2 < 255)
    487                             s += BYTE_MUL_RGB16(dst[1], 255 - a2) << 16;
    488                     }
    489 
    490                     *dest32 = s;
    491                     src += 2;
    492                     dst += 2;
    493                 }
    494             } else {
    495                 for (int i = 0; i < length32; ++i) {
    496                     quint32 *dest32 = reinterpret_cast<quint32*>(dst);
    497                     const quint8 a1 = qAlpha(src[0]);
    498                     const quint8 a2 = qAlpha(src[1]);
    499                     quint32 s;
    500 
    501                     if (!a1 && !a2) {
    502                         src += 2;
    503                         dst +=2;
    504                         continue;
    505                     }
    506 
    507                     const quint64 *src64 =
    508                         reinterpret_cast<const quint64*>(src);
    509                     s = qConvertRgb32To16x2(*src64);
    510 
    511                     if (a1 == a2) {
    512                         if (a1 < 255) {
    513                             const quint8 sa = ((255 - a1)+1) >> 3;
    514                             s += BYTE_MUL_RGB16_32(*dest32, sa);
    515                         }
    516                     } else {
    517                         if (a1 < 255)
    518                             s += BYTE_MUL_RGB16(dst[0], 255 - a1);
    519                         if (a2 < 255)
    520                             s += BYTE_MUL_RGB16(dst[1], 255 - a2) << 16;
    521                     }
    522 
    523                     *dest32 = s;
    524                     src += 2;
    525                     dst += 2;
    526                 }
     487        for (int x=0; x<w; ++x) {
     488
     489            quint32 spix = src[x];
     490            quint32 alpha = spix >> 24;
     491
     492            if (alpha == 255) {
     493                dst[x] = convert_argb32_to_rgb16(spix);
     494            } else if (alpha != 0) {
     495                quint32 dpix = dst[x];
     496
     497                quint32 sia = 255 - alpha;
     498
     499                quint32 sr = (spix >> 8) & 0xf800;
     500                quint32 sg = (spix >> 5) & 0x07e0;
     501                quint32 sb = (spix >> 3) & 0x001f;
     502
     503                quint32 dr = (dpix & 0x0000f800);
     504                quint32 dg = (dpix & 0x000007e0);
     505                quint32 db = (dpix & 0x0000001f);
     506
     507                quint32 siar = dr * sia;
     508                quint32 siag = dg * sia;
     509                quint32 siab = db * sia;
     510
     511                quint32 rr = sr + ((siar + (siar>>8) + (0x80 << 8)) >> 8);
     512                quint32 rg = sg + ((siag + (siag>>8) + (0x80 << 3)) >> 8);
     513                quint32 rb = sb + ((siab + (siab>>8) + (0x80 >> 3)) >> 8);
     514
     515                dst[x] = (rr & 0xf800)
     516                         | (rg & 0x07e0)
     517                         | (rb);
    527518            }
    528519        }
    529         const int tail = length & 0x1;
    530         if (tail) {
    531             const quint8 alpha = qAlpha(*src);
    532             if (alpha) {
    533                 quint16 s = convert_argb32_to_rgb16(*src);
    534                 if (alpha < 255)
    535                     s += BYTE_MUL_RGB16(*dst, 255 - alpha);
    536                 *dst = s;
    537             }
    538             ++dst;
    539             ++src;
    540         }
    541         dst += dstExtraStride;
    542         src += srcExtraStride;
    543     }
    544 
     520        dst = (quint16 *) (((uchar *) dst) + dbpl);
     521        src = (quint32 *) (((uchar *) src) + sbpl);
     522    }
    545523}
    546524
     
    606584            for (int x=0; x<w; ++x) {
    607585                uint s = src[x];
    608                 if ((s & 0xff000000) == 0xff000000)
     586                if (= 0xff000000)
    609587                    dst[x] = s;
    610                 else {
     588                else
    611589                    dst[x] = s + BYTE_MUL(dst[x], qAlpha(~s));
    612                 }
    613590            }
    614591            dst = (quint32 *)(((uchar *) dst) + dbpl);
     
    629606
    630607
    631 static void qt_blend_rgb32_on_rgb32(uchar *destPixels, int dbpl,
     608void qt_blend_rgb32_on_rgb32(uchar *destPixels, int dbpl,
    632609                             const uchar *srcPixels, int sbpl,
    633610                             int w, int h,
     
    706683template <typename T> void qt_scale_image_32bit(uchar *destPixels, int dbpl,
    707684                                                const uchar *srcPixels, int sbpl,
    708                                                 const QRectF &target,
     685                                                const QRectF &target,
    709686                                                const QRectF &srcRect,
    710687                                                const QRect &clip,
    711688                                                T blender)
    712689{
    713     const QRectF targetRect = target.translated(aliasedCoordinateDelta,
    714                                                 aliasedCoordinateDelta);
    715 
    716690    qreal sx = targetRect.width() / (qreal) srcRect.width();
    717691    qreal sy = targetRect.height() / (qreal) srcRect.height();
     
    763737    int w = tx2 - tx1;
    764738
    765     const int dstx = int((tx1 + 0.5 - qMin(targetRect.left(), targetRect.right())) * ix);
    766     const int dsty = int((ty1 + 0.5 - qMin(targetRect.top(), targetRect.bottom())) * iy);
    767 
    768     quint32 basex = quint32((sx < 0 ? srcRect.right() : srcRect.left()) * 65536) + dstx;
    769     quint32 srcy = quint32((sy < 0 ? srcRect.bottom() : srcRect.top()) * 65536) + dsty;
     739    quint32 basex;
     740    quint32 srcy;
     741
     742    if (sx < 0) {
     743        int dstx = qFloor((tx1 + qreal(0.5) - targetRect.right()) * ix) + 1;
     744        basex = quint32(srcRect.right() * 65536) + dstx;
     745    } else {
     746        int dstx = qCeil((tx1 + qreal(0.5) - targetRect.left()) * ix) - 1;
     747        basex = quint32(srcRect.left() * 65536) + dstx;
     748    }
     749    if (sy < 0) {
     750        int dsty = qFloor((ty1 + qreal(0.5) - targetRect.bottom()) * iy) + 1;
     751        srcy = quint32(srcRect.bottom() * 65536) + dsty;
     752    } else {
     753        int dsty = qCeil((ty1 + qreal(0.5) - targetRect.top()) * iy) - 1;
     754        srcy = quint32(srcRect.top() * 65536) + dsty;
     755    }
    770756
    771757    quint32 *dst = ((quint32 *) (destPixels + ty1 * dbpl)) + tx1;
     
    833819}
    834820
    835 
     821struct QTransformImageVertex
     822{
     823    qreal x, y, u, v; // destination coordinates (x, y) and source coordinates (u, v)
     824};
     825
     826template <class SrcT, class DestT, class Blender>
     827void qt_transform_image_rasterize(DestT *destPixels, int dbpl,
     828                                  const SrcT *srcPixels, int sbpl,
     829                                  const QTransformImageVertex &topLeft, const QTransformImageVertex &bottomLeft,
     830                                  const QTransformImageVertex &topRight, const QTransformImageVertex &bottomRight,
     831                                  const QRect &sourceRect,
     832                                  const QRect &clip,
     833                                  qreal topY, qreal bottomY,
     834                                  int dudx, int dvdx, int dudy, int dvdy, int u0, int v0,
     835                                  Blender blender)
     836{
     837    int fromY = qMax(qRound(topY), clip.top());
     838    int toY = qMin(qRound(bottomY), clip.top() + clip.height());
     839    if (fromY >= toY)
     840        return;
     841
     842    qreal leftSlope = (bottomLeft.x - topLeft.x) / (bottomLeft.y - topLeft.y);
     843    qreal rightSlope = (bottomRight.x - topRight.x) / (bottomRight.y - topRight.y);
     844    int dx_l = int(leftSlope * 0x10000);
     845    int dx_r = int(rightSlope * 0x10000);
     846    int x_l = int((topLeft.x + (0.5 + fromY - topLeft.y) * leftSlope + 0.5) * 0x10000);
     847    int x_r = int((topRight.x + (0.5 + fromY - topRight.y) * rightSlope + 0.5) * 0x10000);
     848
     849    int fromX, toX, x1, x2, u, v, i, ii;
     850    DestT *line;
     851    for (int y = fromY; y < toY; ++y) {
     852        line = reinterpret_cast<DestT *>(reinterpret_cast<uchar *>(destPixels) + y * dbpl);
     853
     854        fromX = qMax(x_l >> 16, clip.left());
     855        toX = qMin(x_r >> 16, clip.left() + clip.width());
     856        if (fromX < toX) {
     857            // Because of rounding, we can get source coordinates outside the source image.
     858            // Clamp these coordinates to the source rect to avoid segmentation fault and
     859            // garbage on the screen.
     860
     861            // Find the first pixel on the current scan line where the source coordinates are within the source rect.
     862            x1 = fromX;
     863            u = x1 * dudx + y * dudy + u0;
     864            v = x1 * dvdx + y * dvdy + v0;
     865            for (; x1 < toX; ++x1) {
     866                int uu = u >> 16;
     867                int vv = v >> 16;
     868                if (uu >= sourceRect.left() && uu < sourceRect.left() + sourceRect.width()
     869                    && vv >= sourceRect.top() && vv < sourceRect.top() + sourceRect.height()) {
     870                    break;
     871                }
     872                u += dudx;
     873                v += dvdx;
     874            }
     875
     876            // Find the last pixel on the current scan line where the source coordinates are within the source rect.
     877            x2 = toX;
     878            u = (x2 - 1) * dudx + y * dudy + u0;
     879            v = (x2 - 1) * dvdx + y * dvdy + v0;
     880            for (; x2 > x1; --x2) {
     881                int uu = u >> 16;
     882                int vv = v >> 16;
     883                if (uu >= sourceRect.left() && uu < sourceRect.left() + sourceRect.width()
     884                    && vv >= sourceRect.top() && vv < sourceRect.top() + sourceRect.height()) {
     885                    break;
     886                }
     887                u -= dudx;
     888                v -= dvdx;
     889            }
     890
     891            // Set up values at the beginning of the scan line.
     892            u = fromX * dudx + y * dudy + u0;
     893            v = fromX * dvdx + y * dvdy + v0;
     894            line += fromX;
     895
     896            // Beginning of the scan line, with per-pixel checks.
     897            i = x1 - fromX;
     898            while (i) {
     899                int uu = qBound(sourceRect.left(), u >> 16, sourceRect.left() + sourceRect.width() - 1);
     900                int vv = qBound(sourceRect.top(), v >> 16, sourceRect.top() + sourceRect.height() - 1);
     901                blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + vv * sbpl)[uu]);
     902                u += dudx;
     903                v += dvdx;
     904                ++line;
     905                --i;
     906            }
     907
     908            // Middle of the scan line, without checks.
     909            // Manual loop unrolling.
     910            i = x2 - x1;
     911            ii = i >> 3;
     912            while (ii) {
     913                blender.write(&line[0], reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx;
     914                blender.write(&line[1], reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx;
     915                blender.write(&line[2], reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx;
     916                blender.write(&line[3], reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx;
     917                blender.write(&line[4], reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx;
     918                blender.write(&line[5], reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx;
     919                blender.write(&line[6], reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx;
     920                blender.write(&line[7], reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx;
     921                line += 8;
     922                --ii;
     923            }
     924            switch (i & 7) {
     925                case 7: blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; ++line;
     926                case 6: blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; ++line;
     927                case 5: blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; ++line;
     928                case 4: blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; ++line;
     929                case 3: blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; ++line;
     930                case 2: blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; ++line;
     931                case 1: blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + (v >> 16) * sbpl)[u >> 16]); u += dudx; v += dvdx; ++line;
     932            }
     933
     934            // End of the scan line, with per-pixel checks.
     935            i = toX - x2;
     936            while (i) {
     937                int uu = qBound(sourceRect.left(), u >> 16, sourceRect.left() + sourceRect.width() - 1);
     938                int vv = qBound(sourceRect.top(), v >> 16, sourceRect.top() + sourceRect.height() - 1);
     939                blender.write(line, reinterpret_cast<const SrcT *>(reinterpret_cast<const uchar *>(srcPixels) + vv * sbpl)[uu]);
     940                u += dudx;
     941                v += dvdx;
     942                ++line;
     943                --i;
     944            }
     945        }
     946        x_l += dx_l;
     947        x_r += dx_r;
     948    }
     949}
     950
     951template <class SrcT, class DestT, class Blender>
     952void qt_transform_image(DestT *destPixels, int dbpl,
     953                        const SrcT *srcPixels, int sbpl,
     954                        const QRectF &targetRect,
     955                        const QRectF &sourceRect,
     956                        const QRect &clip,
     957                        const QTransform &targetRectTransform,
     958                        Blender blender)
     959{
     960    enum Corner
     961    {
     962        TopLeft,
     963        TopRight,
     964        BottomRight,
     965        BottomLeft
     966    };
     967
     968    // map source rectangle to destination.
     969    QTransformImageVertex v[4];
     970    v[TopLeft].u = v[BottomLeft].u = sourceRect.left();
     971    v[TopLeft].v = v[TopRight].v = sourceRect.top();
     972    v[TopRight].u = v[BottomRight].u = sourceRect.right();
     973    v[BottomLeft].v = v[BottomRight].v = sourceRect.bottom();
     974    targetRectTransform.map(targetRect.left(), targetRect.top(), &v[TopLeft].x, &v[TopLeft].y);
     975    targetRectTransform.map(targetRect.right(), targetRect.top(), &v[TopRight].x, &v[TopRight].y);
     976    targetRectTransform.map(targetRect.left(), targetRect.bottom(), &v[BottomLeft].x, &v[BottomLeft].y);
     977    targetRectTransform.map(targetRect.right(), targetRect.bottom(), &v[BottomRight].x, &v[BottomRight].y);
     978
     979    // find topmost vertex.
     980    int topmost = 0;
     981    for (int i = 1; i < 4; ++i) {
     982        if (v[i].y < v[topmost].y)
     983            topmost = i;
     984    }
     985    // rearrange array such that topmost vertex is at index 0.
     986    switch (topmost) {
     987    case 1:
     988        {
     989            QTransformImageVertex t = v[0];
     990            for (int i = 0; i < 3; ++i)
     991                v[i] = v[i+1];
     992            v[3] = t;
     993        }
     994        break;
     995    case 2:
     996        qSwap(v[0], v[2]);
     997        qSwap(v[1], v[3]);
     998        break;
     999    case 3:
     1000        {
     1001            QTransformImageVertex t = v[3];
     1002            for (int i = 3; i > 0; --i)
     1003                v[i] = v[i-1];
     1004            v[0] = t;
     1005        }
     1006        break;
     1007    }
     1008
     1009    // if necessary, swap vertex 1 and 3 such that 1 is to the left of 3.
     1010    qreal dx1 = v[1].x - v[0].x;
     1011    qreal dy1 = v[1].y - v[0].y;
     1012    qreal dx2 = v[3].x - v[0].x;
     1013    qreal dy2 = v[3].y - v[0].y;
     1014    if (dx1 * dy2 - dx2 * dy1 > 0)
     1015        qSwap(v[1], v[3]);
     1016
     1017    QTransformImageVertex u = {v[1].x - v[0].x, v[1].y - v[0].y, v[1].u - v[0].u, v[1].v - v[0].v};
     1018    QTransformImageVertex w = {v[2].x - v[0].x, v[2].y - v[0].y, v[2].u - v[0].u, v[2].v - v[0].v};
     1019
     1020    qreal det = u.x * w.y - u.y * w.x;
     1021    if (det == 0)
     1022        return;
     1023
     1024    qreal invDet = 1.0 / det;
     1025    qreal m11, m12, m21, m22, mdx, mdy;
     1026
     1027    m11 = (u.u * w.y - u.y * w.u) * invDet;
     1028    m12 = (u.x * w.u - u.u * w.x) * invDet;
     1029    m21 = (u.v * w.y - u.y * w.v) * invDet;
     1030    m22 = (u.x * w.v - u.v * w.x) * invDet;
     1031    mdx = v[0].u - m11 * v[0].x - m12 * v[0].y;
     1032    mdy = v[0].v - m21 * v[0].x - m22 * v[0].y;
     1033
     1034    int dudx = int(m11 * 0x10000);
     1035    int dvdx = int(m21 * 0x10000);
     1036    int dudy = int(m12 * 0x10000);
     1037    int dvdy = int(m22 * 0x10000);
     1038    int u0 = qCeil((0.5 * m11 + 0.5 * m12 + mdx) * 0x10000) - 1;
     1039    int v0 = qCeil((0.5 * m21 + 0.5 * m22 + mdy) * 0x10000) - 1;
     1040
     1041    int x1 = qFloor(sourceRect.left());
     1042    int y1 = qFloor(sourceRect.top());
     1043    int x2 = qCeil(sourceRect.right());
     1044    int y2 = qCeil(sourceRect.bottom());
     1045    QRect sourceRectI(x1, y1, x2 - x1, y2 - y1);
     1046
     1047    // rasterize trapezoids.
     1048    if (v[1].y < v[3].y) {
     1049        qt_transform_image_rasterize(destPixels, dbpl, srcPixels, sbpl, v[0], v[1], v[0], v[3], sourceRectI, clip, v[0].y, v[1].y, dudx, dvdx, dudy, dvdy, u0, v0, blender);
     1050        qt_transform_image_rasterize(destPixels, dbpl, srcPixels, sbpl, v[1], v[2], v[0], v[3], sourceRectI, clip, v[1].y, v[3].y, dudx, dvdx, dudy, dvdy, u0, v0, blender);
     1051        qt_transform_image_rasterize(destPixels, dbpl, srcPixels, sbpl, v[1], v[2], v[3], v[2], sourceRectI, clip, v[3].y, v[2].y, dudx, dvdx, dudy, dvdy, u0, v0, blender);
     1052    } else {
     1053        qt_transform_image_rasterize(destPixels, dbpl, srcPixels, sbpl, v[0], v[1], v[0], v[3], sourceRectI, clip, v[0].y, v[3].y, dudx, dvdx, dudy, dvdy, u0, v0, blender);
     1054        qt_transform_image_rasterize(destPixels, dbpl, srcPixels, sbpl, v[0], v[1], v[3], v[2], sourceRectI, clip, v[3].y, v[1].y, dudx, dvdx, dudy, dvdy, u0, v0, blender);
     1055        qt_transform_image_rasterize(destPixels, dbpl, srcPixels, sbpl, v[1], v[2], v[3], v[2], sourceRectI, clip, v[1].y, v[2].y, dudx, dvdx, dudy, dvdy, u0, v0, blender);
     1056    }
     1057}
     1058
     1059void qt_transform_image_rgb16_on_rgb16(uchar *destPixels, int dbpl,
     1060                                       const uchar *srcPixels, int sbpl,
     1061                                       const QRectF &targetRect,
     1062                                       const QRectF &sourceRect,
     1063                                       const QRect &clip,
     1064                                       const QTransform &targetRectTransform,
     1065                                       int const_alpha)
     1066{
     1067    if (const_alpha == 256) {
     1068        Blend_RGB16_on_RGB16_NoAlpha noAlpha;
     1069        qt_transform_image(reinterpret_cast<quint16 *>(destPixels), dbpl,
     1070                           reinterpret_cast<const quint16 *>(srcPixels), sbpl,
     1071                           targetRect, sourceRect, clip, targetRectTransform, noAlpha);
     1072    } else {
     1073        Blend_RGB16_on_RGB16_ConstAlpha constAlpha(const_alpha);
     1074        qt_transform_image(reinterpret_cast<quint16 *>(destPixels), dbpl,
     1075                           reinterpret_cast<const quint16 *>(srcPixels), sbpl,
     1076                           targetRect, sourceRect, clip, targetRectTransform, constAlpha);
     1077    }
     1078}
     1079
     1080void qt_transform_image_argb24_on_rgb16(uchar *destPixels, int dbpl,
     1081                                        const uchar *srcPixels, int sbpl,
     1082                                        const QRectF &targetRect,
     1083                                        const QRectF &sourceRect,
     1084                                        const QRect &clip,
     1085                                        const QTransform &targetRectTransform,
     1086                                        int const_alpha)
     1087{
     1088    if (const_alpha == 256) {
     1089        Blend_ARGB24_on_RGB16_SourceAlpha noAlpha;
     1090        qt_transform_image(reinterpret_cast<quint16 *>(destPixels), dbpl,
     1091                           reinterpret_cast<const qargb8565 *>(srcPixels), sbpl,
     1092                           targetRect, sourceRect, clip, targetRectTransform, noAlpha);
     1093    } else {
     1094        Blend_ARGB24_on_RGB16_SourceAndConstAlpha constAlpha(const_alpha);
     1095        qt_transform_image(reinterpret_cast<quint16 *>(destPixels), dbpl,
     1096                           reinterpret_cast<const qargb8565 *>(srcPixels), sbpl,
     1097                           targetRect, sourceRect, clip, targetRectTransform, constAlpha);
     1098    }
     1099}
     1100
     1101
     1102void qt_transform_image_argb32_on_rgb16(uchar *destPixels, int dbpl,
     1103                                        const uchar *srcPixels, int sbpl,
     1104                                        const QRectF &targetRect,
     1105                                        const QRectF &sourceRect,
     1106                                        const QRect &clip,
     1107                                        const QTransform &targetRectTransform,
     1108                                        int const_alpha)
     1109{
     1110    if (const_alpha == 256) {
     1111        Blend_ARGB32_on_RGB16_SourceAlpha noAlpha;
     1112        qt_transform_image(reinterpret_cast<quint16 *>(destPixels), dbpl,
     1113                           reinterpret_cast<const quint32 *>(srcPixels), sbpl,
     1114                           targetRect, sourceRect, clip, targetRectTransform, noAlpha);
     1115    } else {
     1116        Blend_ARGB32_on_RGB16_SourceAndConstAlpha constAlpha(const_alpha);
     1117        qt_transform_image(reinterpret_cast<quint16 *>(destPixels), dbpl,
     1118                           reinterpret_cast<const quint32 *>(srcPixels), sbpl,
     1119                           targetRect, sourceRect, clip, targetRectTransform, constAlpha);
     1120    }
     1121}
     1122
     1123
     1124void qt_transform_image_rgb32_on_rgb32(uchar *destPixels, int dbpl,
     1125                                       const uchar *srcPixels, int sbpl,
     1126                                       const QRectF &targetRect,
     1127                                       const QRectF &sourceRect,
     1128                                       const QRect &clip,
     1129                                       const QTransform &targetRectTransform,
     1130                                       int const_alpha)
     1131{
     1132    if (const_alpha == 256) {
     1133        Blend_RGB32_on_RGB32_NoAlpha noAlpha;
     1134        qt_transform_image(reinterpret_cast<quint32 *>(destPixels), dbpl,
     1135                           reinterpret_cast<const quint32 *>(srcPixels), sbpl,
     1136                           targetRect, sourceRect, clip, targetRectTransform, noAlpha);
     1137    } else {
     1138        Blend_RGB32_on_RGB32_ConstAlpha constAlpha(const_alpha);
     1139        qt_transform_image(reinterpret_cast<quint32 *>(destPixels), dbpl,
     1140                           reinterpret_cast<const quint32 *>(srcPixels), sbpl,
     1141                           targetRect, sourceRect, clip, targetRectTransform, constAlpha);
     1142    }
     1143}
     1144
     1145void qt_transform_image_argb32_on_argb32(uchar *destPixels, int dbpl,
     1146                                         const uchar *srcPixels, int sbpl,
     1147                                         const QRectF &targetRect,
     1148                                         const QRectF &sourceRect,
     1149                                         const QRect &clip,
     1150                                         const QTransform &targetRectTransform,
     1151                                         int const_alpha)
     1152{
     1153    if (const_alpha == 256) {
     1154        Blend_ARGB32_on_ARGB32_SourceAlpha sourceAlpha;
     1155        qt_transform_image(reinterpret_cast<quint32 *>(destPixels), dbpl,
     1156                           reinterpret_cast<const quint32 *>(srcPixels), sbpl,
     1157                           targetRect, sourceRect, clip, targetRectTransform, sourceAlpha);
     1158    } else {
     1159        Blend_ARGB32_on_ARGB32_SourceAndConstAlpha constAlpha(const_alpha);
     1160        qt_transform_image(reinterpret_cast<quint32 *>(destPixels), dbpl,
     1161                           reinterpret_cast<const quint32 *>(srcPixels), sbpl,
     1162                           targetRect, sourceRect, clip, targetRectTransform, constAlpha);
     1163    }
     1164}
    8361165
    8371166SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats] = {
     
    9711300        qt_scale_image_argb32_on_rgb16,       // Format_ARGB32_Premultiplied,
    9721301        qt_scale_image_rgb16_on_rgb16,        // Format_RGB16,
    973         0,      // Format_ARGB8565_Premultiplied,
     1302              // Format_ARGB8565_Premultiplied,
    9741303        0,      // Format_RGB666,
    9751304        0,      // Format_ARGB6666_Premultiplied,
     
    14181747};
    14191748
     1749
     1750
     1751
     1752
     1753
     1754
     1755
     1756
     1757
     1758
     1759
     1760
     1761
     1762
     1763
     1764
     1765
     1766
     1767
     1768
     1769
     1770
     1771
     1772
     1773
     1774
     1775
     1776
     1777
     1778
     1779
     1780
     1781
     1782
     1783
     1784
     1785
     1786
     1787
     1788
     1789
     1790
     1791
     1792
     1793
     1794
     1795
     1796
     1797
     1798
     1799
     1800
     1801
     1802
     1803
     1804
     1805
     1806
     1807
     1808
     1809
     1810
     1811
     1812
     1813
     1814
     1815
     1816
     1817
     1818
     1819
     1820
     1821
     1822
     1823
     1824
     1825
     1826
     1827
     1828
     1829
     1830
     1831
     1832
     1833
     1834
     1835
     1836
     1837
     1838
     1839
     1840
     1841
     1842
     1843
     1844
     1845
     1846
     1847
     1848
     1849
     1850
     1851
     1852
     1853
     1854
     1855
     1856
     1857
     1858
     1859
     1860
     1861
     1862
     1863
     1864
     1865
     1866
     1867
     1868
     1869
     1870
     1871
     1872
     1873
     1874
     1875
     1876
     1877
     1878
     1879
     1880
     1881
     1882
     1883
     1884
     1885
     1886
     1887
     1888
     1889
     1890
     1891
     1892
     1893
     1894
     1895
     1896
     1897
     1898
     1899
     1900
     1901
     1902
     1903
     1904
     1905
     1906
     1907
     1908
     1909
     1910
     1911
     1912
     1913
     1914
     1915
     1916
     1917
     1918
     1919
     1920
     1921
     1922
     1923
     1924
     1925
     1926
     1927
     1928
     1929
     1930
     1931
     1932
     1933
     1934
     1935
     1936
     1937
     1938
     1939
     1940
     1941
     1942
     1943
     1944
     1945
     1946
     1947
     1948
     1949
     1950
     1951
     1952
     1953
     1954
     1955
     1956
     1957
     1958
     1959
     1960
     1961
     1962
     1963
     1964
     1965
     1966
     1967
     1968
     1969
     1970
     1971
     1972
     1973
     1974
     1975
     1976
     1977
     1978
     1979
     1980
     1981
     1982
     1983
     1984
     1985
     1986
     1987
     1988
     1989
     1990
     1991
     1992
     1993
     1994
     1995
     1996
     1997
     1998
     1999
     2000
     2001
     2002
     2003
     2004
     2005
     2006
     2007
     2008
     2009
     2010
     2011
     2012
     2013
     2014
     2015
     2016
     2017
     2018
     2019
     2020
     2021
     2022
     2023
     2024
     2025
     2026
     2027
     2028
     2029
     2030
     2031
     2032
     2033
     2034
     2035
     2036
     2037
     2038
    14202039
    14212040QT_END_NAMESPACE
Note: See TracChangeset for help on using the changeset viewer.