src/gui/painting/qmemrotate.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtGui module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    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.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "private/qmemrotate_p.h"
       
    43 
       
    44 QT_BEGIN_NAMESPACE
       
    45 
       
    46 #if QT_ROTATION_ALGORITHM == QT_ROTATION_TILED
       
    47 static const int tileSize = 32;
       
    48 #endif
       
    49 
       
    50 #if Q_BYTE_ORDER == Q_BIG_ENDIAN
       
    51 #if QT_ROTATION_ALGORITHM == QT_ROTATION_PACKED || QT_ROTATION_ALGORITHM == QT_ROTATION_TILED
       
    52 #error Big endian version not implemented for the transformed driver!
       
    53 #endif
       
    54 #endif
       
    55 
       
    56 template <class DST, class SRC>
       
    57 Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate90_cachedRead(const SRC *src, int w, int h,
       
    58                                              int sstride,
       
    59                                              DST *dest, int dstride)
       
    60 {
       
    61     const char *s = reinterpret_cast<const char*>(src);
       
    62     char *d = reinterpret_cast<char*>(dest);
       
    63     for (int y = 0; y < h; ++y) {
       
    64         for (int x = w - 1; x >= 0; --x) {
       
    65             DST *destline = reinterpret_cast<DST*>(d + (w - x - 1) * dstride);
       
    66             destline[y] = qt_colorConvert<DST,SRC>(src[x], 0);
       
    67         }
       
    68         s += sstride;
       
    69         src = reinterpret_cast<const SRC*>(s);
       
    70     }
       
    71 }
       
    72 
       
    73 template <class DST, class SRC>
       
    74 Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate270_cachedRead(const SRC *src, int w, int h,
       
    75                                               int sstride,
       
    76                                               DST *dest, int dstride)
       
    77 {
       
    78     const char *s = reinterpret_cast<const char*>(src);
       
    79     char *d = reinterpret_cast<char*>(dest);
       
    80     s += (h - 1) * sstride;
       
    81     for (int y = h - 1; y >= 0; --y) {
       
    82         src = reinterpret_cast<const SRC*>(s);
       
    83         for (int x = 0; x < w; ++x) {
       
    84             DST *destline = reinterpret_cast<DST*>(d + x * dstride);
       
    85             destline[h - y - 1] = qt_colorConvert<DST,SRC>(src[x], 0);
       
    86         }
       
    87         s -= sstride;
       
    88     }
       
    89 }
       
    90 
       
    91 #if QT_ROTATION_ALGORITHM == QT_ROTATION_CACHEDWRITE
       
    92 
       
    93 template <class DST, class SRC>
       
    94 Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate90_cachedWrite(const SRC *src, int w, int h,
       
    95                                               int sstride,
       
    96                                               DST *dest, int dstride)
       
    97 {
       
    98     for (int x = w - 1; x >= 0; --x) {
       
    99         DST *d = dest + (w - x - 1) * dstride;
       
   100         for (int y = 0; y < h; ++y) {
       
   101             *d++ = qt_colorConvert<DST,SRC>(src[y * sstride + x], 0);
       
   102         }
       
   103     }
       
   104 
       
   105 }
       
   106 
       
   107 template <class DST, class SRC>
       
   108 Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate270_cachedWrite(const SRC *src, int w, int h,
       
   109                                                int sstride,
       
   110                                                DST *dest, int dstride)
       
   111 {
       
   112     for (int x = 0; x < w; ++x) {
       
   113         DST *d = dest + x * dstride;
       
   114         for (int y = h - 1; y >= 0; --y) {
       
   115             *d++ = qt_colorConvert<DST,SRC>(src[y * sstride + x], 0);
       
   116         }
       
   117     }
       
   118 }
       
   119 
       
   120 #endif // QT_ROTATION_CACHEDWRITE
       
   121 
       
   122 #if QT_ROTATION_ALGORITHM == QT_ROTATION_PACKING
       
   123 
       
   124 // TODO: packing algorithms should probably be modified on 64-bit architectures
       
   125 
       
   126 template <class DST, class SRC>
       
   127 Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate90_packing(const SRC *src, int w, int h,
       
   128                                           int sstride,
       
   129                                           DST *dest, int dstride)
       
   130 {
       
   131     sstride /= sizeof(SRC);
       
   132     dstride /= sizeof(DST);
       
   133 
       
   134     const int pack = sizeof(quint32) / sizeof(DST);
       
   135     const int unaligned = int((long(dest) & (sizeof(quint32)-1))) / sizeof(DST);
       
   136 
       
   137     for (int x = w - 1; x >= 0; --x) {
       
   138         int y = 0;
       
   139 
       
   140         for (int i = 0; i < unaligned; ++i) {
       
   141             dest[(w - x - 1) * dstride + y]
       
   142                 = qt_colorConvert<DST,SRC>(src[y * sstride + x], 0);
       
   143             ++y;
       
   144         }
       
   145 
       
   146         quint32 *d = reinterpret_cast<quint32*>(dest + (w - x - 1) * dstride
       
   147                                                 + unaligned);
       
   148         const int rest = (h - unaligned) % pack;
       
   149         while (y < h - rest) {
       
   150             quint32 c = qt_colorConvert<DST,SRC>(src[y * sstride + x], 0);
       
   151             for (int i = 1; i < pack; ++i) {
       
   152                 c |= qt_colorConvert<DST,SRC>(src[(y + i) * sstride + x], 0)
       
   153                      << (sizeof(int) * 8 / pack * i);
       
   154             }
       
   155             *d++ = c;
       
   156             y += pack;
       
   157         }
       
   158 
       
   159         while (y < h) {
       
   160             dest[(w - x - 1) * dstride + y]
       
   161                 = qt_colorConvert<DST,SRC>(src[y * sstride + x], 0);
       
   162             ++y;
       
   163         }
       
   164     }
       
   165 }
       
   166 
       
   167 template <class DST, class SRC>
       
   168 Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate270_packing(const SRC *src, int w, int h,
       
   169                                            int sstride,
       
   170                                            DST *dest, int dstride)
       
   171 {
       
   172     sstride /= sizeof(SRC);
       
   173     dstride /= sizeof(DST);
       
   174 
       
   175     const int pack = sizeof(quint32) / sizeof(DST);
       
   176     const int unaligned = int((long(dest) & (sizeof(quint32)-1))) / sizeof(DST);
       
   177 
       
   178     for (int x = 0; x < w; ++x) {
       
   179         int y = h - 1;
       
   180 
       
   181         for (int i = 0; i < unaligned; ++i) {
       
   182             dest[x * dstride + h - y - 1]
       
   183                 = qt_colorConvert<DST,SRC>(src[y * sstride + x], 0);
       
   184             --y;
       
   185         }
       
   186 
       
   187         quint32 *d = reinterpret_cast<quint32*>(dest + x * dstride
       
   188                                                 + unaligned);
       
   189         const int rest = (h - unaligned) % pack;
       
   190         while (y > rest) {
       
   191             quint32 c = qt_colorConvert<DST,SRC>(src[y * sstride + x], 0);
       
   192             for (int i = 1; i < pack; ++i) {
       
   193                 c |= qt_colorConvert<DST,SRC>(src[(y - i) * sstride + x], 0)
       
   194                      << (sizeof(int) * 8 / pack * i);
       
   195             }
       
   196             *d++ = c;
       
   197             y -= pack;
       
   198         }
       
   199         while (y >= 0) {
       
   200             dest[x * dstride + h - y - 1]
       
   201                 = qt_colorConvert<DST,SRC>(src[y * sstride + x], 0);
       
   202             --y;
       
   203         }
       
   204     }
       
   205 }
       
   206 
       
   207 #endif // QT_ROTATION_PACKING
       
   208 
       
   209 #if QT_ROTATION_ALGORITHM == QT_ROTATION_TILED
       
   210 template <class DST, class SRC>
       
   211 Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate90_tiled(const SRC *src, int w, int h,
       
   212                                         int sstride,
       
   213                                         DST *dest, int dstride)
       
   214 {
       
   215     sstride /= sizeof(SRC);
       
   216     dstride /= sizeof(DST);
       
   217 
       
   218     const int pack = sizeof(quint32) / sizeof(DST);
       
   219     const int unaligned =
       
   220         qMin(uint((quintptr(dest) & (sizeof(quint32)-1)) / sizeof(DST)), uint(h));
       
   221     const int restX = w % tileSize;
       
   222     const int restY = (h - unaligned) % tileSize;
       
   223     const int unoptimizedY = restY % pack;
       
   224     const int numTilesX = w / tileSize + (restX > 0);
       
   225     const int numTilesY = (h - unaligned) / tileSize + (restY >= pack);
       
   226 
       
   227     for (int tx = 0; tx < numTilesX; ++tx) {
       
   228         const int startx = w - tx * tileSize - 1;
       
   229         const int stopx = qMax(startx - tileSize, 0);
       
   230 
       
   231         if (unaligned) {
       
   232             for (int x = startx; x >= stopx; --x) {
       
   233                 DST *d = dest + (w - x - 1) * dstride;
       
   234                 for (int y = 0; y < unaligned; ++y) {
       
   235                     *d++ = qt_colorConvert<DST,SRC>(src[y * sstride + x], 0);
       
   236                 }
       
   237             }
       
   238         }
       
   239 
       
   240         for (int ty = 0; ty < numTilesY; ++ty) {
       
   241             const int starty = ty * tileSize + unaligned;
       
   242             const int stopy = qMin(starty + tileSize, h - unoptimizedY);
       
   243 
       
   244             for (int x = startx; x >= stopx; --x) {
       
   245                 quint32 *d = reinterpret_cast<quint32*>(dest + (w - x - 1) * dstride + starty);
       
   246                 for (int y = starty; y < stopy; y += pack) {
       
   247                     quint32 c = qt_colorConvert<DST,SRC>(src[y * sstride + x], 0);
       
   248                     for (int i = 1; i < pack; ++i) {
       
   249                         const int shift = (sizeof(int) * 8 / pack * i);
       
   250                         const DST color = qt_colorConvert<DST,SRC>(src[(y + i) * sstride + x], 0);
       
   251                         c |= color << shift;
       
   252                     }
       
   253                     *d++ = c;
       
   254                 }
       
   255             }
       
   256         }
       
   257 
       
   258         if (unoptimizedY) {
       
   259             const int starty = h - unoptimizedY;
       
   260             for (int x = startx; x >= stopx; --x) {
       
   261                 DST *d = dest + (w - x - 1) * dstride + starty;
       
   262                 for (int y = starty; y < h; ++y) {
       
   263                     *d++ = qt_colorConvert<DST,SRC>(src[y * sstride + x], 0);
       
   264                 }
       
   265             }
       
   266         }
       
   267     }
       
   268 }
       
   269 
       
   270 template <class DST, class SRC>
       
   271 Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate90_tiled_unpacked(const SRC *src, int w, int h,
       
   272                                                  int sstride,
       
   273                                                  DST *dest, int dstride)
       
   274 {
       
   275     const int numTilesX = (w + tileSize - 1) / tileSize;
       
   276     const int numTilesY = (h + tileSize - 1) / tileSize;
       
   277 
       
   278     for (int tx = 0; tx < numTilesX; ++tx) {
       
   279         const int startx = w - tx * tileSize - 1;
       
   280         const int stopx = qMax(startx - tileSize, 0);
       
   281 
       
   282         for (int ty = 0; ty < numTilesY; ++ty) {
       
   283             const int starty = ty * tileSize;
       
   284             const int stopy = qMin(starty + tileSize, h);
       
   285 
       
   286             for (int x = startx; x >= stopx; --x) {
       
   287                 DST *d = (DST*)((char*)dest + (w - x - 1) * dstride) + starty;
       
   288                 const char *s = (const char*)(src + x) + starty * sstride;
       
   289                 for (int y = starty; y < stopy; ++y) {
       
   290                     *d++ = qt_colorConvert<DST,SRC>(*(const SRC*)(s), 0);
       
   291                     s += sstride;
       
   292                 }
       
   293             }
       
   294         }
       
   295     }
       
   296 }
       
   297 
       
   298 template <class DST, class SRC>
       
   299 Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate270_tiled(const SRC *src, int w, int h,
       
   300                                          int sstride,
       
   301                                          DST *dest, int dstride)
       
   302 {
       
   303     sstride /= sizeof(SRC);
       
   304     dstride /= sizeof(DST);
       
   305 
       
   306     const int pack = sizeof(quint32) / sizeof(DST);
       
   307     const int unaligned =
       
   308         qMin(uint((long(dest) & (sizeof(quint32)-1)) / sizeof(DST)), uint(h));
       
   309     const int restX = w % tileSize;
       
   310     const int restY = (h - unaligned) % tileSize;
       
   311     const int unoptimizedY = restY % pack;
       
   312     const int numTilesX = w / tileSize + (restX > 0);
       
   313     const int numTilesY = (h - unaligned) / tileSize + (restY >= pack);
       
   314 
       
   315     for (int tx = 0; tx < numTilesX; ++tx) {
       
   316         const int startx = tx * tileSize;
       
   317         const int stopx = qMin(startx + tileSize, w);
       
   318 
       
   319         if (unaligned) {
       
   320             for (int x = startx; x < stopx; ++x) {
       
   321                 DST *d = dest + x * dstride;
       
   322                 for (int y = h - 1; y >= h - unaligned; --y) {
       
   323                     *d++ = qt_colorConvert<DST,SRC>(src[y * sstride + x], 0);
       
   324                 }
       
   325             }
       
   326         }
       
   327 
       
   328         for (int ty = 0; ty < numTilesY; ++ty) {
       
   329             const int starty = h - 1 - unaligned - ty * tileSize;
       
   330             const int stopy = qMax(starty - tileSize, unoptimizedY);
       
   331 
       
   332             for (int x = startx; x < stopx; ++x) {
       
   333                 quint32 *d = reinterpret_cast<quint32*>(dest + x * dstride
       
   334                                                         + h - 1 - starty);
       
   335                 for (int y = starty; y > stopy; y -= pack) {
       
   336                     quint32 c = qt_colorConvert<DST,SRC>(src[y * sstride + x], 0);
       
   337                     for (int i = 1; i < pack; ++i) {
       
   338                         const int shift = (sizeof(int) * 8 / pack * i);
       
   339                         const DST color = qt_colorConvert<DST,SRC>(src[(y - i) * sstride + x], 0);
       
   340                         c |= color << shift;
       
   341                     }
       
   342                     *d++ = c;
       
   343                 }
       
   344             }
       
   345         }
       
   346         if (unoptimizedY) {
       
   347             const int starty = unoptimizedY - 1;
       
   348             for (int x = startx; x < stopx; ++x) {
       
   349                 DST *d = dest + x * dstride + h - 1 - starty;
       
   350                 for (int y = starty; y >= 0; --y) {
       
   351                     *d++ = qt_colorConvert<DST,SRC>(src[y * sstride + x], 0);
       
   352                 }
       
   353             }
       
   354         }
       
   355     }
       
   356 }
       
   357 
       
   358 template <class DST, class SRC>
       
   359 Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate270_tiled_unpacked(const SRC *src, int w, int h,
       
   360                                                   int sstride,
       
   361                                                   DST *dest, int dstride)
       
   362 {
       
   363     const int numTilesX = (w + tileSize - 1) / tileSize;
       
   364     const int numTilesY = (h + tileSize - 1) / tileSize;
       
   365 
       
   366     for (int tx = 0; tx < numTilesX; ++tx) {
       
   367         const int startx = tx * tileSize;
       
   368         const int stopx = qMin(startx + tileSize, w);
       
   369 
       
   370         for (int ty = 0; ty < numTilesY; ++ty) {
       
   371             const int starty = h - 1 - ty * tileSize;
       
   372             const int stopy = qMax(starty - tileSize, 0);
       
   373 
       
   374             for (int x = startx; x < stopx; ++x) {
       
   375                 DST *d = (DST*)((char*)dest + x * dstride) + h - 1 - starty;
       
   376                 const char *s = (const char*)(src + x) + starty * sstride;
       
   377                 for (int y = starty; y >= stopy; --y) {
       
   378                     *d++ = qt_colorConvert<DST,SRC>(*(const SRC*)s, 0);
       
   379                     s -= sstride;
       
   380                 }
       
   381             }
       
   382         }
       
   383     }
       
   384 }
       
   385 
       
   386 #endif // QT_ROTATION_ALGORITHM
       
   387 
       
   388 template <class DST, class SRC>
       
   389 Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate90_template(const SRC *src,
       
   390                                            int srcWidth, int srcHeight, int srcStride,
       
   391                                            DST *dest, int dstStride)
       
   392 {
       
   393 #if QT_ROTATION_ALGORITHM == QT_ROTATION_CACHEDREAD
       
   394     qt_memrotate90_cachedRead<DST,SRC>(src, srcWidth, srcHeight, srcStride,
       
   395                                        dest, dstStride);
       
   396 #elif QT_ROTATION_ALGORITHM == QT_ROTATION_CACHEDWRITE
       
   397     qt_memrotate90_cachedWrite<DST,SRC>(src, srcWidth, srcHeight, srcStride,
       
   398                                         dest, dstStride);
       
   399 #elif QT_ROTATION_ALGORITHM == QT_ROTATION_PACKING
       
   400     qt_memrotate90_packing<DST,SRC>(src, srcWidth, srcHeight, srcStride,
       
   401                                     dest, dstStride);
       
   402 #elif QT_ROTATION_ALGORITHM == QT_ROTATION_TILED
       
   403     qt_memrotate90_tiled<DST,SRC>(src, srcWidth, srcHeight, srcStride,
       
   404                                   dest, dstStride);
       
   405 #endif
       
   406 }
       
   407 
       
   408 template <class DST, class SRC>
       
   409 Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate180_template(const SRC *src,
       
   410                                             int w, int h, int sstride,
       
   411                                             DST *dest, int dstride)
       
   412 {
       
   413     const char *s = (const char*)(src) + (h - 1) * sstride;
       
   414     for (int y = h - 1; y >= 0; --y) {
       
   415         DST *d = reinterpret_cast<DST*>((char *)(dest) + (h - y - 1) * dstride);
       
   416         src = reinterpret_cast<const SRC*>(s);
       
   417         for (int x = w - 1; x >= 0; --x) {
       
   418             d[w - x - 1] = qt_colorConvert<DST,SRC>(src[x], 0);
       
   419         }
       
   420         s -= sstride;
       
   421     }
       
   422 }
       
   423 
       
   424 template <class DST, class SRC>
       
   425 Q_STATIC_TEMPLATE_FUNCTION inline void qt_memrotate270_template(const SRC *src,
       
   426                                             int srcWidth, int srcHeight, int srcStride,
       
   427                                             DST *dest, int dstStride)
       
   428 {
       
   429 #if QT_ROTATION_ALGORITHM == QT_ROTATION_CACHEDREAD
       
   430     qt_memrotate270_cachedRead<DST,SRC>(src, srcWidth, srcHeight, srcStride,
       
   431                                         dest, dstStride);
       
   432 #elif QT_ROTATION_ALGORITHM == QT_ROTATION_CACHEDWRITE
       
   433     qt_memrotate270_cachedWrite<DST,SRC>(src, srcWidth, srcHeight, srcStride,
       
   434                                          dest, dstStride);
       
   435 #elif QT_ROTATION_ALGORITHM == QT_ROTATION_PACKING
       
   436     qt_memrotate270_packing<DST,SRC>(src, srcWidth, srcHeight, srcStride,
       
   437                                      dest, dstStride);
       
   438 #elif QT_ROTATION_ALGORITHM == QT_ROTATION_TILED
       
   439     qt_memrotate270_tiled_unpacked<DST,SRC>(src, srcWidth, srcHeight,
       
   440                                             srcStride,
       
   441                                             dest, dstStride);
       
   442 #endif
       
   443 }
       
   444 
       
   445 template <>
       
   446 Q_STATIC_TEMPLATE_SPECIALIZATION
       
   447 inline void qt_memrotate90_template<quint24, quint24>(const quint24 *src,
       
   448                                                              int srcWidth, int srcHeight, int srcStride,
       
   449                                                              quint24 *dest, int dstStride)
       
   450 {
       
   451 #if QT_ROTATION_ALGORITHM == QT_ROTATION_CACHEDREAD
       
   452     qt_memrotate90_cachedRead<quint24,quint24>(src, srcWidth, srcHeight,
       
   453                                                srcStride, dest, dstStride);
       
   454 #elif QT_ROTATION_ALGORITHM == QT_ROTATION_CACHEDWRITE
       
   455     qt_memrotate90_cachedWrite<quint24,quint24>(src, srcWidth, srcHeight,
       
   456                                                 srcStride, dest, dstStride);
       
   457 #elif QT_ROTATION_ALGORITHM == QT_ROTATION_PACKING
       
   458     // packed algorithm not implemented
       
   459     qt_memrotate90_cachedRead<quint24,quint24>(src, srcWidth, srcHeight,
       
   460                                                srcStride, dest, dstStride);
       
   461 #elif QT_ROTATION_ALGORITHM == QT_ROTATION_TILED
       
   462     // packed algorithm not implemented
       
   463     qt_memrotate90_tiled_unpacked<quint24,quint24>(src, srcWidth, srcHeight,
       
   464                                                    srcStride, dest, dstStride);
       
   465 #endif
       
   466 }
       
   467 
       
   468 template <>
       
   469 Q_STATIC_TEMPLATE_SPECIALIZATION
       
   470 inline void qt_memrotate90_template<quint24, quint32>(const quint32 *src,
       
   471                                                              int srcWidth, int srcHeight, int srcStride,
       
   472                                                              quint24 *dest, int dstStride)
       
   473 {
       
   474 #if QT_ROTATION_ALGORITHM == QT_ROTATION_CACHEDREAD
       
   475     qt_memrotate90_cachedRead<quint24,quint32>(src, srcWidth, srcHeight,
       
   476                                                srcStride, dest, dstStride);
       
   477 #elif QT_ROTATION_ALGORITHM == QT_ROTATION_CACHEDWRITE
       
   478     qt_memrotate90_cachedWrite<quint24,quint32>(src, srcWidth, srcHeight,
       
   479                                                 srcStride, dest, dstStride);
       
   480 #elif QT_ROTATION_ALGORITHM == QT_ROTATION_PACKING
       
   481     // packed algorithm not implemented
       
   482     qt_memrotate90_cachedRead<quint24,quint32>(src, srcWidth, srcHeight,
       
   483                                                srcStride, dest, dstStride);
       
   484 #elif QT_ROTATION_ALGORITHM == QT_ROTATION_TILED
       
   485     // packed algorithm not implemented
       
   486     qt_memrotate90_tiled_unpacked<quint24,quint32>(src, srcWidth, srcHeight,
       
   487                                                    srcStride, dest, dstStride);
       
   488 #endif
       
   489 }
       
   490 
       
   491 template <>
       
   492 Q_STATIC_TEMPLATE_SPECIALIZATION
       
   493 inline void qt_memrotate90_template<quint18, quint32>(const quint32 *src,
       
   494                                                              int srcWidth, int srcHeight, int srcStride,
       
   495                                                              quint18 *dest, int dstStride)
       
   496 {
       
   497 #if QT_ROTATION_ALGORITHM == QT_ROTATION_CACHEDREAD
       
   498     qt_memrotate90_cachedRead<quint18,quint32>(src, srcWidth, srcHeight,
       
   499                                                srcStride, dest, dstStride);
       
   500 #elif QT_ROTATION_ALGORITHM == QT_ROTATION_CACHEDWRITE
       
   501     qt_memrotate90_cachedWrite<quint18,quint32>(src, srcWidth, srcHeight,
       
   502                                                 srcStride, dest, dstStride);
       
   503 #elif QT_ROTATION_ALGORITHM == QT_ROTATION_PACKING
       
   504     // packed algorithm not implemented
       
   505     qt_memrotate90_cachedRead<quint18,quint32>(src, srcWidth, srcHeight,
       
   506                                                srcStride, dest, dstStride);
       
   507 #elif QT_ROTATION_ALGORITHM == QT_ROTATION_TILED
       
   508     // packed algorithm not implemented
       
   509     qt_memrotate90_tiled_unpacked<quint18,quint32>(src, srcWidth, srcHeight,
       
   510                                                    srcStride, dest, dstStride);
       
   511 #endif
       
   512 }
       
   513 
       
   514 #define QT_IMPL_MEMROTATE(srctype, desttype)                        \
       
   515 void qt_memrotate90(const srctype *src, int w, int h, int sstride,  \
       
   516                     desttype *dest, int dstride)                    \
       
   517 {                                                                   \
       
   518     qt_memrotate90_template(src, w, h, sstride, dest, dstride);     \
       
   519 }                                                                   \
       
   520 void qt_memrotate180(const srctype *src, int w, int h, int sstride, \
       
   521                      desttype *dest, int dstride)                   \
       
   522 {                                                                   \
       
   523     qt_memrotate180_template(src, w, h, sstride, dest, dstride);    \
       
   524 }                                                                   \
       
   525 void qt_memrotate270(const srctype *src, int w, int h, int sstride, \
       
   526                      desttype *dest, int dstride)                   \
       
   527 {                                                                   \
       
   528     qt_memrotate270_template(src, w, h, sstride, dest, dstride);    \
       
   529 }
       
   530 
       
   531 #define QT_IMPL_SIMPLE_MEMROTATE(srctype, desttype)                 \
       
   532 void qt_memrotate90(const srctype *src, int w, int h, int sstride,  \
       
   533                     desttype *dest, int dstride)                    \
       
   534 {                                                                   \
       
   535     qt_memrotate90_tiled_unpacked<desttype,srctype>(src, w, h, sstride, dest, dstride); \
       
   536 }                                                                   \
       
   537 void qt_memrotate180(const srctype *src, int w, int h, int sstride, \
       
   538                      desttype *dest, int dstride)                   \
       
   539 {                                                                   \
       
   540     qt_memrotate180_template(src, w, h, sstride, dest, dstride);    \
       
   541 }                                                                   \
       
   542 void qt_memrotate270(const srctype *src, int w, int h, int sstride, \
       
   543                      desttype *dest, int dstride)                   \
       
   544 {                                                                   \
       
   545     qt_memrotate270_tiled_unpacked<desttype,srctype>(src, w, h, sstride, dest, dstride); \
       
   546 }
       
   547 
       
   548 
       
   549 
       
   550 
       
   551 QT_IMPL_MEMROTATE(quint32, quint32)
       
   552 QT_IMPL_MEMROTATE(quint32, quint16)
       
   553 QT_IMPL_MEMROTATE(quint16, quint32)
       
   554 QT_IMPL_MEMROTATE(quint16, quint16)
       
   555 QT_IMPL_MEMROTATE(quint24, quint24)
       
   556 QT_IMPL_MEMROTATE(quint32, quint24)
       
   557 QT_IMPL_MEMROTATE(quint32, quint18)
       
   558 QT_IMPL_MEMROTATE(quint32, quint8)
       
   559 QT_IMPL_MEMROTATE(quint16, quint8)
       
   560 QT_IMPL_MEMROTATE(qrgb444, quint8)
       
   561 QT_IMPL_MEMROTATE(quint8, quint8)
       
   562 
       
   563 #if defined(QT_QWS_ROTATE_BGR)
       
   564 QT_IMPL_SIMPLE_MEMROTATE(quint16, qbgr565)
       
   565 QT_IMPL_SIMPLE_MEMROTATE(quint32, qbgr565)
       
   566 QT_IMPL_SIMPLE_MEMROTATE(qrgb555, qbgr555)
       
   567 QT_IMPL_SIMPLE_MEMROTATE(quint32, qbgr555)
       
   568 #endif
       
   569 
       
   570 #ifdef QT_QWS_DEPTH_GENERIC
       
   571 QT_IMPL_MEMROTATE(quint32, qrgb_generic16)
       
   572 QT_IMPL_MEMROTATE(quint16, qrgb_generic16)
       
   573 #endif
       
   574 
       
   575 
       
   576 QT_END_NAMESPACE