1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 
40 #include <qmath.h>
41 #include "qblendfunctions_p.h"
42 
43 QT_BEGIN_NAMESPACE
44 
45 struct SourceOnlyAlpha
46 {
alphaSourceOnlyAlpha47     inline uchar alpha(uchar src) const { return src; }
bytemulSourceOnlyAlpha48     inline quint16 bytemul(quint16 spix) const { return spix; }
49 };
50 
51 
52 struct SourceAndConstAlpha
53 {
SourceAndConstAlphaSourceAndConstAlpha54     SourceAndConstAlpha(int a) : m_alpha256(a) {
55         m_alpha255 = (m_alpha256 * 255) >> 8;
56     };
alphaSourceAndConstAlpha57     inline uchar alpha(uchar src) const { return (src * m_alpha256) >> 8; }
bytemulSourceAndConstAlpha58     inline quint16 bytemul(quint16 x) const {
59         uint t = (((x & 0x07e0)*m_alpha255) >> 8) & 0x07e0;
60         t |= (((x & 0xf81f)*(m_alpha255>>2)) >> 6) & 0xf81f;
61         return t;
62     }
63     int m_alpha255;
64     int m_alpha256;
65 };
66 
67 
68 /************************************************************************
69                        RGB16 (565) format target format
70  ************************************************************************/
71 
72 struct Blend_RGB16_on_RGB16_NoAlpha {
writeBlend_RGB16_on_RGB16_NoAlpha73     inline void write(quint16 *dst, quint16 src) { *dst = src; }
74 
flushBlend_RGB16_on_RGB16_NoAlpha75     inline void flush(void *) {}
76 };
77 
78 struct Blend_RGB16_on_RGB16_ConstAlpha {
Blend_RGB16_on_RGB16_ConstAlphaBlend_RGB16_on_RGB16_ConstAlpha79     inline Blend_RGB16_on_RGB16_ConstAlpha(quint32 alpha) {
80         m_alpha = (alpha * 255) >> 8;
81         m_ialpha = 255 - m_alpha;
82     }
83 
writeBlend_RGB16_on_RGB16_ConstAlpha84     inline void write(quint16 *dst, quint16 src) {
85         *dst = BYTE_MUL_RGB16(src, m_alpha) + BYTE_MUL_RGB16(*dst, m_ialpha);
86     }
87 
flushBlend_RGB16_on_RGB16_ConstAlpha88     inline void flush(void *) {}
89 
90     quint32 m_alpha;
91     quint32 m_ialpha;
92 };
93 
94 struct Blend_ARGB32_on_RGB16_SourceAlpha {
writeBlend_ARGB32_on_RGB16_SourceAlpha95     inline void write(quint16 *dst, quint32 src) {
96         const quint8 alpha = qAlpha(src);
97         if (alpha) {
98             quint16 s = qConvertRgb32To16(src);
99             if(alpha < 255)
100                 s += BYTE_MUL_RGB16(*dst, 255 - alpha);
101             *dst = s;
102         }
103     }
104 
flushBlend_ARGB32_on_RGB16_SourceAlpha105     inline void flush(void *) {}
106 };
107 
108 struct Blend_ARGB32_on_RGB16_SourceAndConstAlpha {
Blend_ARGB32_on_RGB16_SourceAndConstAlphaBlend_ARGB32_on_RGB16_SourceAndConstAlpha109     inline Blend_ARGB32_on_RGB16_SourceAndConstAlpha(quint32 alpha) {
110         m_alpha = (alpha * 255) >> 8;
111     }
112 
writeBlend_ARGB32_on_RGB16_SourceAndConstAlpha113     inline void write(quint16 *dst, quint32 src) {
114         src = BYTE_MUL(src, m_alpha);
115         const quint8 alpha = qAlpha(src);
116         if(alpha) {
117             quint16 s = qConvertRgb32To16(src);
118             if(alpha < 255)
119                 s += BYTE_MUL_RGB16(*dst, 255 - alpha);
120             *dst = s;
121         }
122     }
123 
flushBlend_ARGB32_on_RGB16_SourceAndConstAlpha124     inline void flush(void *) {}
125 
126     quint32 m_alpha;
127 };
128 
qt_scale_image_rgb16_on_rgb16(uchar * destPixels,int dbpl,const uchar * srcPixels,int sbpl,int srch,const QRectF & targetRect,const QRectF & sourceRect,const QRect & clip,int const_alpha)129 void qt_scale_image_rgb16_on_rgb16(uchar *destPixels, int dbpl,
130                                    const uchar *srcPixels, int sbpl, int srch,
131                                    const QRectF &targetRect,
132                                    const QRectF &sourceRect,
133                                    const QRect &clip,
134                                    int const_alpha)
135 {
136 #ifdef QT_DEBUG_DRAW
137     printf("qt_scale_rgb16_on_rgb16: dst=(%p, %d), src=(%p, %d), target=(%d, %d), [%d x %d], src=(%d, %d) [%d x %d] alpha=%d\n",
138            destPixels, dbpl, srcPixels, sbpl,
139            targetRect.x(), targetRect.y(), targetRect.width(), targetRect.height(),
140            sourceRect.x(), sourceRect.y(), sourceRect.width(), sourceRect.height(),
141            const_alpha);
142 #endif
143     if (const_alpha == 256) {
144         Blend_RGB16_on_RGB16_NoAlpha noAlpha;
145         qt_scale_image_16bit<quint16>(destPixels, dbpl, srcPixels, sbpl, srch,
146                                       targetRect, sourceRect, clip, noAlpha);
147     } else {
148         Blend_RGB16_on_RGB16_ConstAlpha constAlpha(const_alpha);
149         qt_scale_image_16bit<quint16>(destPixels, dbpl, srcPixels, sbpl, srch,
150                                      targetRect, sourceRect, clip, constAlpha);
151     }
152 }
153 
qt_scale_image_argb32_on_rgb16(uchar * destPixels,int dbpl,const uchar * srcPixels,int sbpl,int srch,const QRectF & targetRect,const QRectF & sourceRect,const QRect & clip,int const_alpha)154 void qt_scale_image_argb32_on_rgb16(uchar *destPixels, int dbpl,
155                                     const uchar *srcPixels, int sbpl, int srch,
156                                     const QRectF &targetRect,
157                                     const QRectF &sourceRect,
158                                     const QRect &clip,
159                                     int const_alpha)
160 {
161 #ifdef QT_DEBUG_DRAW
162     printf("qt_scale_argb32_on_rgb16: dst=(%p, %d), src=(%p, %d), target=(%d, %d), [%d x %d], src=(%d, %d) [%d x %d] alpha=%d\n",
163            destPixels, dbpl, srcPixels, sbpl,
164            targetRect.x(), targetRect.y(), targetRect.width(), targetRect.height(),
165            sourceRect.x(), sourceRect.y(), sourceRect.width(), sourceRect.height(),
166            const_alpha);
167 #endif
168     if (const_alpha == 256) {
169         Blend_ARGB32_on_RGB16_SourceAlpha noAlpha;
170         qt_scale_image_16bit<quint32>(destPixels, dbpl, srcPixels, sbpl, srch,
171                                       targetRect, sourceRect, clip, noAlpha);
172     } else {
173         Blend_ARGB32_on_RGB16_SourceAndConstAlpha constAlpha(const_alpha);
174         qt_scale_image_16bit<quint32>(destPixels, dbpl, srcPixels, sbpl, srch,
175                                      targetRect, sourceRect, clip, constAlpha);
176     }
177 }
178 
qt_blend_rgb16_on_rgb16(uchar * dst,int dbpl,const uchar * src,int sbpl,int w,int h,int const_alpha)179 void qt_blend_rgb16_on_rgb16(uchar *dst, int dbpl,
180                              const uchar *src, int sbpl,
181                              int w, int h,
182                              int const_alpha)
183 {
184 #ifdef QT_DEBUG_DRAW
185     printf("qt_blend_rgb16_on_rgb16: dst=(%p, %d), src=(%p, %d), dim=(%d, %d) alpha=%d\n",
186            dst, dbpl, src, sbpl, w, h, const_alpha);
187 #endif
188 
189     if (const_alpha == 256) {
190         int length = w << 1;
191         while (h--) {
192             memcpy(dst, src, length);
193             dst += dbpl;
194             src += sbpl;
195         }
196     } else if (const_alpha != 0) {
197         quint16 *d = (quint16 *) dst;
198         const quint16 *s = (const quint16 *) src;
199         quint8 a = (255 * const_alpha) >> 8;
200         quint8 ia = 255 - a;
201         while (h--) {
202             for (int x=0; x<w; ++x) {
203                 d[x] = BYTE_MUL_RGB16(s[x], a) + BYTE_MUL_RGB16(d[x], ia);
204             }
205             d = (quint16 *)(((uchar *) d) + dbpl);
206             s = (const quint16 *)(((const uchar *) s) + sbpl);
207         }
208     }
209 }
210 
211 
qt_blend_argb32_on_rgb16_const_alpha(uchar * destPixels,int dbpl,const uchar * srcPixels,int sbpl,int w,int h,int const_alpha)212 void qt_blend_argb32_on_rgb16_const_alpha(uchar *destPixels, int dbpl,
213                                           const uchar *srcPixels, int sbpl,
214                                           int w, int h,
215                                           int const_alpha)
216 {
217     quint16 *dst = (quint16 *) destPixels;
218     const quint32 *src = (const quint32 *) srcPixels;
219 
220     const_alpha = (const_alpha * 255) >> 8;
221     for (int y=0; y<h; ++y) {
222         for (int i = 0; i < w; ++i) {
223             uint s = src[i];
224             s = BYTE_MUL(s, const_alpha);
225             int alpha = qAlpha(s);
226             s = qConvertRgb32To16(s);
227             s += BYTE_MUL_RGB16(dst[i], 255 - alpha);
228             dst[i] = s;
229         }
230         dst = (quint16 *)(((uchar *) dst) + dbpl);
231         src = (const quint32 *)(((const uchar *) src) + sbpl);
232     }
233 }
234 
qt_blend_argb32_on_rgb16(uchar * destPixels,int dbpl,const uchar * srcPixels,int sbpl,int w,int h,int const_alpha)235 static void qt_blend_argb32_on_rgb16(uchar *destPixels, int dbpl,
236                                      const uchar *srcPixels, int sbpl,
237                                      int w, int h,
238                                      int const_alpha)
239 {
240     if (const_alpha != 256) {
241         qt_blend_argb32_on_rgb16_const_alpha(destPixels, dbpl, srcPixels, sbpl, w, h, const_alpha);
242         return;
243     }
244 
245     quint16 *dst = (quint16 *) destPixels;
246     const quint32 *src = (const quint32 *) srcPixels;
247 
248     for (int y=0; y<h; ++y) {
249         for (int x=0; x<w; ++x) {
250 
251             quint32 spix = src[x];
252             quint32 alpha = spix >> 24;
253 
254             if (alpha == 255) {
255                 dst[x] = qConvertRgb32To16(spix);
256             } else if (alpha != 0) {
257                 quint32 dpix = dst[x];
258 
259                 quint32 sia = 255 - alpha;
260 
261                 quint32 sr = (spix >> 8) & 0xf800;
262                 quint32 sg = (spix >> 5) & 0x07e0;
263                 quint32 sb = (spix >> 3) & 0x001f;
264 
265                 quint32 dr = (dpix & 0x0000f800);
266                 quint32 dg = (dpix & 0x000007e0);
267                 quint32 db = (dpix & 0x0000001f);
268 
269                 quint32 siar = dr * sia;
270                 quint32 siag = dg * sia;
271                 quint32 siab = db * sia;
272 
273                 quint32 rr = sr + ((siar + (siar>>8) + (0x80 << 8)) >> 8);
274                 quint32 rg = sg + ((siag + (siag>>8) + (0x80 << 3)) >> 8);
275                 quint32 rb = sb + ((siab + (siab>>8) + (0x80 >> 3)) >> 8);
276 
277                 dst[x] = (rr & 0xf800)
278                          | (rg & 0x07e0)
279                          | (rb);
280             }
281         }
282         dst = (quint16 *) (((uchar *) dst) + dbpl);
283         src = (const quint32 *) (((const uchar *) src) + sbpl);
284     }
285 }
286 
287 
qt_blend_rgb32_on_rgb16(uchar * destPixels,int dbpl,const uchar * srcPixels,int sbpl,int w,int h,int const_alpha)288 static void qt_blend_rgb32_on_rgb16(uchar *destPixels, int dbpl,
289                                     const uchar *srcPixels, int sbpl,
290                                     int w, int h,
291                                     int const_alpha)
292 {
293 #ifdef QT_DEBUG_DRAW
294     printf("qt_blend_rgb32_on_rgb16: dst=(%p, %d), src=(%p, %d), dim=(%d, %d) alpha=%d\n",
295            destPixels, dbpl, srcPixels, sbpl, w, h, const_alpha);
296 #endif
297 
298     if (const_alpha != 256) {
299         qt_blend_argb32_on_rgb16(destPixels, dbpl, srcPixels, sbpl, w, h, const_alpha);
300         return;
301     }
302 
303     const quint32 *src = (const quint32 *) srcPixels;
304     int srcExtraStride = (sbpl >> 2) - w;
305 
306     int dstJPL = dbpl / 2;
307 
308     quint16 *dst = (quint16 *) destPixels;
309     quint16 *dstEnd = dst + dstJPL * h;
310 
311     int dstExtraStride = dstJPL - w;
312 
313     while (dst < dstEnd) {
314         const quint32 *srcEnd = src + w;
315         while (src < srcEnd) {
316             *dst = qConvertRgb32To16(*src);
317             ++dst;
318             ++src;
319         }
320         dst += dstExtraStride;
321         src += srcExtraStride;
322     }
323 }
324 
325 
326 
327 /************************************************************************
328                        RGB32 (-888) format target format
329  ************************************************************************/
330 
qt_blend_argb32_on_argb32(uchar * destPixels,int dbpl,const uchar * srcPixels,int sbpl,int w,int h,int const_alpha)331 static void qt_blend_argb32_on_argb32(uchar *destPixels, int dbpl,
332                                       const uchar *srcPixels, int sbpl,
333                                       int w, int h,
334                                       int const_alpha)
335 {
336 #ifdef QT_DEBUG_DRAW
337     fprintf(stdout, "qt_blend_argb32_on_argb32: dst=(%p, %d), src=(%p, %d), dim=(%d, %d) alpha=%d\n",
338             destPixels, dbpl, srcPixels, sbpl, w, h, const_alpha);
339     fflush(stdout);
340 #endif
341 
342     const uint *src = (const uint *) srcPixels;
343     uint *dst = (uint *) destPixels;
344     if (const_alpha == 256) {
345         for (int y=0; y<h; ++y) {
346             for (int x=0; x<w; ++x) {
347                 uint s = src[x];
348                 if (s >= 0xff000000)
349                     dst[x] = s;
350                 else if (s != 0)
351                     dst[x] = s + BYTE_MUL(dst[x], qAlpha(~s));
352             }
353             dst = (quint32 *)(((uchar *) dst) + dbpl);
354             src = (const quint32 *)(((const uchar *) src) + sbpl);
355         }
356     } else if (const_alpha != 0) {
357         const_alpha = (const_alpha * 255) >> 8;
358         for (int y=0; y<h; ++y) {
359             for (int x=0; x<w; ++x) {
360                 uint s = BYTE_MUL(src[x], const_alpha);
361                 dst[x] = s + BYTE_MUL(dst[x], qAlpha(~s));
362             }
363             dst = (quint32 *)(((uchar *) dst) + dbpl);
364             src = (const quint32 *)(((const uchar *) src) + sbpl);
365         }
366     }
367 }
368 
369 
qt_blend_rgb32_on_rgb32(uchar * destPixels,int dbpl,const uchar * srcPixels,int sbpl,int w,int h,int const_alpha)370 void qt_blend_rgb32_on_rgb32(uchar *destPixels, int dbpl,
371                              const uchar *srcPixels, int sbpl,
372                              int w, int h,
373                              int const_alpha)
374 {
375 #ifdef QT_DEBUG_DRAW
376     fprintf(stdout, "qt_blend_rgb32_on_rgb32: dst=(%p, %d), src=(%p, %d), dim=(%d, %d) alpha=%d\n",
377             destPixels, dbpl, srcPixels, sbpl, w, h, const_alpha);
378     fflush(stdout);
379 #endif
380     const uint *src = (const uint *) srcPixels;
381     uint *dst = (uint *) destPixels;
382     if (const_alpha == 256) {
383         const int len = w * 4;
384         for (int y = 0; y < h; ++y) {
385             memcpy(dst, src, len);
386             dst = (quint32 *)(((uchar *) dst) + dbpl);
387             src = (const quint32 *)(((const uchar *) src) + sbpl);
388         }
389         return;
390     } else if (const_alpha != 0) {
391         const_alpha = (const_alpha * 255) >> 8;
392         int ialpha = 255 - const_alpha;
393         for (int y=0; y<h; ++y) {
394             for (int x=0; x<w; ++x)
395                 dst[x] = INTERPOLATE_PIXEL_255(dst[x], ialpha, src[x], const_alpha);
396             dst = (quint32 *)(((uchar *) dst) + dbpl);
397             src = (const quint32 *)(((const uchar *) src) + sbpl);
398         }
399     }
400 }
401 
402 struct Blend_RGB32_on_RGB32_NoAlpha {
writeBlend_RGB32_on_RGB32_NoAlpha403     inline void write(quint32 *dst, quint32 src) { *dst = src; }
404 
flushBlend_RGB32_on_RGB32_NoAlpha405     inline void flush(void *) {}
406 };
407 
408 struct Blend_RGB32_on_RGB32_ConstAlpha {
Blend_RGB32_on_RGB32_ConstAlphaBlend_RGB32_on_RGB32_ConstAlpha409     inline Blend_RGB32_on_RGB32_ConstAlpha(quint32 alpha) {
410         m_alpha = (alpha * 255) >> 8;
411         m_ialpha = 255 - m_alpha;
412     }
413 
writeBlend_RGB32_on_RGB32_ConstAlpha414     inline void write(quint32 *dst, quint32 src) {
415         *dst = INTERPOLATE_PIXEL_255(src, m_alpha, *dst, m_ialpha);
416     }
417 
flushBlend_RGB32_on_RGB32_ConstAlpha418     inline void flush(void *) {}
419 
420     quint32 m_alpha;
421     quint32 m_ialpha;
422 };
423 
424 struct Blend_ARGB32_on_ARGB32_SourceAlpha {
writeBlend_ARGB32_on_ARGB32_SourceAlpha425     inline void write(quint32 *dst, quint32 src)
426     {
427         blend_pixel(*dst, src);
428     }
429 
flushBlend_ARGB32_on_ARGB32_SourceAlpha430     inline void flush(void *) {}
431 };
432 
433 struct Blend_ARGB32_on_ARGB32_SourceAndConstAlpha {
Blend_ARGB32_on_ARGB32_SourceAndConstAlphaBlend_ARGB32_on_ARGB32_SourceAndConstAlpha434     inline Blend_ARGB32_on_ARGB32_SourceAndConstAlpha(quint32 alpha)
435     {
436         m_alpha = (alpha * 255) >> 8;
437     }
438 
writeBlend_ARGB32_on_ARGB32_SourceAndConstAlpha439     inline void write(quint32 *dst, quint32 src)
440     {
441         blend_pixel(*dst, src, m_alpha);
442     }
443 
flushBlend_ARGB32_on_ARGB32_SourceAndConstAlpha444     inline void flush(void *) {}
445 
446     quint32 m_alpha;
447 };
448 
qt_scale_image_rgb32_on_rgb32(uchar * destPixels,int dbpl,const uchar * srcPixels,int sbpl,int srch,const QRectF & targetRect,const QRectF & sourceRect,const QRect & clip,int const_alpha)449 void qt_scale_image_rgb32_on_rgb32(uchar *destPixels, int dbpl,
450                                    const uchar *srcPixels, int sbpl, int srch,
451                                    const QRectF &targetRect,
452                                    const QRectF &sourceRect,
453                                    const QRect &clip,
454                                    int const_alpha)
455 {
456 #ifdef QT_DEBUG_DRAW
457     printf("qt_scale_rgb32_on_rgb32: dst=(%p, %d), src=(%p, %d), target=(%d, %d), [%d x %d], src=(%d, %d) [%d x %d] alpha=%d\n",
458            destPixels, dbpl, srcPixels, sbpl,
459            targetRect.x(), targetRect.y(), targetRect.width(), targetRect.height(),
460            sourceRect.x(), sourceRect.y(), sourceRect.width(), sourceRect.height(),
461            const_alpha);
462 #endif
463     if (const_alpha == 256) {
464         Blend_RGB32_on_RGB32_NoAlpha noAlpha;
465         qt_scale_image_32bit(destPixels, dbpl, srcPixels, sbpl, srch,
466                              targetRect, sourceRect, clip, noAlpha);
467     } else {
468         Blend_RGB32_on_RGB32_ConstAlpha constAlpha(const_alpha);
469         qt_scale_image_32bit(destPixels, dbpl, srcPixels, sbpl, srch,
470                              targetRect, sourceRect, clip, constAlpha);
471     }
472 }
473 
qt_scale_image_argb32_on_argb32(uchar * destPixels,int dbpl,const uchar * srcPixels,int sbpl,int srch,const QRectF & targetRect,const QRectF & sourceRect,const QRect & clip,int const_alpha)474 void qt_scale_image_argb32_on_argb32(uchar *destPixels, int dbpl,
475                                      const uchar *srcPixels, int sbpl, int srch,
476                                      const QRectF &targetRect,
477                                      const QRectF &sourceRect,
478                                      const QRect &clip,
479                                      int const_alpha)
480 {
481 #ifdef QT_DEBUG_DRAW
482     printf("qt_scale_argb32_on_argb32: dst=(%p, %d), src=(%p, %d), target=(%d, %d), [%d x %d], src=(%d, %d) [%d x %d] alpha=%d\n",
483            destPixels, dbpl, srcPixels, sbpl,
484            targetRect.x(), targetRect.y(), targetRect.width(), targetRect.height(),
485            sourceRect.x(), sourceRect.y(), sourceRect.width(), sourceRect.height(),
486            const_alpha);
487 #endif
488     if (const_alpha == 256) {
489         Blend_ARGB32_on_ARGB32_SourceAlpha sourceAlpha;
490         qt_scale_image_32bit(destPixels, dbpl, srcPixels, sbpl, srch,
491                              targetRect, sourceRect, clip, sourceAlpha);
492     } else {
493         Blend_ARGB32_on_ARGB32_SourceAndConstAlpha constAlpha(const_alpha);
494         qt_scale_image_32bit(destPixels, dbpl, srcPixels, sbpl, srch,
495                              targetRect, sourceRect, clip, constAlpha);
496     }
497 }
498 
qt_transform_image_rgb16_on_rgb16(uchar * destPixels,int dbpl,const uchar * srcPixels,int sbpl,const QRectF & targetRect,const QRectF & sourceRect,const QRect & clip,const QTransform & targetRectTransform,int const_alpha)499 void qt_transform_image_rgb16_on_rgb16(uchar *destPixels, int dbpl,
500                                        const uchar *srcPixels, int sbpl,
501                                        const QRectF &targetRect,
502                                        const QRectF &sourceRect,
503                                        const QRect &clip,
504                                        const QTransform &targetRectTransform,
505                                        int const_alpha)
506 {
507     if (const_alpha == 256) {
508         Blend_RGB16_on_RGB16_NoAlpha noAlpha;
509         qt_transform_image(reinterpret_cast<quint16 *>(destPixels), dbpl,
510                            reinterpret_cast<const quint16 *>(srcPixels), sbpl,
511                            targetRect, sourceRect, clip, targetRectTransform, noAlpha);
512     } else {
513         Blend_RGB16_on_RGB16_ConstAlpha constAlpha(const_alpha);
514         qt_transform_image(reinterpret_cast<quint16 *>(destPixels), dbpl,
515                            reinterpret_cast<const quint16 *>(srcPixels), sbpl,
516                            targetRect, sourceRect, clip, targetRectTransform, constAlpha);
517     }
518 }
519 
qt_transform_image_argb32_on_rgb16(uchar * destPixels,int dbpl,const uchar * srcPixels,int sbpl,const QRectF & targetRect,const QRectF & sourceRect,const QRect & clip,const QTransform & targetRectTransform,int const_alpha)520 void qt_transform_image_argb32_on_rgb16(uchar *destPixels, int dbpl,
521                                         const uchar *srcPixels, int sbpl,
522                                         const QRectF &targetRect,
523                                         const QRectF &sourceRect,
524                                         const QRect &clip,
525                                         const QTransform &targetRectTransform,
526                                         int const_alpha)
527 {
528     if (const_alpha == 256) {
529         Blend_ARGB32_on_RGB16_SourceAlpha noAlpha;
530         qt_transform_image(reinterpret_cast<quint16 *>(destPixels), dbpl,
531                            reinterpret_cast<const quint32 *>(srcPixels), sbpl,
532                            targetRect, sourceRect, clip, targetRectTransform, noAlpha);
533     } else {
534         Blend_ARGB32_on_RGB16_SourceAndConstAlpha constAlpha(const_alpha);
535         qt_transform_image(reinterpret_cast<quint16 *>(destPixels), dbpl,
536                            reinterpret_cast<const quint32 *>(srcPixels), sbpl,
537                            targetRect, sourceRect, clip, targetRectTransform, constAlpha);
538     }
539 }
540 
541 
qt_transform_image_rgb32_on_rgb32(uchar * destPixels,int dbpl,const uchar * srcPixels,int sbpl,const QRectF & targetRect,const QRectF & sourceRect,const QRect & clip,const QTransform & targetRectTransform,int const_alpha)542 void qt_transform_image_rgb32_on_rgb32(uchar *destPixels, int dbpl,
543                                        const uchar *srcPixels, int sbpl,
544                                        const QRectF &targetRect,
545                                        const QRectF &sourceRect,
546                                        const QRect &clip,
547                                        const QTransform &targetRectTransform,
548                                        int const_alpha)
549 {
550     if (const_alpha == 256) {
551         Blend_RGB32_on_RGB32_NoAlpha noAlpha;
552         qt_transform_image(reinterpret_cast<quint32 *>(destPixels), dbpl,
553                            reinterpret_cast<const quint32 *>(srcPixels), sbpl,
554                            targetRect, sourceRect, clip, targetRectTransform, noAlpha);
555     } else {
556         Blend_RGB32_on_RGB32_ConstAlpha constAlpha(const_alpha);
557         qt_transform_image(reinterpret_cast<quint32 *>(destPixels), dbpl,
558                            reinterpret_cast<const quint32 *>(srcPixels), sbpl,
559                            targetRect, sourceRect, clip, targetRectTransform, constAlpha);
560     }
561 }
562 
qt_transform_image_argb32_on_argb32(uchar * destPixels,int dbpl,const uchar * srcPixels,int sbpl,const QRectF & targetRect,const QRectF & sourceRect,const QRect & clip,const QTransform & targetRectTransform,int const_alpha)563 void qt_transform_image_argb32_on_argb32(uchar *destPixels, int dbpl,
564                                          const uchar *srcPixels, int sbpl,
565                                          const QRectF &targetRect,
566                                          const QRectF &sourceRect,
567                                          const QRect &clip,
568                                          const QTransform &targetRectTransform,
569                                          int const_alpha)
570 {
571     if (const_alpha == 256) {
572         Blend_ARGB32_on_ARGB32_SourceAlpha sourceAlpha;
573         qt_transform_image(reinterpret_cast<quint32 *>(destPixels), dbpl,
574                            reinterpret_cast<const quint32 *>(srcPixels), sbpl,
575                            targetRect, sourceRect, clip, targetRectTransform, sourceAlpha);
576     } else {
577         Blend_ARGB32_on_ARGB32_SourceAndConstAlpha constAlpha(const_alpha);
578         qt_transform_image(reinterpret_cast<quint32 *>(destPixels), dbpl,
579                            reinterpret_cast<const quint32 *>(srcPixels), sbpl,
580                            targetRect, sourceRect, clip, targetRectTransform, constAlpha);
581     }
582 }
583 
584 SrcOverScaleFunc qScaleFunctions[QImage::NImageFormats][QImage::NImageFormats];
585 SrcOverBlendFunc qBlendFunctions[QImage::NImageFormats][QImage::NImageFormats];
586 SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::NImageFormats];
587 
qInitBlendFunctions()588 void qInitBlendFunctions()
589 {
590     qScaleFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_scale_image_rgb32_on_rgb32;
591     qScaleFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32;
592     qScaleFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_scale_image_rgb32_on_rgb32;
593     qScaleFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32;
594     qScaleFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_rgb16;
595     qScaleFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_scale_image_rgb16_on_rgb16;
596 #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
597     qScaleFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_scale_image_rgb32_on_rgb32;
598     qScaleFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32;
599     qScaleFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_scale_image_rgb32_on_rgb32;
600     qScaleFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32;
601 #endif
602 
603     qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32;
604     qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32;
605     qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32;
606     qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32;
607     qBlendFunctions[QImage::Format_RGB16][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb16;
608     qBlendFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_rgb16;
609     qBlendFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_blend_rgb16_on_rgb16;
610 #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
611     qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32;
612     qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32;
613     qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32;
614     qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32;
615 #endif
616 
617     qTransformFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_transform_image_rgb32_on_rgb32;
618     qTransformFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_transform_image_argb32_on_argb32;
619     qTransformFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_transform_image_rgb32_on_rgb32;
620     qTransformFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_transform_image_argb32_on_argb32;
621     qTransformFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_transform_image_argb32_on_rgb16;
622     qTransformFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_transform_image_rgb16_on_rgb16;
623 #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
624     qTransformFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_transform_image_rgb32_on_rgb32;
625     qTransformFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_transform_image_argb32_on_argb32;
626     qTransformFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_transform_image_rgb32_on_rgb32;
627     qTransformFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_transform_image_argb32_on_argb32;
628 #endif
629 }
630 
631 QT_END_NAMESPACE
632