Absolute File Name: | /home/qt/qt5_coco/qt5/qtbase/src/gui/painting/qdrawhelper.cpp |
Source code | Switch to Preprocessed file |
Line | Source | Count | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | /**************************************************************************** | - | ||||||||||||
2 | ** | - | ||||||||||||
3 | ** Copyright (C) 2016 The Qt Company Ltd. | - | ||||||||||||
4 | ** Copyright (C) 2016 Intel Corporation. | - | ||||||||||||
5 | ** Contact: https://www.qt.io/licensing/ | - | ||||||||||||
6 | ** | - | ||||||||||||
7 | ** This file is part of the QtGui module of the Qt Toolkit. | - | ||||||||||||
8 | ** | - | ||||||||||||
9 | ** $QT_BEGIN_LICENSE:LGPL$ | - | ||||||||||||
10 | ** Commercial License Usage | - | ||||||||||||
11 | ** Licensees holding valid commercial Qt licenses may use this file in | - | ||||||||||||
12 | ** accordance with the commercial license agreement provided with the | - | ||||||||||||
13 | ** Software or, alternatively, in accordance with the terms contained in | - | ||||||||||||
14 | ** a written agreement between you and The Qt Company. For licensing terms | - | ||||||||||||
15 | ** and conditions see https://www.qt.io/terms-conditions. For further | - | ||||||||||||
16 | ** information use the contact form at https://www.qt.io/contact-us. | - | ||||||||||||
17 | ** | - | ||||||||||||
18 | ** GNU Lesser General Public License Usage | - | ||||||||||||
19 | ** Alternatively, this file may be used under the terms of the GNU Lesser | - | ||||||||||||
20 | ** General Public License version 3 as published by the Free Software | - | ||||||||||||
21 | ** Foundation and appearing in the file LICENSE.LGPL3 included in the | - | ||||||||||||
22 | ** packaging of this file. Please review the following information to | - | ||||||||||||
23 | ** ensure the GNU Lesser General Public License version 3 requirements | - | ||||||||||||
24 | ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. | - | ||||||||||||
25 | ** | - | ||||||||||||
26 | ** GNU General Public License Usage | - | ||||||||||||
27 | ** Alternatively, this file may be used under the terms of the GNU | - | ||||||||||||
28 | ** General Public License version 2.0 or (at your option) the GNU General | - | ||||||||||||
29 | ** Public license version 3 or any later version approved by the KDE Free | - | ||||||||||||
30 | ** Qt Foundation. The licenses are as published by the Free Software | - | ||||||||||||
31 | ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 | - | ||||||||||||
32 | ** included in the packaging of this file. Please review the following | - | ||||||||||||
33 | ** information to ensure the GNU General Public License requirements will | - | ||||||||||||
34 | ** be met: https://www.gnu.org/licenses/gpl-2.0.html and | - | ||||||||||||
35 | ** https://www.gnu.org/licenses/gpl-3.0.html. | - | ||||||||||||
36 | ** | - | ||||||||||||
37 | ** $QT_END_LICENSE$ | - | ||||||||||||
38 | ** | - | ||||||||||||
39 | ****************************************************************************/ | - | ||||||||||||
40 | - | |||||||||||||
41 | #include <qglobal.h> | - | ||||||||||||
42 | - | |||||||||||||
43 | #include <qstylehints.h> | - | ||||||||||||
44 | #include <qguiapplication.h> | - | ||||||||||||
45 | #include <qatomic.h> | - | ||||||||||||
46 | #include <private/qdrawhelper_p.h> | - | ||||||||||||
47 | #include <private/qpaintengine_raster_p.h> | - | ||||||||||||
48 | #include <private/qpainter_p.h> | - | ||||||||||||
49 | #include <private/qdrawhelper_x86_p.h> | - | ||||||||||||
50 | #include <private/qdrawingprimitive_sse2_p.h> | - | ||||||||||||
51 | #include <private/qdrawhelper_neon_p.h> | - | ||||||||||||
52 | #if defined(QT_COMPILER_SUPPORTS_MIPS_DSP) || defined(QT_COMPILER_SUPPORTS_MIPS_DSPR2) | - | ||||||||||||
53 | #include <private/qdrawhelper_mips_dsp_p.h> | - | ||||||||||||
54 | #endif | - | ||||||||||||
55 | #include <private/qguiapplication_p.h> | - | ||||||||||||
56 | #include <private/qrgba64_p.h> | - | ||||||||||||
57 | #include <qmath.h> | - | ||||||||||||
58 | - | |||||||||||||
59 | QT_BEGIN_NAMESPACE | - | ||||||||||||
60 | - | |||||||||||||
61 | #define MASK(src, a) src = BYTE_MUL(src, a) | - | ||||||||||||
62 | - | |||||||||||||
63 | /* | - | ||||||||||||
64 | constants and structures | - | ||||||||||||
65 | */ | - | ||||||||||||
66 | - | |||||||||||||
67 | enum { | - | ||||||||||||
68 | fixed_scale = 1 << 16, | - | ||||||||||||
69 | half_point = 1 << 15 | - | ||||||||||||
70 | }; | - | ||||||||||||
71 | - | |||||||||||||
72 | // must be multiple of 4 for easier SIMD implementations | - | ||||||||||||
73 | static const int buffer_size = 2048; | - | ||||||||||||
74 | - | |||||||||||||
75 | template<QImage::Format> Q_DECL_CONSTEXPR uint redWidth(); | - | ||||||||||||
76 | template<QImage::Format> Q_DECL_CONSTEXPR uint redShift(); | - | ||||||||||||
77 | template<QImage::Format> Q_DECL_CONSTEXPR uint greenWidth(); | - | ||||||||||||
78 | template<QImage::Format> Q_DECL_CONSTEXPR uint greenShift(); | - | ||||||||||||
79 | template<QImage::Format> Q_DECL_CONSTEXPR uint blueWidth(); | - | ||||||||||||
80 | template<QImage::Format> Q_DECL_CONSTEXPR uint blueShift(); | - | ||||||||||||
81 | template<QImage::Format> Q_DECL_CONSTEXPR uint alphaWidth(); | - | ||||||||||||
82 | template<QImage::Format> Q_DECL_CONSTEXPR uint alphaShift(); | - | ||||||||||||
83 | - | |||||||||||||
84 | template<> Q_DECL_CONSTEXPR uint redWidth<QImage::Format_RGB16>() { return 5; } | - | ||||||||||||
85 | template<> Q_DECL_CONSTEXPR uint redWidth<QImage::Format_RGB444>() { return 4; } | - | ||||||||||||
86 | template<> Q_DECL_CONSTEXPR uint redWidth<QImage::Format_RGB555>() { return 5; } | - | ||||||||||||
87 | template<> Q_DECL_CONSTEXPR uint redWidth<QImage::Format_RGB666>() { return 6; } | - | ||||||||||||
88 | template<> Q_DECL_CONSTEXPR uint redWidth<QImage::Format_RGB888>() { return 8; } | - | ||||||||||||
89 | template<> Q_DECL_CONSTEXPR uint redWidth<QImage::Format_ARGB4444_Premultiplied>() { return 4; } | - | ||||||||||||
90 | template<> Q_DECL_CONSTEXPR uint redWidth<QImage::Format_ARGB8555_Premultiplied>() { return 5; } | - | ||||||||||||
91 | template<> Q_DECL_CONSTEXPR uint redWidth<QImage::Format_ARGB8565_Premultiplied>() { return 5; } | - | ||||||||||||
92 | template<> Q_DECL_CONSTEXPR uint redWidth<QImage::Format_ARGB6666_Premultiplied>() { return 6; } | - | ||||||||||||
93 | template<> Q_DECL_CONSTEXPR uint redShift<QImage::Format_RGB16>() { return 11; } | - | ||||||||||||
94 | template<> Q_DECL_CONSTEXPR uint redShift<QImage::Format_RGB444>() { return 8; } | - | ||||||||||||
95 | template<> Q_DECL_CONSTEXPR uint redShift<QImage::Format_RGB555>() { return 10; } | - | ||||||||||||
96 | template<> Q_DECL_CONSTEXPR uint redShift<QImage::Format_RGB666>() { return 12; } | - | ||||||||||||
97 | template<> Q_DECL_CONSTEXPR uint redShift<QImage::Format_RGB888>() { return 16; } | - | ||||||||||||
98 | template<> Q_DECL_CONSTEXPR uint redShift<QImage::Format_ARGB4444_Premultiplied>() { return 8; } | - | ||||||||||||
99 | template<> Q_DECL_CONSTEXPR uint redShift<QImage::Format_ARGB8555_Premultiplied>() { return 18; } | - | ||||||||||||
100 | template<> Q_DECL_CONSTEXPR uint redShift<QImage::Format_ARGB8565_Premultiplied>() { return 19; } | - | ||||||||||||
101 | template<> Q_DECL_CONSTEXPR uint redShift<QImage::Format_ARGB6666_Premultiplied>() { return 12; } | - | ||||||||||||
102 | template<> Q_DECL_CONSTEXPR uint greenWidth<QImage::Format_RGB16>() { return 6; } | - | ||||||||||||
103 | template<> Q_DECL_CONSTEXPR uint greenWidth<QImage::Format_RGB444>() { return 4; } | - | ||||||||||||
104 | template<> Q_DECL_CONSTEXPR uint greenWidth<QImage::Format_RGB555>() { return 5; } | - | ||||||||||||
105 | template<> Q_DECL_CONSTEXPR uint greenWidth<QImage::Format_RGB666>() { return 6; } | - | ||||||||||||
106 | template<> Q_DECL_CONSTEXPR uint greenWidth<QImage::Format_RGB888>() { return 8; } | - | ||||||||||||
107 | template<> Q_DECL_CONSTEXPR uint greenWidth<QImage::Format_ARGB4444_Premultiplied>() { return 4; } | - | ||||||||||||
108 | template<> Q_DECL_CONSTEXPR uint greenWidth<QImage::Format_ARGB8555_Premultiplied>() { return 5; } | - | ||||||||||||
109 | template<> Q_DECL_CONSTEXPR uint greenWidth<QImage::Format_ARGB8565_Premultiplied>() { return 6; } | - | ||||||||||||
110 | template<> Q_DECL_CONSTEXPR uint greenWidth<QImage::Format_ARGB6666_Premultiplied>() { return 6; } | - | ||||||||||||
111 | template<> Q_DECL_CONSTEXPR uint greenShift<QImage::Format_RGB16>() { return 5; } | - | ||||||||||||
112 | template<> Q_DECL_CONSTEXPR uint greenShift<QImage::Format_RGB444>() { return 4; } | - | ||||||||||||
113 | template<> Q_DECL_CONSTEXPR uint greenShift<QImage::Format_RGB555>() { return 5; } | - | ||||||||||||
114 | template<> Q_DECL_CONSTEXPR uint greenShift<QImage::Format_RGB666>() { return 6; } | - | ||||||||||||
115 | template<> Q_DECL_CONSTEXPR uint greenShift<QImage::Format_RGB888>() { return 8; } | - | ||||||||||||
116 | template<> Q_DECL_CONSTEXPR uint greenShift<QImage::Format_ARGB4444_Premultiplied>() { return 4; } | - | ||||||||||||
117 | template<> Q_DECL_CONSTEXPR uint greenShift<QImage::Format_ARGB8555_Premultiplied>() { return 13; } | - | ||||||||||||
118 | template<> Q_DECL_CONSTEXPR uint greenShift<QImage::Format_ARGB8565_Premultiplied>() { return 13; } | - | ||||||||||||
119 | template<> Q_DECL_CONSTEXPR uint greenShift<QImage::Format_ARGB6666_Premultiplied>() { return 6; } | - | ||||||||||||
120 | template<> Q_DECL_CONSTEXPR uint blueWidth<QImage::Format_RGB16>() { return 5; } | - | ||||||||||||
121 | template<> Q_DECL_CONSTEXPR uint blueWidth<QImage::Format_RGB444>() { return 4; } | - | ||||||||||||
122 | template<> Q_DECL_CONSTEXPR uint blueWidth<QImage::Format_RGB555>() { return 5; } | - | ||||||||||||
123 | template<> Q_DECL_CONSTEXPR uint blueWidth<QImage::Format_RGB666>() { return 6; } | - | ||||||||||||
124 | template<> Q_DECL_CONSTEXPR uint blueWidth<QImage::Format_RGB888>() { return 8; } | - | ||||||||||||
125 | template<> Q_DECL_CONSTEXPR uint blueWidth<QImage::Format_ARGB4444_Premultiplied>() { return 4; } | - | ||||||||||||
126 | template<> Q_DECL_CONSTEXPR uint blueWidth<QImage::Format_ARGB8555_Premultiplied>() { return 5; } | - | ||||||||||||
127 | template<> Q_DECL_CONSTEXPR uint blueWidth<QImage::Format_ARGB8565_Premultiplied>() { return 5; } | - | ||||||||||||
128 | template<> Q_DECL_CONSTEXPR uint blueWidth<QImage::Format_ARGB6666_Premultiplied>() { return 6; } | - | ||||||||||||
129 | template<> Q_DECL_CONSTEXPR uint blueShift<QImage::Format_RGB16>() { return 0; } | - | ||||||||||||
130 | template<> Q_DECL_CONSTEXPR uint blueShift<QImage::Format_RGB444>() { return 0; } | - | ||||||||||||
131 | template<> Q_DECL_CONSTEXPR uint blueShift<QImage::Format_RGB555>() { return 0; } | - | ||||||||||||
132 | template<> Q_DECL_CONSTEXPR uint blueShift<QImage::Format_RGB666>() { return 0; } | - | ||||||||||||
133 | template<> Q_DECL_CONSTEXPR uint blueShift<QImage::Format_RGB888>() { return 0; } | - | ||||||||||||
134 | template<> Q_DECL_CONSTEXPR uint blueShift<QImage::Format_ARGB4444_Premultiplied>() { return 0; } | - | ||||||||||||
135 | template<> Q_DECL_CONSTEXPR uint blueShift<QImage::Format_ARGB8555_Premultiplied>() { return 8; } | - | ||||||||||||
136 | template<> Q_DECL_CONSTEXPR uint blueShift<QImage::Format_ARGB8565_Premultiplied>() { return 8; } | - | ||||||||||||
137 | template<> Q_DECL_CONSTEXPR uint blueShift<QImage::Format_ARGB6666_Premultiplied>() { return 0; } | - | ||||||||||||
138 | template<> Q_DECL_CONSTEXPR uint alphaWidth<QImage::Format_RGB16>() { return 0; } | - | ||||||||||||
139 | template<> Q_DECL_CONSTEXPR uint alphaWidth<QImage::Format_RGB444>() { return 0; } | - | ||||||||||||
140 | template<> Q_DECL_CONSTEXPR uint alphaWidth<QImage::Format_RGB555>() { return 0; } | - | ||||||||||||
141 | template<> Q_DECL_CONSTEXPR uint alphaWidth<QImage::Format_RGB666>() { return 0; } | - | ||||||||||||
142 | template<> Q_DECL_CONSTEXPR uint alphaWidth<QImage::Format_RGB888>() { return 0; } | - | ||||||||||||
143 | template<> Q_DECL_CONSTEXPR uint alphaWidth<QImage::Format_ARGB4444_Premultiplied>() { return 4; } | - | ||||||||||||
144 | template<> Q_DECL_CONSTEXPR uint alphaWidth<QImage::Format_ARGB8555_Premultiplied>() { return 8; } | - | ||||||||||||
145 | template<> Q_DECL_CONSTEXPR uint alphaWidth<QImage::Format_ARGB8565_Premultiplied>() { return 8; } | - | ||||||||||||
146 | template<> Q_DECL_CONSTEXPR uint alphaWidth<QImage::Format_ARGB6666_Premultiplied>() { return 6; } | - | ||||||||||||
147 | template<> Q_DECL_CONSTEXPR uint alphaShift<QImage::Format_RGB16>() { return 0; } | - | ||||||||||||
148 | template<> Q_DECL_CONSTEXPR uint alphaShift<QImage::Format_RGB444>() { return 0; } | - | ||||||||||||
149 | template<> Q_DECL_CONSTEXPR uint alphaShift<QImage::Format_RGB555>() { return 0; } | - | ||||||||||||
150 | template<> Q_DECL_CONSTEXPR uint alphaShift<QImage::Format_RGB666>() { return 0; } | - | ||||||||||||
151 | template<> Q_DECL_CONSTEXPR uint alphaShift<QImage::Format_RGB888>() { return 0; } | - | ||||||||||||
152 | template<> Q_DECL_CONSTEXPR uint alphaShift<QImage::Format_ARGB4444_Premultiplied>() { return 12; } | - | ||||||||||||
153 | template<> Q_DECL_CONSTEXPR uint alphaShift<QImage::Format_ARGB8555_Premultiplied>() { return 0; } | - | ||||||||||||
154 | template<> Q_DECL_CONSTEXPR uint alphaShift<QImage::Format_ARGB8565_Premultiplied>() { return 0; } | - | ||||||||||||
155 | template<> Q_DECL_CONSTEXPR uint alphaShift<QImage::Format_ARGB6666_Premultiplied>() { return 18; } | - | ||||||||||||
156 | - | |||||||||||||
157 | template<QImage::Format> Q_DECL_CONSTEXPR QPixelLayout::BPP bitsPerPixel(); | - | ||||||||||||
158 | template<> Q_DECL_CONSTEXPR QPixelLayout::BPP bitsPerPixel<QImage::Format_RGB16>() { return QPixelLayout::BPP16; } | - | ||||||||||||
159 | template<> Q_DECL_CONSTEXPR QPixelLayout::BPP bitsPerPixel<QImage::Format_RGB444>() { return QPixelLayout::BPP16; } | - | ||||||||||||
160 | template<> Q_DECL_CONSTEXPR QPixelLayout::BPP bitsPerPixel<QImage::Format_RGB555>() { return QPixelLayout::BPP16; } | - | ||||||||||||
161 | template<> Q_DECL_CONSTEXPR QPixelLayout::BPP bitsPerPixel<QImage::Format_RGB666>() { return QPixelLayout::BPP24; } | - | ||||||||||||
162 | template<> Q_DECL_CONSTEXPR QPixelLayout::BPP bitsPerPixel<QImage::Format_RGB888>() { return QPixelLayout::BPP24; } | - | ||||||||||||
163 | template<> Q_DECL_CONSTEXPR QPixelLayout::BPP bitsPerPixel<QImage::Format_ARGB4444_Premultiplied>() { return QPixelLayout::BPP16; } | - | ||||||||||||
164 | template<> Q_DECL_CONSTEXPR QPixelLayout::BPP bitsPerPixel<QImage::Format_ARGB8555_Premultiplied>() { return QPixelLayout::BPP24; } | - | ||||||||||||
165 | template<> Q_DECL_CONSTEXPR QPixelLayout::BPP bitsPerPixel<QImage::Format_ARGB8565_Premultiplied>() { return QPixelLayout::BPP24; } | - | ||||||||||||
166 | template<> Q_DECL_CONSTEXPR QPixelLayout::BPP bitsPerPixel<QImage::Format_ARGB6666_Premultiplied>() { return QPixelLayout::BPP24; } | - | ||||||||||||
167 | - | |||||||||||||
168 | - | |||||||||||||
169 | template<QImage::Format Format> | - | ||||||||||||
170 | static const uint *QT_FASTCALL convertToRGB32(uint *buffer, const uint *src, int count, | - | ||||||||||||
171 | const QPixelLayout *, const QRgb *) | - | ||||||||||||
172 | { | - | ||||||||||||
173 | Q_CONSTEXPR uint redMask = ((1 << redWidth<Format>()) - 1); | - | ||||||||||||
174 | Q_CONSTEXPR uint greenMask = ((1 << greenWidth<Format>()) - 1); | - | ||||||||||||
175 | Q_CONSTEXPR uint blueMask = ((1 << blueWidth<Format>()) - 1); | - | ||||||||||||
176 | - | |||||||||||||
177 | Q_CONSTEXPR uchar redLeftShift = 8 - redWidth<Format>(); | - | ||||||||||||
178 | Q_CONSTEXPR uchar greenLeftShift = 8 - greenWidth<Format>(); | - | ||||||||||||
179 | Q_CONSTEXPR uchar blueLeftShift = 8 - blueWidth<Format>(); | - | ||||||||||||
180 | - | |||||||||||||
181 | Q_CONSTEXPR uchar redRightShift = 2 * redWidth<Format>() - 8; | - | ||||||||||||
182 | Q_CONSTEXPR uchar greenRightShift = 2 * greenWidth<Format>() - 8; | - | ||||||||||||
183 | Q_CONSTEXPR uchar blueRightShift = 2 * blueWidth<Format>() - 8; | - | ||||||||||||
184 | - | |||||||||||||
185 | for (int i = 0; i < count; ++i) {
| 0 | ||||||||||||
186 | uint red = (src[i] >> redShift<Format>()) & redMask; | - | ||||||||||||
187 | uint green = (src[i] >> greenShift<Format>()) & greenMask; | - | ||||||||||||
188 | uint blue = (src[i] >> blueShift<Format>()) & blueMask; | - | ||||||||||||
189 | - | |||||||||||||
190 | red = ((red << redLeftShift) | (red >> redRightShift)) << 16; | - | ||||||||||||
191 | green = ((green << greenLeftShift) | (green >> greenRightShift)) << 8; | - | ||||||||||||
192 | blue = (blue << blueLeftShift) | (blue >> blueRightShift); | - | ||||||||||||
193 | buffer[i] = 0xff000000 | red | green | blue; | - | ||||||||||||
194 | } never executed: end of block | 0 | ||||||||||||
195 | - | |||||||||||||
196 | return buffer; never executed: return buffer; | 0 | ||||||||||||
197 | } | - | ||||||||||||
198 | - | |||||||||||||
199 | template<QImage::Format Format> | - | ||||||||||||
200 | static const QRgba64 *QT_FASTCALL convertToRGB64(QRgba64 *buffer, const uint *src, int count, | - | ||||||||||||
201 | const QPixelLayout *, const QRgb *) | - | ||||||||||||
202 | { | - | ||||||||||||
203 | Q_CONSTEXPR uint redMask = ((1 << redWidth<Format>()) - 1); | - | ||||||||||||
204 | Q_CONSTEXPR uint greenMask = ((1 << greenWidth<Format>()) - 1); | - | ||||||||||||
205 | Q_CONSTEXPR uint blueMask = ((1 << blueWidth<Format>()) - 1); | - | ||||||||||||
206 | - | |||||||||||||
207 | Q_CONSTEXPR uchar redLeftShift = 8 - redWidth<Format>(); | - | ||||||||||||
208 | Q_CONSTEXPR uchar greenLeftShift = 8 - greenWidth<Format>(); | - | ||||||||||||
209 | Q_CONSTEXPR uchar blueLeftShift = 8 - blueWidth<Format>(); | - | ||||||||||||
210 | - | |||||||||||||
211 | Q_CONSTEXPR uchar redRightShift = 2 * redWidth<Format>() - 8; | - | ||||||||||||
212 | Q_CONSTEXPR uchar greenRightShift = 2 * greenWidth<Format>() - 8; | - | ||||||||||||
213 | Q_CONSTEXPR uchar blueRightShift = 2 * blueWidth<Format>() - 8; | - | ||||||||||||
214 | - | |||||||||||||
215 | for (int i = 0; i < count; ++i) {
| 0 | ||||||||||||
216 | uint red = (src[i] >> redShift<Format>()) & redMask; | - | ||||||||||||
217 | uint green = (src[i] >> greenShift<Format>()) & greenMask; | - | ||||||||||||
218 | uint blue = (src[i] >> blueShift<Format>()) & blueMask; | - | ||||||||||||
219 | - | |||||||||||||
220 | red = ((red << redLeftShift) | (red >> redRightShift)) << 16; | - | ||||||||||||
221 | green = ((green << greenLeftShift) | (green >> greenRightShift)) << 8; | - | ||||||||||||
222 | blue = (blue << blueLeftShift) | (blue >> blueRightShift); | - | ||||||||||||
223 | buffer[i] = QRgba64::fromRgba(red, green, blue, 255); | - | ||||||||||||
224 | } never executed: end of block | 0 | ||||||||||||
225 | - | |||||||||||||
226 | return buffer; never executed: return buffer; | 0 | ||||||||||||
227 | } | - | ||||||||||||
228 | - | |||||||||||||
229 | template<QImage::Format Format> | - | ||||||||||||
230 | static const uint *QT_FASTCALL convertARGBPMToARGB32PM(uint *buffer, const uint *src, int count, | - | ||||||||||||
231 | const QPixelLayout *, const QRgb *) | - | ||||||||||||
232 | { | - | ||||||||||||
233 | Q_CONSTEXPR uint alphaMask = ((1 << alphaWidth<Format>()) - 1); | - | ||||||||||||
234 | Q_CONSTEXPR uint redMask = ((1 << redWidth<Format>()) - 1); | - | ||||||||||||
235 | Q_CONSTEXPR uint greenMask = ((1 << greenWidth<Format>()) - 1); | - | ||||||||||||
236 | Q_CONSTEXPR uint blueMask = ((1 << blueWidth<Format>()) - 1); | - | ||||||||||||
237 | - | |||||||||||||
238 | Q_CONSTEXPR uchar alphaLeftShift = 8 - alphaWidth<Format>(); | - | ||||||||||||
239 | Q_CONSTEXPR uchar redLeftShift = 8 - redWidth<Format>(); | - | ||||||||||||
240 | Q_CONSTEXPR uchar greenLeftShift = 8 - greenWidth<Format>(); | - | ||||||||||||
241 | Q_CONSTEXPR uchar blueLeftShift = 8 - blueWidth<Format>(); | - | ||||||||||||
242 | - | |||||||||||||
243 | Q_CONSTEXPR uchar alphaRightShift = 2 * alphaWidth<Format>() - 8; | - | ||||||||||||
244 | Q_CONSTEXPR uchar redRightShift = 2 * redWidth<Format>() - 8; | - | ||||||||||||
245 | Q_CONSTEXPR uchar greenRightShift = 2 * greenWidth<Format>() - 8; | - | ||||||||||||
246 | Q_CONSTEXPR uchar blueRightShift = 2 * blueWidth<Format>() - 8; | - | ||||||||||||
247 | - | |||||||||||||
248 | Q_CONSTEXPR bool mustMin = (alphaWidth<Format>() != redWidth<Format>()) || | - | ||||||||||||
249 | (alphaWidth<Format>() != greenWidth<Format>()) || | - | ||||||||||||
250 | (alphaWidth<Format>() != blueWidth<Format>()); | - | ||||||||||||
251 | - | |||||||||||||
252 | if (mustMin) {
| 0 | ||||||||||||
253 | for (int i = 0; i < count; ++i) {
| 0 | ||||||||||||
254 | uint alpha = (src[i] >> alphaShift<Format>()) & alphaMask; | - | ||||||||||||
255 | uint red = (src[i] >> redShift<Format>()) & redMask; | - | ||||||||||||
256 | uint green = (src[i] >> greenShift<Format>()) & greenMask; | - | ||||||||||||
257 | uint blue = (src[i] >> blueShift<Format>()) & blueMask; | - | ||||||||||||
258 | - | |||||||||||||
259 | alpha = (alpha << alphaLeftShift) | (alpha >> alphaRightShift); | - | ||||||||||||
260 | red = qMin(alpha, (red << redLeftShift) | (red >> redRightShift)); | - | ||||||||||||
261 | green = qMin(alpha, (green << greenLeftShift) | (green >> greenRightShift)); | - | ||||||||||||
262 | blue = qMin(alpha, (blue << blueLeftShift) | (blue >> blueRightShift)); | - | ||||||||||||
263 | buffer[i] = (alpha << 24) | (red << 16) | (green << 8) | blue; | - | ||||||||||||
264 | } never executed: end of block | 0 | ||||||||||||
265 | } else { never executed: end of block | 0 | ||||||||||||
266 | for (int i = 0; i < count; ++i) {
| 0 | ||||||||||||
267 | uint alpha = (src[i] >> alphaShift<Format>()) & alphaMask; | - | ||||||||||||
268 | uint red = (src[i] >> redShift<Format>()) & redMask; | - | ||||||||||||
269 | uint green = (src[i] >> greenShift<Format>()) & greenMask; | - | ||||||||||||
270 | uint blue = (src[i] >> blueShift<Format>()) & blueMask; | - | ||||||||||||
271 | - | |||||||||||||
272 | alpha = ((alpha << alphaLeftShift) | (alpha >> alphaRightShift)) << 24; | - | ||||||||||||
273 | red = ((red << redLeftShift) | (red >> redRightShift)) << 16; | - | ||||||||||||
274 | green = ((green << greenLeftShift) | (green >> greenRightShift)) << 8; | - | ||||||||||||
275 | blue = (blue << blueLeftShift) | (blue >> blueRightShift); | - | ||||||||||||
276 | buffer[i] = alpha | red | green | blue; | - | ||||||||||||
277 | } never executed: end of block | 0 | ||||||||||||
278 | } never executed: end of block | 0 | ||||||||||||
279 | - | |||||||||||||
280 | return buffer; never executed: return buffer; | 0 | ||||||||||||
281 | } | - | ||||||||||||
282 | - | |||||||||||||
283 | template<QImage::Format Format> | - | ||||||||||||
284 | static const QRgba64 *QT_FASTCALL convertARGBPMToARGB64PM(QRgba64 *buffer, const uint *src, int count, | - | ||||||||||||
285 | const QPixelLayout *, const QRgb *) | - | ||||||||||||
286 | { | - | ||||||||||||
287 | Q_CONSTEXPR uint alphaMask = ((1 << alphaWidth<Format>()) - 1); | - | ||||||||||||
288 | Q_CONSTEXPR uint redMask = ((1 << redWidth<Format>()) - 1); | - | ||||||||||||
289 | Q_CONSTEXPR uint greenMask = ((1 << greenWidth<Format>()) - 1); | - | ||||||||||||
290 | Q_CONSTEXPR uint blueMask = ((1 << blueWidth<Format>()) - 1); | - | ||||||||||||
291 | - | |||||||||||||
292 | Q_CONSTEXPR uchar alphaLeftShift = 8 - alphaWidth<Format>(); | - | ||||||||||||
293 | Q_CONSTEXPR uchar redLeftShift = 8 - redWidth<Format>(); | - | ||||||||||||
294 | Q_CONSTEXPR uchar greenLeftShift = 8 - greenWidth<Format>(); | - | ||||||||||||
295 | Q_CONSTEXPR uchar blueLeftShift = 8 - blueWidth<Format>(); | - | ||||||||||||
296 | - | |||||||||||||
297 | Q_CONSTEXPR uchar alphaRightShift = 2 * alphaWidth<Format>() - 8; | - | ||||||||||||
298 | Q_CONSTEXPR uchar redRightShift = 2 * redWidth<Format>() - 8; | - | ||||||||||||
299 | Q_CONSTEXPR uchar greenRightShift = 2 * greenWidth<Format>() - 8; | - | ||||||||||||
300 | Q_CONSTEXPR uchar blueRightShift = 2 * blueWidth<Format>() - 8; | - | ||||||||||||
301 | - | |||||||||||||
302 | Q_CONSTEXPR bool mustMin = (alphaWidth<Format>() != redWidth<Format>()) || | - | ||||||||||||
303 | (alphaWidth<Format>() != greenWidth<Format>()) || | - | ||||||||||||
304 | (alphaWidth<Format>() != blueWidth<Format>()); | - | ||||||||||||
305 | - | |||||||||||||
306 | if (mustMin) {
| 0 | ||||||||||||
307 | for (int i = 0; i < count; ++i) {
| 0 | ||||||||||||
308 | uint alpha = (src[i] >> alphaShift<Format>()) & alphaMask; | - | ||||||||||||
309 | uint red = (src[i] >> redShift<Format>()) & redMask; | - | ||||||||||||
310 | uint green = (src[i] >> greenShift<Format>()) & greenMask; | - | ||||||||||||
311 | uint blue = (src[i] >> blueShift<Format>()) & blueMask; | - | ||||||||||||
312 | - | |||||||||||||
313 | alpha = (alpha << alphaLeftShift) | (alpha >> alphaRightShift); | - | ||||||||||||
314 | red = qMin(alpha, (red << redLeftShift) | (red >> redRightShift)); | - | ||||||||||||
315 | green = qMin(alpha, (green << greenLeftShift) | (green >> greenRightShift)); | - | ||||||||||||
316 | blue = qMin(alpha, (blue << blueLeftShift) | (blue >> blueRightShift)); | - | ||||||||||||
317 | buffer[i] = QRgba64::fromRgba(red, green, blue, alpha); | - | ||||||||||||
318 | } never executed: end of block | 0 | ||||||||||||
319 | } else { never executed: end of block | 0 | ||||||||||||
320 | for (int i = 0; i < count; ++i) {
| 0 | ||||||||||||
321 | uint alpha = (src[i] >> alphaShift<Format>()) & alphaMask; | - | ||||||||||||
322 | uint red = (src[i] >> redShift<Format>()) & redMask; | - | ||||||||||||
323 | uint green = (src[i] >> greenShift<Format>()) & greenMask; | - | ||||||||||||
324 | uint blue = (src[i] >> blueShift<Format>()) & blueMask; | - | ||||||||||||
325 | - | |||||||||||||
326 | alpha = (alpha << alphaLeftShift) | (alpha >> alphaRightShift); | - | ||||||||||||
327 | red = (red << redLeftShift) | (red >> redRightShift); | - | ||||||||||||
328 | green = (green << greenLeftShift) | (green >> greenRightShift); | - | ||||||||||||
329 | blue = (blue << blueLeftShift) | (blue >> blueRightShift); | - | ||||||||||||
330 | buffer[i] = QRgba64::fromRgba(red, green, blue, alpha); | - | ||||||||||||
331 | } never executed: end of block | 0 | ||||||||||||
332 | } never executed: end of block | 0 | ||||||||||||
333 | - | |||||||||||||
334 | return buffer; never executed: return buffer; | 0 | ||||||||||||
335 | } | - | ||||||||||||
336 | - | |||||||||||||
337 | template<QImage::Format Format, bool fromRGB> | - | ||||||||||||
338 | static const uint *QT_FASTCALL convertRGBFromARGB32PM(uint *buffer, const uint *src, int count, | - | ||||||||||||
339 | const QPixelLayout *, const QRgb *) | - | ||||||||||||
340 | { | - | ||||||||||||
341 | Q_CONSTEXPR uint rMask = ((1 << redWidth<Format>()) - 1); | - | ||||||||||||
342 | Q_CONSTEXPR uint gMask = ((1 << greenWidth<Format>()) - 1); | - | ||||||||||||
343 | Q_CONSTEXPR uint bMask = ((1 << blueWidth<Format>()) - 1); | - | ||||||||||||
344 | - | |||||||||||||
345 | Q_CONSTEXPR uchar rRightShift = 24 - redWidth<Format>(); | - | ||||||||||||
346 | Q_CONSTEXPR uchar gRightShift = 16 - greenWidth<Format>(); | - | ||||||||||||
347 | Q_CONSTEXPR uchar bRightShift = 8 - blueWidth<Format>(); | - | ||||||||||||
348 | - | |||||||||||||
349 | for (int i = 0; i < count; ++i) {
| 0 | ||||||||||||
350 | const uint c = fromRGB ? src[i] : qUnpremultiply(src[i]); | - | ||||||||||||
351 | const uint r = ((c >> rRightShift) & rMask) << redShift<Format>(); | - | ||||||||||||
352 | const uint g = ((c >> gRightShift) & gMask) << greenShift<Format>(); | - | ||||||||||||
353 | const uint b = ((c >> bRightShift) & bMask) << blueShift<Format>(); | - | ||||||||||||
354 | buffer[i] = r | g | b; | - | ||||||||||||
355 | } never executed: end of block | 0 | ||||||||||||
356 | return buffer; never executed: return buffer; | 0 | ||||||||||||
357 | } | - | ||||||||||||
358 | - | |||||||||||||
359 | template<QImage::Format Format, bool fromRGB> | - | ||||||||||||
360 | static const uint *QT_FASTCALL convertARGBPMFromARGB32PM(uint *buffer, const uint *src, int count, | - | ||||||||||||
361 | const QPixelLayout *, const QRgb *) | - | ||||||||||||
362 | { | - | ||||||||||||
363 | Q_CONSTEXPR uint aMask = ((1 << alphaWidth<Format>()) - 1); | - | ||||||||||||
364 | Q_CONSTEXPR uint rMask = ((1 << redWidth<Format>()) - 1); | - | ||||||||||||
365 | Q_CONSTEXPR uint gMask = ((1 << greenWidth<Format>()) - 1); | - | ||||||||||||
366 | Q_CONSTEXPR uint bMask = ((1 << blueWidth<Format>()) - 1); | - | ||||||||||||
367 | - | |||||||||||||
368 | Q_CONSTEXPR uchar aRightShift = 32 - alphaWidth<Format>(); | - | ||||||||||||
369 | Q_CONSTEXPR uchar rRightShift = 24 - redWidth<Format>(); | - | ||||||||||||
370 | Q_CONSTEXPR uchar gRightShift = 16 - greenWidth<Format>(); | - | ||||||||||||
371 | Q_CONSTEXPR uchar bRightShift = 8 - blueWidth<Format>(); | - | ||||||||||||
372 | - | |||||||||||||
373 | Q_CONSTEXPR uint aOpaque = (0xff & aMask) << alphaShift<Format>(); | - | ||||||||||||
374 | for (int i = 0; i < count; ++i) {
| 0 | ||||||||||||
375 | const uint c = src[i]; | - | ||||||||||||
376 | const uint a = fromRGB ? aOpaque : (((c >> aRightShift) & aMask) << alphaShift<Format>()); | - | ||||||||||||
377 | const uint r = ((c >> rRightShift) & rMask) << redShift<Format>(); | - | ||||||||||||
378 | const uint g = ((c >> gRightShift) & gMask) << greenShift<Format>(); | - | ||||||||||||
379 | const uint b = ((c >> bRightShift) & bMask) << blueShift<Format>(); | - | ||||||||||||
380 | buffer[i] = a | r | g | b; | - | ||||||||||||
381 | } never executed: end of block | 0 | ||||||||||||
382 | return buffer; never executed: return buffer; | 0 | ||||||||||||
383 | } | - | ||||||||||||
384 | - | |||||||||||||
385 | #ifdef Q_COMPILER_CONSTEXPR | - | ||||||||||||
386 | - | |||||||||||||
387 | template<QImage::Format Format> Q_DECL_CONSTEXPR static inline QPixelLayout pixelLayoutRGB() | - | ||||||||||||
388 | { | - | ||||||||||||
389 | return QPixelLayout{ | - | ||||||||||||
390 | uchar(redWidth<Format>()), uchar(redShift<Format>()), | - | ||||||||||||
391 | uchar(greenWidth<Format>()), uchar(greenShift<Format>()), | - | ||||||||||||
392 | uchar(blueWidth<Format>()), uchar(blueShift<Format>()), | - | ||||||||||||
393 | 0, 0, | - | ||||||||||||
394 | false, bitsPerPixel<Format>(), | - | ||||||||||||
395 | convertToRGB32<Format>, | - | ||||||||||||
396 | convertRGBFromARGB32PM<Format, false>, | - | ||||||||||||
397 | convertRGBFromARGB32PM<Format, true>, | - | ||||||||||||
398 | convertToRGB64<Format> | - | ||||||||||||
399 | }; | - | ||||||||||||
400 | } | - | ||||||||||||
401 | - | |||||||||||||
402 | template<QImage::Format Format> Q_DECL_CONSTEXPR static inline QPixelLayout pixelLayoutARGBPM() | - | ||||||||||||
403 | { | - | ||||||||||||
404 | return QPixelLayout{ | - | ||||||||||||
405 | uchar(redWidth<Format>()), uchar(redShift<Format>()), | - | ||||||||||||
406 | uchar(greenWidth<Format>()), uchar(greenShift<Format>()), | - | ||||||||||||
407 | uchar(blueWidth<Format>()), uchar(blueShift<Format>()), | - | ||||||||||||
408 | uchar(alphaWidth<Format>()), uchar(alphaShift<Format>()), | - | ||||||||||||
409 | true, bitsPerPixel<Format>(), | - | ||||||||||||
410 | convertARGBPMToARGB32PM<Format>, | - | ||||||||||||
411 | convertARGBPMFromARGB32PM<Format, false>, | - | ||||||||||||
412 | convertARGBPMFromARGB32PM<Format, true>, | - | ||||||||||||
413 | convertARGBPMToARGB64PM<Format> | - | ||||||||||||
414 | }; | - | ||||||||||||
415 | } | - | ||||||||||||
416 | - | |||||||||||||
417 | #endif | - | ||||||||||||
418 | - | |||||||||||||
419 | // To convert in place, let 'dest' and 'src' be the same. | - | ||||||||||||
420 | static const uint *QT_FASTCALL convertIndexedToARGB32PM(uint *buffer, const uint *src, int count, | - | ||||||||||||
421 | const QPixelLayout *, const QRgb *clut) | - | ||||||||||||
422 | { | - | ||||||||||||
423 | for (int i = 0; i < count; ++i)
| 0 | ||||||||||||
424 | buffer[i] = qPremultiply(clut[src[i]]); never executed: buffer[i] = qPremultiply(clut[src[i]]); | 0 | ||||||||||||
425 | return buffer; never executed: return buffer; | 0 | ||||||||||||
426 | } | - | ||||||||||||
427 | - | |||||||||||||
428 | static const QRgba64 *QT_FASTCALL convertIndexedToARGB64PM(QRgba64 *buffer, const uint *src, int count, | - | ||||||||||||
429 | const QPixelLayout *, const QRgb *clut) | - | ||||||||||||
430 | { | - | ||||||||||||
431 | for (int i = 0; i < count; ++i)
| 0 | ||||||||||||
432 | buffer[i] = QRgba64::fromArgb32(clut[src[i]]).premultiplied(); never executed: buffer[i] = QRgba64::fromArgb32(clut[src[i]]).premultiplied(); | 0 | ||||||||||||
433 | return buffer; never executed: return buffer; | 0 | ||||||||||||
434 | } | - | ||||||||||||
435 | - | |||||||||||||
436 | static const uint *QT_FASTCALL convertPassThrough(uint *, const uint *src, int, | - | ||||||||||||
437 | const QPixelLayout *, const QRgb *) | - | ||||||||||||
438 | { | - | ||||||||||||
439 | return src; never executed: return src; | 0 | ||||||||||||
440 | } | - | ||||||||||||
441 | - | |||||||||||||
442 | static const uint *QT_FASTCALL convertARGB32ToARGB32PM(uint *buffer, const uint *src, int count, | - | ||||||||||||
443 | const QPixelLayout *, const QRgb *) | - | ||||||||||||
444 | { | - | ||||||||||||
445 | return qt_convertARGB32ToARGB32PM(buffer, src, count); never executed: return qt_convertARGB32ToARGB32PM(buffer, src, count); | 0 | ||||||||||||
446 | } | - | ||||||||||||
447 | - | |||||||||||||
448 | static const uint *QT_FASTCALL convertRGBA8888PMToARGB32PM(uint *buffer, const uint *src, int count, | - | ||||||||||||
449 | const QPixelLayout *, const QRgb *) | - | ||||||||||||
450 | { | - | ||||||||||||
451 | for (int i = 0; i < count; ++i)
| 0 | ||||||||||||
452 | buffer[i] = RGBA2ARGB(src[i]); never executed: buffer[i] = RGBA2ARGB(src[i]); | 0 | ||||||||||||
453 | return buffer; never executed: return buffer; | 0 | ||||||||||||
454 | } | - | ||||||||||||
455 | - | |||||||||||||
456 | static const uint *QT_FASTCALL convertRGBA8888ToARGB32PM(uint *buffer, const uint *src, int count, | - | ||||||||||||
457 | const QPixelLayout *, const QRgb *) | - | ||||||||||||
458 | { | - | ||||||||||||
459 | return qt_convertRGBA8888ToARGB32PM(buffer, src, count); never executed: return qt_convertRGBA8888ToARGB32PM(buffer, src, count); | 0 | ||||||||||||
460 | } | - | ||||||||||||
461 | - | |||||||||||||
462 | static const uint *QT_FASTCALL convertAlpha8ToRGB32(uint *buffer, const uint *src, int count, | - | ||||||||||||
463 | const QPixelLayout *, const QRgb *) | - | ||||||||||||
464 | { | - | ||||||||||||
465 | for (int i = 0; i < count; ++i)
| 0 | ||||||||||||
466 | buffer[i] = qRgba(0, 0, 0, src[i]); never executed: buffer[i] = qRgba(0, 0, 0, src[i]); | 0 | ||||||||||||
467 | return buffer; never executed: return buffer; | 0 | ||||||||||||
468 | } | - | ||||||||||||
469 | - | |||||||||||||
470 | static const uint *QT_FASTCALL convertGrayscale8ToRGB32(uint *buffer, const uint *src, int count, | - | ||||||||||||
471 | const QPixelLayout *, const QRgb *) | - | ||||||||||||
472 | { | - | ||||||||||||
473 | for (int i = 0; i < count; ++i)
| 0 | ||||||||||||
474 | buffer[i] = qRgb(src[i], src[i], src[i]); never executed: buffer[i] = qRgb(src[i], src[i], src[i]); | 0 | ||||||||||||
475 | return buffer; never executed: return buffer; | 0 | ||||||||||||
476 | } | - | ||||||||||||
477 | - | |||||||||||||
478 | static const QRgba64 *QT_FASTCALL convertAlpha8ToRGB64(QRgba64 *buffer, const uint *src, int count, | - | ||||||||||||
479 | const QPixelLayout *, const QRgb *) | - | ||||||||||||
480 | { | - | ||||||||||||
481 | for (int i = 0; i < count; ++i)
| 0 | ||||||||||||
482 | buffer[i] = QRgba64::fromRgba(0, 0, 0, src[i]); never executed: buffer[i] = QRgba64::fromRgba(0, 0, 0, src[i]); | 0 | ||||||||||||
483 | return buffer; never executed: return buffer; | 0 | ||||||||||||
484 | } | - | ||||||||||||
485 | - | |||||||||||||
486 | static const QRgba64 *QT_FASTCALL convertGrayscale8ToRGB64(QRgba64 *buffer, const uint *src, int count, | - | ||||||||||||
487 | const QPixelLayout *, const QRgb *) | - | ||||||||||||
488 | { | - | ||||||||||||
489 | for (int i = 0; i < count; ++i)
| 0 | ||||||||||||
490 | buffer[i] = QRgba64::fromRgba(src[i], src[i], src[i], 255); never executed: buffer[i] = QRgba64::fromRgba(src[i], src[i], src[i], 255); | 0 | ||||||||||||
491 | return buffer; never executed: return buffer; | 0 | ||||||||||||
492 | } | - | ||||||||||||
493 | - | |||||||||||||
494 | static const uint *QT_FASTCALL convertARGB32FromARGB32PM(uint *buffer, const uint *src, int count, | - | ||||||||||||
495 | const QPixelLayout *, const QRgb *) | - | ||||||||||||
496 | { | - | ||||||||||||
497 | for (int i = 0; i < count; ++i)
| 0 | ||||||||||||
498 | buffer[i] = qUnpremultiply(src[i]); never executed: buffer[i] = qUnpremultiply(src[i]); | 0 | ||||||||||||
499 | return buffer; never executed: return buffer; | 0 | ||||||||||||
500 | } | - | ||||||||||||
501 | - | |||||||||||||
502 | static const uint *QT_FASTCALL convertRGBA8888PMFromARGB32PM(uint *buffer, const uint *src, int count, | - | ||||||||||||
503 | const QPixelLayout *, const QRgb *) | - | ||||||||||||
504 | { | - | ||||||||||||
505 | for (int i = 0; i < count; ++i)
| 0 | ||||||||||||
506 | buffer[i] = ARGB2RGBA(src[i]); never executed: buffer[i] = ARGB2RGBA(src[i]); | 0 | ||||||||||||
507 | return buffer; never executed: return buffer; | 0 | ||||||||||||
508 | } | - | ||||||||||||
509 | - | |||||||||||||
510 | #ifdef __SSE2__ | - | ||||||||||||
511 | template<bool RGBA, bool maskAlpha> | - | ||||||||||||
512 | static inline void qConvertARGB32PMToARGB64PM_sse2(QRgba64 *buffer, const uint *src, int count) | - | ||||||||||||
513 | { | - | ||||||||||||
514 | if (count <= 0)
| 0 | ||||||||||||
515 | return; never executed: return; | 0 | ||||||||||||
516 | - | |||||||||||||
517 | const __m128i amask = _mm_set1_epi32(0xff000000); | - | ||||||||||||
518 | int i = 0; | - | ||||||||||||
519 | for (; ((uintptr_t)buffer & 0xf) && i < count; ++i) {
| 0 | ||||||||||||
520 | uint s = *src++; | - | ||||||||||||
521 | if (RGBA)
| 0 | ||||||||||||
522 | s = RGBA2ARGB(s); never executed: s = RGBA2ARGB(s); | 0 | ||||||||||||
523 | *buffer++ = QRgba64::fromArgb32(s); | - | ||||||||||||
524 | } never executed: end of block | 0 | ||||||||||||
525 | for (; i < count-3; i += 4) {
| 0 | ||||||||||||
526 | __m128i vs = _mm_loadu_si128((const __m128i*)src); | - | ||||||||||||
527 | if (maskAlpha)
| 0 | ||||||||||||
528 | vs = _mm_or_si128(vs, amask); never executed: vs = _mm_or_si128(vs, amask); | 0 | ||||||||||||
529 | src += 4; | - | ||||||||||||
530 | __m128i v1 = _mm_unpacklo_epi8(vs, vs); | - | ||||||||||||
531 | __m128i v2 = _mm_unpackhi_epi8(vs, vs); | - | ||||||||||||
532 | if (!RGBA) {
| 0 | ||||||||||||
533 | v1 = _mm_shufflelo_epi16(v1, _MM_SHUFFLE(3, 0, 1, 2)); | - | ||||||||||||
534 | v2 = _mm_shufflelo_epi16(v2, _MM_SHUFFLE(3, 0, 1, 2)); | - | ||||||||||||
535 | v1 = _mm_shufflehi_epi16(v1, _MM_SHUFFLE(3, 0, 1, 2)); | - | ||||||||||||
536 | v2 = _mm_shufflehi_epi16(v2, _MM_SHUFFLE(3, 0, 1, 2)); | - | ||||||||||||
537 | } never executed: end of block | 0 | ||||||||||||
538 | _mm_store_si128((__m128i*)(buffer), v1); | - | ||||||||||||
539 | buffer += 2; | - | ||||||||||||
540 | _mm_store_si128((__m128i*)(buffer), v2); | - | ||||||||||||
541 | buffer += 2; | - | ||||||||||||
542 | } never executed: end of block | 0 | ||||||||||||
543 | - | |||||||||||||
544 | for (; i < count; ++i) {
| 0 | ||||||||||||
545 | uint s = *src++; | - | ||||||||||||
546 | if (RGBA)
| 0 | ||||||||||||
547 | s = RGBA2ARGB(s); never executed: s = RGBA2ARGB(s); | 0 | ||||||||||||
548 | *buffer++ = QRgba64::fromArgb32(s); | - | ||||||||||||
549 | } never executed: end of block | 0 | ||||||||||||
550 | } never executed: end of block | 0 | ||||||||||||
551 | #endif | - | ||||||||||||
552 | - | |||||||||||||
553 | static const QRgba64 *QT_FASTCALL convertRGB32ToRGB64(QRgba64 *buffer, const uint *src, int count, | - | ||||||||||||
554 | const QPixelLayout *, const QRgb *) | - | ||||||||||||
555 | { | - | ||||||||||||
556 | #ifdef __SSE2__ | - | ||||||||||||
557 | qConvertARGB32PMToARGB64PM_sse2<false, true>(buffer, src, count); | - | ||||||||||||
558 | #else | - | ||||||||||||
559 | for (int i = 0; i < count; ++i) | - | ||||||||||||
560 | buffer[i] = QRgba64::fromArgb32(0xff000000 | src[i]); | - | ||||||||||||
561 | #endif | - | ||||||||||||
562 | return buffer; never executed: return buffer; | 0 | ||||||||||||
563 | } | - | ||||||||||||
564 | - | |||||||||||||
565 | static const QRgba64 *QT_FASTCALL convertARGB32ToARGB64PM(QRgba64 *buffer, const uint *src, int count, | - | ||||||||||||
566 | const QPixelLayout *, const QRgb *) | - | ||||||||||||
567 | { | - | ||||||||||||
568 | #ifdef __SSE2__ | - | ||||||||||||
569 | qConvertARGB32PMToARGB64PM_sse2<false, false>(buffer, src, count); | - | ||||||||||||
570 | for (int i = 0; i < count; ++i)
| 0 | ||||||||||||
571 | buffer[i] = buffer[i].premultiplied(); never executed: buffer[i] = buffer[i].premultiplied(); | 0 | ||||||||||||
572 | #else | - | ||||||||||||
573 | for (int i = 0; i < count; ++i) | - | ||||||||||||
574 | buffer[i] = QRgba64::fromArgb32(src[i]).premultiplied(); | - | ||||||||||||
575 | #endif | - | ||||||||||||
576 | return buffer; never executed: return buffer; | 0 | ||||||||||||
577 | } | - | ||||||||||||
578 | - | |||||||||||||
579 | static const QRgba64 *QT_FASTCALL convertARGB32PMToARGB64PM(QRgba64 *buffer, const uint *src, int count, | - | ||||||||||||
580 | const QPixelLayout *, const QRgb *) | - | ||||||||||||
581 | { | - | ||||||||||||
582 | #ifdef __SSE2__ | - | ||||||||||||
583 | qConvertARGB32PMToARGB64PM_sse2<false, false>(buffer, src, count); | - | ||||||||||||
584 | #else | - | ||||||||||||
585 | for (int i = 0; i < count; ++i) | - | ||||||||||||
586 | buffer[i] = QRgba64::fromArgb32(src[i]); | - | ||||||||||||
587 | #endif | - | ||||||||||||
588 | return buffer; never executed: return buffer; | 0 | ||||||||||||
589 | } | - | ||||||||||||
590 | - | |||||||||||||
591 | static const QRgba64 *QT_FASTCALL convertRGBA8888ToARGB64PM(QRgba64 *buffer, const uint *src, int count, | - | ||||||||||||
592 | const QPixelLayout *, const QRgb *) | - | ||||||||||||
593 | { | - | ||||||||||||
594 | #ifdef __SSE2__ | - | ||||||||||||
595 | qConvertARGB32PMToARGB64PM_sse2<true, false>(buffer, src, count); | - | ||||||||||||
596 | for (int i = 0; i < count; ++i)
| 0 | ||||||||||||
597 | buffer[i] = buffer[i].premultiplied(); never executed: buffer[i] = buffer[i].premultiplied(); | 0 | ||||||||||||
598 | #else | - | ||||||||||||
599 | for (int i = 0; i < count; ++i) | - | ||||||||||||
600 | buffer[i] = QRgba64::fromArgb32(RGBA2ARGB(src[i])).premultiplied(); | - | ||||||||||||
601 | #endif | - | ||||||||||||
602 | return buffer; never executed: return buffer; | 0 | ||||||||||||
603 | } | - | ||||||||||||
604 | - | |||||||||||||
605 | static const QRgba64 *QT_FASTCALL convertRGBA8888PMToARGB64PM(QRgba64 *buffer, const uint *src, int count, | - | ||||||||||||
606 | const QPixelLayout *, const QRgb *) | - | ||||||||||||
607 | { | - | ||||||||||||
608 | #ifdef __SSE2__ | - | ||||||||||||
609 | qConvertARGB32PMToARGB64PM_sse2<true, false>(buffer, src, count); | - | ||||||||||||
610 | #else | - | ||||||||||||
611 | for (int i = 0; i < count; ++i) | - | ||||||||||||
612 | buffer[i] = QRgba64::fromArgb32(RGBA2ARGB(src[i])); | - | ||||||||||||
613 | #endif | - | ||||||||||||
614 | return buffer; never executed: return buffer; | 0 | ||||||||||||
615 | } | - | ||||||||||||
616 | - | |||||||||||||
617 | static const uint *QT_FASTCALL convertRGBA8888FromARGB32PM(uint *buffer, const uint *src, int count, | - | ||||||||||||
618 | const QPixelLayout *, const QRgb *) | - | ||||||||||||
619 | { | - | ||||||||||||
620 | for (int i = 0; i < count; ++i)
| 0 | ||||||||||||
621 | buffer[i] = ARGB2RGBA(qUnpremultiply(src[i])); never executed: buffer[i] = ARGB2RGBA(qUnpremultiply(src[i])); | 0 | ||||||||||||
622 | return buffer; never executed: return buffer; | 0 | ||||||||||||
623 | } | - | ||||||||||||
624 | - | |||||||||||||
625 | static const uint *QT_FASTCALL convertRGBXFromRGB32(uint *buffer, const uint *src, int count, | - | ||||||||||||
626 | const QPixelLayout *, const QRgb *) | - | ||||||||||||
627 | { | - | ||||||||||||
628 | for (int i = 0; i < count; ++i)
| 0 | ||||||||||||
629 | buffer[i] = ARGB2RGBA(0xff000000 | src[i]); never executed: buffer[i] = ARGB2RGBA(0xff000000 | src[i]); | 0 | ||||||||||||
630 | return buffer; never executed: return buffer; | 0 | ||||||||||||
631 | } | - | ||||||||||||
632 | - | |||||||||||||
633 | static const uint *QT_FASTCALL convertRGBXFromARGB32PM(uint *buffer, const uint *src, int count, | - | ||||||||||||
634 | const QPixelLayout *, const QRgb *) | - | ||||||||||||
635 | { | - | ||||||||||||
636 | for (int i = 0; i < count; ++i)
| 0 | ||||||||||||
637 | buffer[i] = ARGB2RGBA(0xff000000 | qUnpremultiply(src[i])); never executed: buffer[i] = ARGB2RGBA(0xff000000 | qUnpremultiply(src[i])); | 0 | ||||||||||||
638 | return buffer; never executed: return buffer; | 0 | ||||||||||||
639 | } | - | ||||||||||||
640 | - | |||||||||||||
641 | template<QtPixelOrder PixelOrder> | - | ||||||||||||
642 | static const uint *QT_FASTCALL convertA2RGB30PMToARGB32PM(uint *buffer, const uint *src, int count, | - | ||||||||||||
643 | const QPixelLayout *, const QRgb *) | - | ||||||||||||
644 | { | - | ||||||||||||
645 | for (int i = 0; i < count; ++i)
| 0 | ||||||||||||
646 | buffer[i] = qConvertA2rgb30ToArgb32<PixelOrder>(src[i]); never executed: buffer[i] = qConvertA2rgb30ToArgb32<PixelOrder>(src[i]); | 0 | ||||||||||||
647 | return buffer; never executed: return buffer; | 0 | ||||||||||||
648 | } | - | ||||||||||||
649 | - | |||||||||||||
650 | #ifdef __SSE2__ | - | ||||||||||||
651 | template<QtPixelOrder PixelOrder> | - | ||||||||||||
652 | static inline void qConvertA2RGB30PMToARGB64PM_sse2(QRgba64 *buffer, const uint *src, int count) | - | ||||||||||||
653 | { | - | ||||||||||||
654 | if (count <= 0)
| 0 | ||||||||||||
655 | return; never executed: return; | 0 | ||||||||||||
656 | - | |||||||||||||
657 | const __m128i rmask = _mm_set1_epi32(0x3ff00000); | - | ||||||||||||
658 | const __m128i gmask = _mm_set1_epi32(0x000ffc00); | - | ||||||||||||
659 | const __m128i bmask = _mm_set1_epi32(0x000003ff); | - | ||||||||||||
660 | const __m128i afactor = _mm_set1_epi16(0x5555); | - | ||||||||||||
661 | int i = 0; | - | ||||||||||||
662 | - | |||||||||||||
663 | for (; ((uintptr_t)buffer & 0xf) && i < count; ++i)
| 0 | ||||||||||||
664 | *buffer++ = qConvertA2rgb30ToRgb64<PixelOrder>(*src++); never executed: *buffer++ = qConvertA2rgb30ToRgb64<PixelOrder>(*src++); | 0 | ||||||||||||
665 | - | |||||||||||||
666 | for (; i < count-3; i += 4) {
| 0 | ||||||||||||
667 | __m128i vs = _mm_loadu_si128((const __m128i*)src); | - | ||||||||||||
668 | src += 4; | - | ||||||||||||
669 | __m128i va = _mm_srli_epi32(vs, 30); | - | ||||||||||||
670 | __m128i vr = _mm_and_si128(vs, rmask); | - | ||||||||||||
671 | __m128i vb = _mm_and_si128(vs, bmask); | - | ||||||||||||
672 | __m128i vg = _mm_and_si128(vs, gmask); | - | ||||||||||||
673 | va = _mm_mullo_epi16(va, afactor); | - | ||||||||||||
674 | vr = _mm_or_si128(_mm_srli_epi32(vr, 14), _mm_srli_epi32(vr, 24)); | - | ||||||||||||
675 | vg = _mm_or_si128(_mm_srli_epi32(vg, 4), _mm_srli_epi32(vg, 14)); | - | ||||||||||||
676 | vb = _mm_or_si128(_mm_slli_epi32(vb, 6), _mm_srli_epi32(vb, 4)); | - | ||||||||||||
677 | __m128i vrb; | - | ||||||||||||
678 | if (PixelOrder == PixelOrderRGB)
| 0 | ||||||||||||
679 | vrb = _mm_or_si128(vr, _mm_slli_si128(vb, 2)); never executed: vrb = _mm_or_si128(vr, ((__m128i)__builtin_ia32_pslldqi128 ((__m128i)(vb), (int)(2) * 8))); | 0 | ||||||||||||
680 | else | - | ||||||||||||
681 | vrb = _mm_or_si128(vb, _mm_slli_si128(vr, 2)); never executed: vrb = _mm_or_si128(vb, ((__m128i)__builtin_ia32_pslldqi128 ((__m128i)(vr), (int)(2) * 8))); | 0 | ||||||||||||
682 | __m128i vga = _mm_or_si128(vg, _mm_slli_si128(va, 2)); | - | ||||||||||||
683 | _mm_store_si128((__m128i*)(buffer), _mm_unpacklo_epi16(vrb, vga)); | - | ||||||||||||
684 | buffer += 2; | - | ||||||||||||
685 | _mm_store_si128((__m128i*)(buffer), _mm_unpackhi_epi16(vrb, vga)); | - | ||||||||||||
686 | buffer += 2; | - | ||||||||||||
687 | } never executed: end of block | 0 | ||||||||||||
688 | - | |||||||||||||
689 | for (; i < count; ++i)
| 0 | ||||||||||||
690 | *buffer++ = qConvertA2rgb30ToRgb64<PixelOrder>(*src++); never executed: *buffer++ = qConvertA2rgb30ToRgb64<PixelOrder>(*src++); | 0 | ||||||||||||
691 | } never executed: end of block | 0 | ||||||||||||
692 | #endif | - | ||||||||||||
693 | - | |||||||||||||
694 | template<QtPixelOrder PixelOrder> | - | ||||||||||||
695 | static const QRgba64 *QT_FASTCALL convertA2RGB30PMToARGB64PM(QRgba64 *buffer, const uint *src, int count, | - | ||||||||||||
696 | const QPixelLayout *, const QRgb *) | - | ||||||||||||
697 | { | - | ||||||||||||
698 | #ifdef __SSE2__ | - | ||||||||||||
699 | qConvertA2RGB30PMToARGB64PM_sse2<PixelOrder>(buffer, src, count); | - | ||||||||||||
700 | #else | - | ||||||||||||
701 | for (int i = 0; i < count; ++i) | - | ||||||||||||
702 | buffer[i] = qConvertA2rgb30ToRgb64<PixelOrder>(src[i]); | - | ||||||||||||
703 | #endif | - | ||||||||||||
704 | return buffer; never executed: return buffer; | 0 | ||||||||||||
705 | } | - | ||||||||||||
706 | - | |||||||||||||
707 | template<QtPixelOrder PixelOrder> | - | ||||||||||||
708 | static const uint *QT_FASTCALL convertA2RGB30PMFromARGB32PM(uint *buffer, const uint *src, int count, | - | ||||||||||||
709 | const QPixelLayout *, const QRgb *) | - | ||||||||||||
710 | { | - | ||||||||||||
711 | for (int i = 0; i < count; ++i)
| 0 | ||||||||||||
712 | buffer[i] = qConvertArgb32ToA2rgb30<PixelOrder>(src[i]); never executed: buffer[i] = qConvertArgb32ToA2rgb30<PixelOrder>(src[i]); | 0 | ||||||||||||
713 | return buffer; never executed: return buffer; | 0 | ||||||||||||
714 | } | - | ||||||||||||
715 | - | |||||||||||||
716 | template<QtPixelOrder PixelOrder> | - | ||||||||||||
717 | static const uint *QT_FASTCALL convertRGB30FromRGB32(uint *buffer, const uint *src, int count, | - | ||||||||||||
718 | const QPixelLayout *, const QRgb *) | - | ||||||||||||
719 | { | - | ||||||||||||
720 | for (int i = 0; i < count; ++i)
| 0 | ||||||||||||
721 | buffer[i] = qConvertRgb32ToRgb30<PixelOrder>(src[i]); never executed: buffer[i] = qConvertRgb32ToRgb30<PixelOrder>(src[i]); | 0 | ||||||||||||
722 | return buffer; never executed: return buffer; | 0 | ||||||||||||
723 | } | - | ||||||||||||
724 | - | |||||||||||||
725 | template<QtPixelOrder PixelOrder> | - | ||||||||||||
726 | static const uint *QT_FASTCALL convertRGB30FromARGB32PM(uint *buffer, const uint *src, int count, | - | ||||||||||||
727 | const QPixelLayout *, const QRgb *) | - | ||||||||||||
728 | { | - | ||||||||||||
729 | for (int i = 0; i < count; ++i)
| 0 | ||||||||||||
730 | buffer[i] = qConvertRgb32ToRgb30<PixelOrder>(qUnpremultiply(src[i])); never executed: buffer[i] = qConvertRgb32ToRgb30<PixelOrder>(qUnpremultiply(src[i])); | 0 | ||||||||||||
731 | return buffer; never executed: return buffer; | 0 | ||||||||||||
732 | } | - | ||||||||||||
733 | - | |||||||||||||
734 | static const uint *QT_FASTCALL convertAlpha8FromARGB32PM(uint *buffer, const uint *src, int count, | - | ||||||||||||
735 | const QPixelLayout *, const QRgb *) | - | ||||||||||||
736 | { | - | ||||||||||||
737 | for (int i = 0; i < count; ++i)
| 0 | ||||||||||||
738 | buffer[i] = qAlpha(src[i]); never executed: buffer[i] = qAlpha(src[i]); | 0 | ||||||||||||
739 | return buffer; never executed: return buffer; | 0 | ||||||||||||
740 | } | - | ||||||||||||
741 | - | |||||||||||||
742 | static const uint *QT_FASTCALL convertGrayscale8FromRGB32(uint *buffer, const uint *src, int count, | - | ||||||||||||
743 | const QPixelLayout *, const QRgb *) | - | ||||||||||||
744 | { | - | ||||||||||||
745 | for (int i = 0; i < count; ++i)
| 0 | ||||||||||||
746 | buffer[i] = qGray(src[i]); never executed: buffer[i] = qGray(src[i]); | 0 | ||||||||||||
747 | return buffer; never executed: return buffer; | 0 | ||||||||||||
748 | } | - | ||||||||||||
749 | - | |||||||||||||
750 | static const uint *QT_FASTCALL convertGrayscale8FromARGB32PM(uint *buffer, const uint *src, int count, | - | ||||||||||||
751 | const QPixelLayout *, const QRgb *) | - | ||||||||||||
752 | { | - | ||||||||||||
753 | for (int i = 0; i < count; ++i)
| 0 | ||||||||||||
754 | buffer[i] = qGray(qUnpremultiply(src[i])); never executed: buffer[i] = qGray(qUnpremultiply(src[i])); | 0 | ||||||||||||
755 | return buffer; never executed: return buffer; | 0 | ||||||||||||
756 | } | - | ||||||||||||
757 | - | |||||||||||||
758 | template <QPixelLayout::BPP bpp> static | - | ||||||||||||
759 | uint QT_FASTCALL fetchPixel(const uchar *src, int index); | - | ||||||||||||
760 | - | |||||||||||||
761 | template <> | - | ||||||||||||
762 | inline uint QT_FASTCALL fetchPixel<QPixelLayout::BPP1LSB>(const uchar *src, int index) | - | ||||||||||||
763 | { | - | ||||||||||||
764 | return (src[index >> 3] >> (index & 7)) & 1; never executed: return (src[index >> 3] >> (index & 7)) & 1; | 0 | ||||||||||||
765 | } | - | ||||||||||||
766 | - | |||||||||||||
767 | template <> | - | ||||||||||||
768 | inline uint QT_FASTCALL fetchPixel<QPixelLayout::BPP1MSB>(const uchar *src, int index) | - | ||||||||||||
769 | { | - | ||||||||||||
770 | return (src[index >> 3] >> (~index & 7)) & 1; never executed: return (src[index >> 3] >> (~index & 7)) & 1; | 0 | ||||||||||||
771 | } | - | ||||||||||||
772 | - | |||||||||||||
773 | template <> | - | ||||||||||||
774 | inline uint QT_FASTCALL fetchPixel<QPixelLayout::BPP8>(const uchar *src, int index) | - | ||||||||||||
775 | { | - | ||||||||||||
776 | return src[index]; never executed: return src[index]; | 0 | ||||||||||||
777 | } | - | ||||||||||||
778 | - | |||||||||||||
779 | template <> | - | ||||||||||||
780 | inline uint QT_FASTCALL fetchPixel<QPixelLayout::BPP16>(const uchar *src, int index) | - | ||||||||||||
781 | { | - | ||||||||||||
782 | return reinterpret_cast<const quint16 *>(src)[index]; never executed: return reinterpret_cast<const quint16 *>(src)[index]; | 0 | ||||||||||||
783 | } | - | ||||||||||||
784 | - | |||||||||||||
785 | template <> | - | ||||||||||||
786 | inline uint QT_FASTCALL fetchPixel<QPixelLayout::BPP24>(const uchar *src, int index) | - | ||||||||||||
787 | { | - | ||||||||||||
788 | return reinterpret_cast<const quint24 *>(src)[index]; never executed: return reinterpret_cast<const quint24 *>(src)[index]; | 0 | ||||||||||||
789 | } | - | ||||||||||||
790 | - | |||||||||||||
791 | template <> | - | ||||||||||||
792 | inline uint QT_FASTCALL fetchPixel<QPixelLayout::BPP32>(const uchar *src, int index) | - | ||||||||||||
793 | { | - | ||||||||||||
794 | return reinterpret_cast<const uint *>(src)[index]; never executed: return reinterpret_cast<const uint *>(src)[index]; | 0 | ||||||||||||
795 | } | - | ||||||||||||
796 | - | |||||||||||||
797 | template <QPixelLayout::BPP bpp> | - | ||||||||||||
798 | inline const uint *QT_FASTCALL fetchPixels(uint *buffer, const uchar *src, int index, int count) | - | ||||||||||||
799 | { | - | ||||||||||||
800 | for (int i = 0; i < count; ++i)
| 0 | ||||||||||||
801 | buffer[i] = fetchPixel<bpp>(src, index + i); never executed: buffer[i] = fetchPixel<bpp>(src, index + i); | 0 | ||||||||||||
802 | return buffer; never executed: return buffer; | 0 | ||||||||||||
803 | } | - | ||||||||||||
804 | - | |||||||||||||
805 | template <> | - | ||||||||||||
806 | inline const uint *QT_FASTCALL fetchPixels<QPixelLayout::BPP32>(uint *, const uchar *src, int index, int) | - | ||||||||||||
807 | { | - | ||||||||||||
808 | return reinterpret_cast<const uint *>(src) + index; never executed: return reinterpret_cast<const uint *>(src) + index; | 0 | ||||||||||||
809 | } | - | ||||||||||||
810 | - | |||||||||||||
811 | template <QPixelLayout::BPP width> static | - | ||||||||||||
812 | void QT_FASTCALL storePixel(uchar *dest, int index, uint pixel); | - | ||||||||||||
813 | - | |||||||||||||
814 | template <> | - | ||||||||||||
815 | inline void QT_FASTCALL storePixel<QPixelLayout::BPP1LSB>(uchar *dest, int index, uint pixel) | - | ||||||||||||
816 | { | - | ||||||||||||
817 | if (pixel)
| 0 | ||||||||||||
818 | dest[index >> 3] |= 1 << (index & 7); never executed: dest[index >> 3] |= 1 << (index & 7); | 0 | ||||||||||||
819 | else | - | ||||||||||||
820 | dest[index >> 3] &= ~(1 << (index & 7)); never executed: dest[index >> 3] &= ~(1 << (index & 7)); | 0 | ||||||||||||
821 | } | - | ||||||||||||
822 | - | |||||||||||||
823 | template <> | - | ||||||||||||
824 | inline void QT_FASTCALL storePixel<QPixelLayout::BPP1MSB>(uchar *dest, int index, uint pixel) | - | ||||||||||||
825 | { | - | ||||||||||||
826 | if (pixel)
| 0 | ||||||||||||
827 | dest[index >> 3] |= 1 << (~index & 7); never executed: dest[index >> 3] |= 1 << (~index & 7); | 0 | ||||||||||||
828 | else | - | ||||||||||||
829 | dest[index >> 3] &= ~(1 << (~index & 7)); never executed: dest[index >> 3] &= ~(1 << (~index & 7)); | 0 | ||||||||||||
830 | } | - | ||||||||||||
831 | - | |||||||||||||
832 | template <> | - | ||||||||||||
833 | inline void QT_FASTCALL storePixel<QPixelLayout::BPP8>(uchar *dest, int index, uint pixel) | - | ||||||||||||
834 | { | - | ||||||||||||
835 | dest[index] = uchar(pixel); | - | ||||||||||||
836 | } never executed: end of block | 0 | ||||||||||||
837 | - | |||||||||||||
838 | template <> | - | ||||||||||||
839 | inline void QT_FASTCALL storePixel<QPixelLayout::BPP16>(uchar *dest, int index, uint pixel) | - | ||||||||||||
840 | { | - | ||||||||||||
841 | reinterpret_cast<quint16 *>(dest)[index] = quint16(pixel); | - | ||||||||||||
842 | } never executed: end of block | 0 | ||||||||||||
843 | - | |||||||||||||
844 | template <> | - | ||||||||||||
845 | inline void QT_FASTCALL storePixel<QPixelLayout::BPP24>(uchar *dest, int index, uint pixel) | - | ||||||||||||
846 | { | - | ||||||||||||
847 | reinterpret_cast<quint24 *>(dest)[index] = quint24(pixel); | - | ||||||||||||
848 | } never executed: end of block | 0 | ||||||||||||
849 | - | |||||||||||||
850 | template <QPixelLayout::BPP width> | - | ||||||||||||
851 | inline void QT_FASTCALL storePixels(uchar *dest, const uint *src, int index, int count) | - | ||||||||||||
852 | { | - | ||||||||||||
853 | for (int i = 0; i < count; ++i)
| 0 | ||||||||||||
854 | storePixel<width>(dest, index + i, src[i]); never executed: storePixel<width>(dest, index + i, src[i]); | 0 | ||||||||||||
855 | } never executed: end of block | 0 | ||||||||||||
856 | - | |||||||||||||
857 | template <> | - | ||||||||||||
858 | inline void QT_FASTCALL storePixels<QPixelLayout::BPP32>(uchar *dest, const uint *src, int index, int count) | - | ||||||||||||
859 | { | - | ||||||||||||
860 | memcpy(reinterpret_cast<uint *>(dest) + index, src, count * sizeof(uint)); | - | ||||||||||||
861 | } never executed: end of block | 0 | ||||||||||||
862 | - | |||||||||||||
863 | // Note: | - | ||||||||||||
864 | // convertToArgb32() assumes that no color channel is less than 4 bits. | - | ||||||||||||
865 | // convertFromArgb32() assumes that no color channel is more than 8 bits. | - | ||||||||||||
866 | // QImage::rgbSwapped() assumes that the red and blue color channels have the same number of bits. | - | ||||||||||||
867 | QPixelLayout qPixelLayouts[QImage::NImageFormats] = { | - | ||||||||||||
868 | { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPPNone, 0, 0, 0, 0 }, // Format_Invalid | - | ||||||||||||
869 | { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPP1MSB, convertIndexedToARGB32PM, 0, 0, convertIndexedToARGB64PM }, // Format_Mono | - | ||||||||||||
870 | { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPP1LSB, convertIndexedToARGB32PM, 0, 0, convertIndexedToARGB64PM }, // Format_MonoLSB | - | ||||||||||||
871 | { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPP8, convertIndexedToARGB32PM, 0, 0, convertIndexedToARGB64PM }, // Format_Indexed8 | - | ||||||||||||
872 | // Technically using convertPassThrough to convert from ARGB32PM to RGB32 is wrong, | - | ||||||||||||
873 | // but everywhere this generic conversion would be wrong is currently overloaded. | - | ||||||||||||
874 | { 8, 16, 8, 8, 8, 0, 0, 0, false, QPixelLayout::BPP32, convertPassThrough, convertPassThrough, convertPassThrough, convertRGB32ToRGB64 }, // Format_RGB32 | - | ||||||||||||
875 | { 8, 16, 8, 8, 8, 0, 8, 24, false, QPixelLayout::BPP32, convertARGB32ToARGB32PM, convertARGB32FromARGB32PM, convertPassThrough, convertARGB32ToARGB64PM }, // Format_ARGB32 | - | ||||||||||||
876 | { 8, 16, 8, 8, 8, 0, 8, 24, true, QPixelLayout::BPP32, convertPassThrough, convertPassThrough, convertPassThrough, convertARGB32PMToARGB64PM }, // Format_ARGB32_Premultiplied | - | ||||||||||||
877 | #ifdef Q_COMPILER_CONSTEXPR | - | ||||||||||||
878 | pixelLayoutRGB<QImage::Format_RGB16>(), | - | ||||||||||||
879 | pixelLayoutARGBPM<QImage::Format_ARGB8565_Premultiplied>(), | - | ||||||||||||
880 | pixelLayoutRGB<QImage::Format_RGB666>(), | - | ||||||||||||
881 | pixelLayoutARGBPM<QImage::Format_ARGB6666_Premultiplied>(), | - | ||||||||||||
882 | pixelLayoutRGB<QImage::Format_RGB555>(), | - | ||||||||||||
883 | pixelLayoutARGBPM<QImage::Format_ARGB8555_Premultiplied>(), | - | ||||||||||||
884 | pixelLayoutRGB<QImage::Format_RGB888>(), | - | ||||||||||||
885 | pixelLayoutRGB<QImage::Format_RGB444>(), | - | ||||||||||||
886 | pixelLayoutARGBPM<QImage::Format_ARGB4444_Premultiplied>(), | - | ||||||||||||
887 | #else | - | ||||||||||||
888 | { 5, 11, 6, 5, 5, 0, 0, 0, false, QPixelLayout::BPP16, | - | ||||||||||||
889 | convertToRGB32<QImage::Format_RGB16>, | - | ||||||||||||
890 | convertRGBFromARGB32PM<QImage::Format_RGB16, false>, | - | ||||||||||||
891 | convertRGBFromARGB32PM<QImage::Format_RGB16, true>, | - | ||||||||||||
892 | convertToRGB64<QImage::Format_RGB16>, | - | ||||||||||||
893 | }, | - | ||||||||||||
894 | { 5, 19, 6, 13, 5, 8, 8, 0, true, QPixelLayout::BPP24, | - | ||||||||||||
895 | convertARGBPMToARGB32PM<QImage::Format_ARGB8565_Premultiplied>, | - | ||||||||||||
896 | convertARGBPMFromARGB32PM<QImage::Format_ARGB8565_Premultiplied, false>, | - | ||||||||||||
897 | convertARGBPMFromARGB32PM<QImage::Format_ARGB8565_Premultiplied, true>, | - | ||||||||||||
898 | convertARGBPMToARGB64PM<QImage::Format_ARGB8565_Premultiplied>, | - | ||||||||||||
899 | }, | - | ||||||||||||
900 | { 6, 12, 6, 6, 6, 0, 0, 0, false, QPixelLayout::BPP24, | - | ||||||||||||
901 | convertToRGB32<QImage::Format_RGB666>, | - | ||||||||||||
902 | convertRGBFromARGB32PM<QImage::Format_RGB666, false>, | - | ||||||||||||
903 | convertRGBFromARGB32PM<QImage::Format_RGB666, true>, | - | ||||||||||||
904 | convertToRGB64<QImage::Format_RGB666>, | - | ||||||||||||
905 | }, | - | ||||||||||||
906 | { 6, 12, 6, 6, 6, 0, 6, 18, true, QPixelLayout::BPP24, | - | ||||||||||||
907 | convertARGBPMToARGB32PM<QImage::Format_ARGB6666_Premultiplied>, | - | ||||||||||||
908 | convertARGBPMFromARGB32PM<QImage::Format_ARGB6666_Premultiplied, false>, | - | ||||||||||||
909 | convertARGBPMFromARGB32PM<QImage::Format_ARGB6666_Premultiplied, true>, | - | ||||||||||||
910 | convertARGBPMToARGB64PM<QImage::Format_ARGB6666_Premultiplied>, | - | ||||||||||||
911 | }, | - | ||||||||||||
912 | { 5, 10, 5, 5, 5, 0, 0, 0, false, QPixelLayout::BPP16, | - | ||||||||||||
913 | convertToRGB32<QImage::Format_RGB555>, | - | ||||||||||||
914 | convertRGBFromARGB32PM<QImage::Format_RGB555, false>, | - | ||||||||||||
915 | convertRGBFromARGB32PM<QImage::Format_RGB555, true>, | - | ||||||||||||
916 | convertToRGB64<QImage::Format_RGB555>, | - | ||||||||||||
917 | }, | - | ||||||||||||
918 | { 5, 18, 5, 13, 5, 8, 8, 0, true, QPixelLayout::BPP24, | - | ||||||||||||
919 | convertARGBPMToARGB32PM<QImage::Format_ARGB8555_Premultiplied>, | - | ||||||||||||
920 | convertARGBPMFromARGB32PM<QImage::Format_ARGB8555_Premultiplied, false>, | - | ||||||||||||
921 | convertARGBPMFromARGB32PM<QImage::Format_ARGB8555_Premultiplied, true>, | - | ||||||||||||
922 | convertARGBPMToARGB64PM<QImage::Format_ARGB8555_Premultiplied>, | - | ||||||||||||
923 | }, | - | ||||||||||||
924 | { 8, 16, 8, 8, 8, 0, 0, 0, false, QPixelLayout::BPP24, | - | ||||||||||||
925 | convertToRGB32<QImage::Format_RGB888>, | - | ||||||||||||
926 | convertRGBFromARGB32PM<QImage::Format_RGB888, false>, | - | ||||||||||||
927 | convertRGBFromARGB32PM<QImage::Format_RGB888, true>, | - | ||||||||||||
928 | convertToRGB64<QImage::Format_RGB888>, | - | ||||||||||||
929 | }, | - | ||||||||||||
930 | { 4, 8, 4, 4, 4, 0, 0, 0, false, QPixelLayout::BPP16, | - | ||||||||||||
931 | convertToRGB32<QImage::Format_RGB444>, | - | ||||||||||||
932 | convertRGBFromARGB32PM<QImage::Format_RGB444, false>, | - | ||||||||||||
933 | convertRGBFromARGB32PM<QImage::Format_RGB444, true>, | - | ||||||||||||
934 | convertToRGB64<QImage::Format_RGB444>, | - | ||||||||||||
935 | }, | - | ||||||||||||
936 | { 4, 8, 4, 4, 4, 0, 4, 12, true, QPixelLayout::BPP16, | - | ||||||||||||
937 | convertARGBPMToARGB32PM<QImage::Format_ARGB4444_Premultiplied>, | - | ||||||||||||
938 | convertARGBPMFromARGB32PM<QImage::Format_ARGB4444_Premultiplied, false>, | - | ||||||||||||
939 | convertARGBPMFromARGB32PM<QImage::Format_ARGB4444_Premultiplied, true>, | - | ||||||||||||
940 | convertARGBPMToARGB64PM<QImage::Format_ARGB4444_Premultiplied>, | - | ||||||||||||
941 | }, | - | ||||||||||||
942 | #endif | - | ||||||||||||
943 | #if Q_BYTE_ORDER == Q_BIG_ENDIAN | - | ||||||||||||
944 | { 8, 24, 8, 16, 8, 8, 0, 0, false, QPixelLayout::BPP32, convertRGBA8888PMToARGB32PM, convertRGBXFromARGB32PM, convertRGBXFromRGB32, convertRGBA8888PMToARGB64PM }, // Format_RGBX8888 | - | ||||||||||||
945 | { 8, 24, 8, 16, 8, 8, 8, 0, false, QPixelLayout::BPP32, convertRGBA8888ToARGB32PM, convertRGBA8888FromARGB32PM, convertRGBXFromRGB32, convertRGBA8888ToARGB64PM }, // Format_RGBA8888 | - | ||||||||||||
946 | { 8, 24, 8, 16, 8, 8, 8, 0, true, QPixelLayout::BPP32, convertRGBA8888PMToARGB32PM, convertRGBA8888PMFromARGB32PM, convertRGBXFromRGB32, convertRGBA8888PMToARGB64PM}, // Format_RGBA8888_Premultiplied | - | ||||||||||||
947 | #else | - | ||||||||||||
948 | { 8, 0, 8, 8, 8, 16, 0, 24, false, QPixelLayout::BPP32, convertRGBA8888PMToARGB32PM, convertRGBXFromARGB32PM, convertRGBXFromRGB32, convertRGBA8888PMToARGB64PM }, // Format_RGBX8888 | - | ||||||||||||
949 | { 8, 0, 8, 8, 8, 16, 8, 24, false, QPixelLayout::BPP32, convertRGBA8888ToARGB32PM, convertRGBA8888FromARGB32PM, convertRGBXFromRGB32, convertRGBA8888ToARGB64PM }, // Format_RGBA8888 (ABGR32) | - | ||||||||||||
950 | { 8, 0, 8, 8, 8, 16, 8, 24, true, QPixelLayout::BPP32, convertRGBA8888PMToARGB32PM, convertRGBA8888PMFromARGB32PM, convertRGBXFromRGB32, convertRGBA8888PMToARGB64PM }, // Format_RGBA8888_Premultiplied | - | ||||||||||||
951 | #endif | - | ||||||||||||
952 | { 10, 20, 10, 10, 10, 0, 0, 30, false, QPixelLayout::BPP32, convertA2RGB30PMToARGB32PM<PixelOrderBGR>, convertRGB30FromARGB32PM<PixelOrderBGR>, convertRGB30FromRGB32<PixelOrderBGR>, convertA2RGB30PMToARGB64PM<PixelOrderBGR> }, // Format_BGR30 | - | ||||||||||||
953 | { 10, 20, 10, 10, 10, 0, 2, 30, true, QPixelLayout::BPP32, convertA2RGB30PMToARGB32PM<PixelOrderBGR>, convertA2RGB30PMFromARGB32PM<PixelOrderBGR>, convertRGB30FromRGB32<PixelOrderBGR>, convertA2RGB30PMToARGB64PM<PixelOrderBGR> }, // Format_A2BGR30_Premultiplied | - | ||||||||||||
954 | { 10, 0, 10, 10, 10, 20, 0, 30, false, QPixelLayout::BPP32, convertA2RGB30PMToARGB32PM<PixelOrderRGB>, convertRGB30FromARGB32PM<PixelOrderRGB>, convertRGB30FromRGB32<PixelOrderRGB>, convertA2RGB30PMToARGB64PM<PixelOrderRGB> }, // Format_RGB30 | - | ||||||||||||
955 | { 10, 0, 10, 10, 10, 20, 2, 30, true, QPixelLayout::BPP32, convertA2RGB30PMToARGB32PM<PixelOrderRGB>, convertA2RGB30PMFromARGB32PM<PixelOrderRGB>, convertRGB30FromRGB32<PixelOrderRGB>, convertA2RGB30PMToARGB64PM<PixelOrderRGB> }, // Format_A2RGB30_Premultiplied | - | ||||||||||||
956 | { 0, 0, 0, 0, 0, 0, 8, 0, false, QPixelLayout::BPP8, convertAlpha8ToRGB32, convertAlpha8FromARGB32PM, 0, convertAlpha8ToRGB64 }, // Format_Alpha8 | - | ||||||||||||
957 | { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPP8, convertGrayscale8ToRGB32, convertGrayscale8FromARGB32PM, convertGrayscale8FromRGB32, convertGrayscale8ToRGB64 } // Format_Grayscale8 | - | ||||||||||||
958 | }; | - | ||||||||||||
959 | - | |||||||||||||
960 | const FetchPixelsFunc qFetchPixels[QPixelLayout::BPPCount] = { | - | ||||||||||||
961 | 0, // BPPNone | - | ||||||||||||
962 | fetchPixels<QPixelLayout::BPP1MSB>, // BPP1MSB | - | ||||||||||||
963 | fetchPixels<QPixelLayout::BPP1LSB>, // BPP1LSB | - | ||||||||||||
964 | fetchPixels<QPixelLayout::BPP8>, // BPP8 | - | ||||||||||||
965 | fetchPixels<QPixelLayout::BPP16>, // BPP16 | - | ||||||||||||
966 | fetchPixels<QPixelLayout::BPP24>, // BPP24 | - | ||||||||||||
967 | fetchPixels<QPixelLayout::BPP32> // BPP32 | - | ||||||||||||
968 | }; | - | ||||||||||||
969 | - | |||||||||||||
970 | StorePixelsFunc qStorePixels[QPixelLayout::BPPCount] = { | - | ||||||||||||
971 | 0, // BPPNone | - | ||||||||||||
972 | storePixels<QPixelLayout::BPP1MSB>, // BPP1MSB | - | ||||||||||||
973 | storePixels<QPixelLayout::BPP1LSB>, // BPP1LSB | - | ||||||||||||
974 | storePixels<QPixelLayout::BPP8>, // BPP8 | - | ||||||||||||
975 | storePixels<QPixelLayout::BPP16>, // BPP16 | - | ||||||||||||
976 | storePixels<QPixelLayout::BPP24>, // BPP24 | - | ||||||||||||
977 | storePixels<QPixelLayout::BPP32> // BPP32 | - | ||||||||||||
978 | }; | - | ||||||||||||
979 | - | |||||||||||||
980 | typedef uint (QT_FASTCALL *FetchPixelFunc)(const uchar *src, int index); | - | ||||||||||||
981 | - | |||||||||||||
982 | static const FetchPixelFunc qFetchPixel[QPixelLayout::BPPCount] = { | - | ||||||||||||
983 | 0, // BPPNone | - | ||||||||||||
984 | fetchPixel<QPixelLayout::BPP1MSB>, // BPP1MSB | - | ||||||||||||
985 | fetchPixel<QPixelLayout::BPP1LSB>, // BPP1LSB | - | ||||||||||||
986 | fetchPixel<QPixelLayout::BPP8>, // BPP8 | - | ||||||||||||
987 | fetchPixel<QPixelLayout::BPP16>, // BPP16 | - | ||||||||||||
988 | fetchPixel<QPixelLayout::BPP24>, // BPP24 | - | ||||||||||||
989 | fetchPixel<QPixelLayout::BPP32> // BPP32 | - | ||||||||||||
990 | }; | - | ||||||||||||
991 | - | |||||||||||||
992 | /* | - | ||||||||||||
993 | Destination fetch. This is simple as we don't have to do bounds checks or | - | ||||||||||||
994 | transformations | - | ||||||||||||
995 | */ | - | ||||||||||||
996 | - | |||||||||||||
997 | static uint * QT_FASTCALL destFetchMono(uint *buffer, QRasterBuffer *rasterBuffer, int x, int y, int length) | - | ||||||||||||
998 | { | - | ||||||||||||
999 | uchar *Q_DECL_RESTRICT data = (uchar *)rasterBuffer->scanLine(y); | - | ||||||||||||
1000 | uint *start = buffer; | - | ||||||||||||
1001 | const uint *end = buffer + length; | - | ||||||||||||
1002 | while (buffer < end) {
| 0 | ||||||||||||
1003 | *buffer = data[x>>3] & (0x80 >> (x & 7)) ? rasterBuffer->destColor1 : rasterBuffer->destColor0;
| 0 | ||||||||||||
1004 | ++buffer; | - | ||||||||||||
1005 | ++x; | - | ||||||||||||
1006 | } never executed: end of block | 0 | ||||||||||||
1007 | return start; never executed: return start; | 0 | ||||||||||||
1008 | } | - | ||||||||||||
1009 | - | |||||||||||||
1010 | static uint * QT_FASTCALL destFetchMonoLsb(uint *buffer, QRasterBuffer *rasterBuffer, int x, int y, int length) | - | ||||||||||||
1011 | { | - | ||||||||||||
1012 | uchar *Q_DECL_RESTRICT data = (uchar *)rasterBuffer->scanLine(y); | - | ||||||||||||
1013 | uint *start = buffer; | - | ||||||||||||
1014 | const uint *end = buffer + length; | - | ||||||||||||
1015 | while (buffer < end) {
| 0 | ||||||||||||
1016 | *buffer = data[x>>3] & (0x1 << (x & 7)) ? rasterBuffer->destColor1 : rasterBuffer->destColor0;
| 0 | ||||||||||||
1017 | ++buffer; | - | ||||||||||||
1018 | ++x; | - | ||||||||||||
1019 | } never executed: end of block | 0 | ||||||||||||
1020 | return start; never executed: return start; | 0 | ||||||||||||
1021 | } | - | ||||||||||||
1022 | - | |||||||||||||
1023 | static uint * QT_FASTCALL destFetchARGB32P(uint *, QRasterBuffer *rasterBuffer, int x, int y, int) | - | ||||||||||||
1024 | { | - | ||||||||||||
1025 | return (uint *)rasterBuffer->scanLine(y) + x; never executed: return (uint *)rasterBuffer->scanLine(y) + x; | 0 | ||||||||||||
1026 | } | - | ||||||||||||
1027 | - | |||||||||||||
1028 | static uint * QT_FASTCALL destFetchRGB16(uint *buffer, QRasterBuffer *rasterBuffer, int x, int y, int length) | - | ||||||||||||
1029 | { | - | ||||||||||||
1030 | const ushort *Q_DECL_RESTRICT data = (const ushort *)rasterBuffer->scanLine(y) + x; | - | ||||||||||||
1031 | for (int i = 0; i < length; ++i)
| 0 | ||||||||||||
1032 | buffer[i] = qConvertRgb16To32(data[i]); never executed: buffer[i] = qConvertRgb16To32(data[i]); | 0 | ||||||||||||
1033 | return buffer; never executed: return buffer; | 0 | ||||||||||||
1034 | } | - | ||||||||||||
1035 | - | |||||||||||||
1036 | static uint *QT_FASTCALL destFetch(uint *buffer, QRasterBuffer *rasterBuffer, int x, int y, int length) | - | ||||||||||||
1037 | { | - | ||||||||||||
1038 | const QPixelLayout *layout = &qPixelLayouts[rasterBuffer->format]; | - | ||||||||||||
1039 | const uint *ptr = qFetchPixels[layout->bpp](buffer, rasterBuffer->scanLine(y), x, length); | - | ||||||||||||
1040 | return const_cast<uint *>(layout->convertToARGB32PM(buffer, ptr, length, layout, 0)); never executed: return const_cast<uint *>(layout->convertToARGB32PM(buffer, ptr, length, layout, 0)); | 0 | ||||||||||||
1041 | } | - | ||||||||||||
1042 | - | |||||||||||||
1043 | static QRgba64 *QT_FASTCALL destFetch64(QRgba64 *buffer, QRasterBuffer *rasterBuffer, int x, int y, int length) | - | ||||||||||||
1044 | { | - | ||||||||||||
1045 | const QPixelLayout *layout = &qPixelLayouts[rasterBuffer->format]; | - | ||||||||||||
1046 | uint buffer32[buffer_size]; | - | ||||||||||||
1047 | const uint *ptr = qFetchPixels[layout->bpp](buffer32, rasterBuffer->scanLine(y), x, length); | - | ||||||||||||
1048 | return const_cast<QRgba64 *>(layout->convertToARGB64PM(buffer, ptr, length, layout, 0)); never executed: return const_cast<QRgba64 *>(layout->convertToARGB64PM(buffer, ptr, length, layout, 0)); | 0 | ||||||||||||
1049 | } | - | ||||||||||||
1050 | - | |||||||||||||
1051 | static QRgba64 *QT_FASTCALL destFetch64uint32(QRgba64 *buffer, QRasterBuffer *rasterBuffer, int x, int y, int length) | - | ||||||||||||
1052 | { | - | ||||||||||||
1053 | const QPixelLayout *layout = &qPixelLayouts[rasterBuffer->format]; | - | ||||||||||||
1054 | const uint *src = ((const uint *)rasterBuffer->scanLine(y)) + x; | - | ||||||||||||
1055 | return const_cast<QRgba64 *>(layout->convertToARGB64PM(buffer, src, length, layout, 0)); never executed: return const_cast<QRgba64 *>(layout->convertToARGB64PM(buffer, src, length, layout, 0)); | 0 | ||||||||||||
1056 | } | - | ||||||||||||
1057 | - | |||||||||||||
1058 | static DestFetchProc destFetchProc[QImage::NImageFormats] = | - | ||||||||||||
1059 | { | - | ||||||||||||
1060 | 0, // Format_Invalid | - | ||||||||||||
1061 | destFetchMono, // Format_Mono, | - | ||||||||||||
1062 | destFetchMonoLsb, // Format_MonoLSB | - | ||||||||||||
1063 | 0, // Format_Indexed8 | - | ||||||||||||
1064 | destFetchARGB32P, // Format_RGB32 | - | ||||||||||||
1065 | destFetch, // Format_ARGB32, | - | ||||||||||||
1066 | destFetchARGB32P, // Format_ARGB32_Premultiplied | - | ||||||||||||
1067 | destFetchRGB16, // Format_RGB16 | - | ||||||||||||
1068 | destFetch, // Format_ARGB8565_Premultiplied | - | ||||||||||||
1069 | destFetch, // Format_RGB666 | - | ||||||||||||
1070 | destFetch, // Format_ARGB6666_Premultiplied | - | ||||||||||||
1071 | destFetch, // Format_RGB555 | - | ||||||||||||
1072 | destFetch, // Format_ARGB8555_Premultiplied | - | ||||||||||||
1073 | destFetch, // Format_RGB888 | - | ||||||||||||
1074 | destFetch, // Format_RGB444 | - | ||||||||||||
1075 | destFetch, // Format_ARGB4444_Premultiplied | - | ||||||||||||
1076 | destFetch, // Format_RGBX8888 | - | ||||||||||||
1077 | destFetch, // Format_RGBA8888 | - | ||||||||||||
1078 | destFetch, // Format_RGBA8888_Premultiplied | - | ||||||||||||
1079 | destFetch, // Format_BGR30 | - | ||||||||||||
1080 | destFetch, // Format_A2BGR30_Premultiplied | - | ||||||||||||
1081 | destFetch, // Format_RGB30 | - | ||||||||||||
1082 | destFetch, // Format_A2RGB30_Premultiplied | - | ||||||||||||
1083 | destFetch, // Format_Alpha8 | - | ||||||||||||
1084 | destFetch, // Format_Grayscale8 | - | ||||||||||||
1085 | }; | - | ||||||||||||
1086 | - | |||||||||||||
1087 | static DestFetchProc64 destFetchProc64[QImage::NImageFormats] = | - | ||||||||||||
1088 | { | - | ||||||||||||
1089 | 0, // Format_Invalid | - | ||||||||||||
1090 | destFetch64, // Format_Mono, | - | ||||||||||||
1091 | destFetch64, // Format_MonoLSB | - | ||||||||||||
1092 | 0, // Format_Indexed8 | - | ||||||||||||
1093 | destFetch64uint32, // Format_RGB32 | - | ||||||||||||
1094 | destFetch64uint32, // Format_ARGB32, | - | ||||||||||||
1095 | destFetch64uint32, // Format_ARGB32_Premultiplied | - | ||||||||||||
1096 | destFetch64, // Format_RGB16 | - | ||||||||||||
1097 | destFetch64, // Format_ARGB8565_Premultiplied | - | ||||||||||||
1098 | destFetch64, // Format_RGB666 | - | ||||||||||||
1099 | destFetch64, // Format_ARGB6666_Premultiplied | - | ||||||||||||
1100 | destFetch64, // Format_RGB555 | - | ||||||||||||
1101 | destFetch64, // Format_ARGB8555_Premultiplied | - | ||||||||||||
1102 | destFetch64, // Format_RGB888 | - | ||||||||||||
1103 | destFetch64, // Format_RGB444 | - | ||||||||||||
1104 | destFetch64, // Format_ARGB4444_Premultiplied | - | ||||||||||||
1105 | destFetch64uint32, // Format_RGBX8888 | - | ||||||||||||
1106 | destFetch64uint32, // Format_RGBA8888 | - | ||||||||||||
1107 | destFetch64uint32, // Format_RGBA8888_Premultiplied | - | ||||||||||||
1108 | destFetch64uint32, // Format_BGR30 | - | ||||||||||||
1109 | destFetch64uint32, // Format_A2BGR30_Premultiplied | - | ||||||||||||
1110 | destFetch64uint32, // Format_RGB30 | - | ||||||||||||
1111 | destFetch64uint32, // Format_A2RGB30_Premultiplied | - | ||||||||||||
1112 | destFetch64, // Format_Alpha8 | - | ||||||||||||
1113 | destFetch64, // Format_Grayscale8 | - | ||||||||||||
1114 | }; | - | ||||||||||||
1115 | - | |||||||||||||
1116 | /* | - | ||||||||||||
1117 | Returns the color in the mono destination color table | - | ||||||||||||
1118 | that is the "nearest" to /color/. | - | ||||||||||||
1119 | */ | - | ||||||||||||
1120 | static inline QRgb findNearestColor(QRgb color, QRasterBuffer *rbuf) | - | ||||||||||||
1121 | { | - | ||||||||||||
1122 | QRgb color_0 = qPremultiply(rbuf->destColor0); | - | ||||||||||||
1123 | QRgb color_1 = qPremultiply(rbuf->destColor1); | - | ||||||||||||
1124 | color = qPremultiply(color); | - | ||||||||||||
1125 | - | |||||||||||||
1126 | int r = qRed(color); | - | ||||||||||||
1127 | int g = qGreen(color); | - | ||||||||||||
1128 | int b = qBlue(color); | - | ||||||||||||
1129 | int rx, gx, bx; | - | ||||||||||||
1130 | int dist_0, dist_1; | - | ||||||||||||
1131 | - | |||||||||||||
1132 | rx = r - qRed(color_0); | - | ||||||||||||
1133 | gx = g - qGreen(color_0); | - | ||||||||||||
1134 | bx = b - qBlue(color_0); | - | ||||||||||||
1135 | dist_0 = rx*rx + gx*gx + bx*bx; | - | ||||||||||||
1136 | - | |||||||||||||
1137 | rx = r - qRed(color_1); | - | ||||||||||||
1138 | gx = g - qGreen(color_1); | - | ||||||||||||
1139 | bx = b - qBlue(color_1); | - | ||||||||||||
1140 | dist_1 = rx*rx + gx*gx + bx*bx; | - | ||||||||||||
1141 | - | |||||||||||||
1142 | if (dist_0 < dist_1)
| 0 | ||||||||||||
1143 | return color_0; never executed: return color_0; | 0 | ||||||||||||
1144 | return color_1; never executed: return color_1; | 0 | ||||||||||||
1145 | } | - | ||||||||||||
1146 | - | |||||||||||||
1147 | /* | - | ||||||||||||
1148 | Destination store. | - | ||||||||||||
1149 | */ | - | ||||||||||||
1150 | - | |||||||||||||
1151 | static void QT_FASTCALL destStoreMono(QRasterBuffer *rasterBuffer, int x, int y, const uint *buffer, int length) | - | ||||||||||||
1152 | { | - | ||||||||||||
1153 | uchar *Q_DECL_RESTRICT data = (uchar *)rasterBuffer->scanLine(y); | - | ||||||||||||
1154 | if (rasterBuffer->monoDestinationWithClut) {
| 0 | ||||||||||||
1155 | for (int i = 0; i < length; ++i) {
| 0 | ||||||||||||
1156 | if (buffer[i] == rasterBuffer->destColor0) {
| 0 | ||||||||||||
1157 | data[x >> 3] &= ~(0x80 >> (x & 7)); | - | ||||||||||||
1158 | } else if (buffer[i] == rasterBuffer->destColor1) { never executed: end of block
| 0 | ||||||||||||
1159 | data[x >> 3] |= 0x80 >> (x & 7); | - | ||||||||||||
1160 | } else if (findNearestColor(buffer[i], rasterBuffer) == rasterBuffer->destColor0) { never executed: end of block
| 0 | ||||||||||||
1161 | data[x >> 3] &= ~(0x80 >> (x & 7)); | - | ||||||||||||
1162 | } else { never executed: end of block | 0 | ||||||||||||
1163 | data[x >> 3] |= 0x80 >> (x & 7); | - | ||||||||||||
1164 | } never executed: end of block | 0 | ||||||||||||
1165 | ++x; | - | ||||||||||||
1166 | } never executed: end of block | 0 | ||||||||||||
1167 | } else { never executed: end of block | 0 | ||||||||||||
1168 | for (int i = 0; i < length; ++i) {
| 0 | ||||||||||||
1169 | if (qGray(buffer[i]) < int(qt_bayer_matrix[y & 15][x & 15]))
| 0 | ||||||||||||
1170 | data[x >> 3] |= 0x80 >> (x & 7); never executed: data[x >> 3] |= 0x80 >> (x & 7); | 0 | ||||||||||||
1171 | else | - | ||||||||||||
1172 | data[x >> 3] &= ~(0x80 >> (x & 7)); never executed: data[x >> 3] &= ~(0x80 >> (x & 7)); | 0 | ||||||||||||
1173 | ++x; | - | ||||||||||||
1174 | } never executed: end of block | 0 | ||||||||||||
1175 | } never executed: end of block | 0 | ||||||||||||
1176 | } | - | ||||||||||||
1177 | - | |||||||||||||
1178 | static void QT_FASTCALL destStoreMonoLsb(QRasterBuffer *rasterBuffer, int x, int y, const uint *buffer, int length) | - | ||||||||||||
1179 | { | - | ||||||||||||
1180 | uchar *Q_DECL_RESTRICT data = (uchar *)rasterBuffer->scanLine(y); | - | ||||||||||||
1181 | if (rasterBuffer->monoDestinationWithClut) {
| 0 | ||||||||||||
1182 | for (int i = 0; i < length; ++i) {
| 0 | ||||||||||||
1183 | if (buffer[i] == rasterBuffer->destColor0) {
| 0 | ||||||||||||
1184 | data[x >> 3] &= ~(1 << (x & 7)); | - | ||||||||||||
1185 | } else if (buffer[i] == rasterBuffer->destColor1) { never executed: end of block
| 0 | ||||||||||||
1186 | data[x >> 3] |= 1 << (x & 7); | - | ||||||||||||
1187 | } else if (findNearestColor(buffer[i], rasterBuffer) == rasterBuffer->destColor0) { never executed: end of block
| 0 | ||||||||||||
1188 | data[x >> 3] &= ~(1 << (x & 7)); | - | ||||||||||||
1189 | } else { never executed: end of block | 0 | ||||||||||||
1190 | data[x >> 3] |= 1 << (x & 7); | - | ||||||||||||
1191 | } never executed: end of block | 0 | ||||||||||||
1192 | ++x; | - | ||||||||||||
1193 | } never executed: end of block | 0 | ||||||||||||
1194 | } else { never executed: end of block | 0 | ||||||||||||
1195 | for (int i = 0; i < length; ++i) {
| 0 | ||||||||||||
1196 | if (qGray(buffer[i]) < int(qt_bayer_matrix[y & 15][x & 15]))
| 0 | ||||||||||||
1197 | data[x >> 3] |= 1 << (x & 7); never executed: data[x >> 3] |= 1 << (x & 7); | 0 | ||||||||||||
1198 | else | - | ||||||||||||
1199 | data[x >> 3] &= ~(1 << (x & 7)); never executed: data[x >> 3] &= ~(1 << (x & 7)); | 0 | ||||||||||||
1200 | ++x; | - | ||||||||||||
1201 | } never executed: end of block | 0 | ||||||||||||
1202 | } never executed: end of block | 0 | ||||||||||||
1203 | } | - | ||||||||||||
1204 | - | |||||||||||||
1205 | static void QT_FASTCALL destStoreRGB16(QRasterBuffer *rasterBuffer, int x, int y, const uint *buffer, int length) | - | ||||||||||||
1206 | { | - | ||||||||||||
1207 | quint16 *data = (quint16*)rasterBuffer->scanLine(y) + x; | - | ||||||||||||
1208 | for (int i = 0; i < length; ++i)
| 0 | ||||||||||||
1209 | data[i] = qConvertRgb32To16(buffer[i]); never executed: data[i] = qConvertRgb32To16(buffer[i]); | 0 | ||||||||||||
1210 | } never executed: end of block | 0 | ||||||||||||
1211 | - | |||||||||||||
1212 | static void QT_FASTCALL destStore(QRasterBuffer *rasterBuffer, int x, int y, const uint *buffer, int length) | - | ||||||||||||
1213 | { | - | ||||||||||||
1214 | uint buf[buffer_size]; | - | ||||||||||||
1215 | const QPixelLayout *layout = &qPixelLayouts[rasterBuffer->format]; | - | ||||||||||||
1216 | StorePixelsFunc store = qStorePixels[layout->bpp]; | - | ||||||||||||
1217 | uchar *dest = rasterBuffer->scanLine(y); | - | ||||||||||||
1218 | while (length) {
| 0 | ||||||||||||
1219 | int l = qMin(length, buffer_size); | - | ||||||||||||
1220 | const uint *ptr = 0; | - | ||||||||||||
1221 | if (!layout->premultiplied && !layout->alphaWidth)
| 0 | ||||||||||||
1222 | ptr = layout->convertFromRGB32(buf, buffer, l, layout, 0); never executed: ptr = layout->convertFromRGB32(buf, buffer, l, layout, 0); | 0 | ||||||||||||
1223 | else | - | ||||||||||||
1224 | ptr = layout->convertFromARGB32PM(buf, buffer, l, layout, 0); never executed: ptr = layout->convertFromARGB32PM(buf, buffer, l, layout, 0); | 0 | ||||||||||||
1225 | store(dest, ptr, x, l); | - | ||||||||||||
1226 | length -= l; | - | ||||||||||||
1227 | buffer += l; | - | ||||||||||||
1228 | x += l; | - | ||||||||||||
1229 | } never executed: end of block | 0 | ||||||||||||
1230 | } never executed: end of block | 0 | ||||||||||||
1231 | - | |||||||||||||
1232 | static void QT_FASTCALL convertFromRgb64(uint *dest, const QRgba64 *src, int length) | - | ||||||||||||
1233 | { | - | ||||||||||||
1234 | for (int i = 0; i < length; ++i) {
| 0 | ||||||||||||
1235 | dest[i] = src[i].toArgb32(); | - | ||||||||||||
1236 | } never executed: end of block | 0 | ||||||||||||
1237 | } never executed: end of block | 0 | ||||||||||||
1238 | - | |||||||||||||
1239 | static void QT_FASTCALL destStore64(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 *buffer, int length) | - | ||||||||||||
1240 | { | - | ||||||||||||
1241 | uint buf[buffer_size]; | - | ||||||||||||
1242 | const QPixelLayout *layout = &qPixelLayouts[rasterBuffer->format]; | - | ||||||||||||
1243 | StorePixelsFunc store = qStorePixels[layout->bpp]; | - | ||||||||||||
1244 | uchar *dest = rasterBuffer->scanLine(y); | - | ||||||||||||
1245 | while (length) {
| 0 | ||||||||||||
1246 | int l = qMin(length, buffer_size); | - | ||||||||||||
1247 | const uint *ptr = 0; | - | ||||||||||||
1248 | convertFromRgb64(buf, buffer, l); | - | ||||||||||||
1249 | if (!layout->premultiplied && !layout->alphaWidth)
| 0 | ||||||||||||
1250 | ptr = layout->convertFromRGB32(buf, buf, l, layout, 0); never executed: ptr = layout->convertFromRGB32(buf, buf, l, layout, 0); | 0 | ||||||||||||
1251 | else | - | ||||||||||||
1252 | ptr = layout->convertFromARGB32PM(buf, buf, l, layout, 0); never executed: ptr = layout->convertFromARGB32PM(buf, buf, l, layout, 0); | 0 | ||||||||||||
1253 | store(dest, ptr, x, l); | - | ||||||||||||
1254 | length -= l; | - | ||||||||||||
1255 | buffer += l; | - | ||||||||||||
1256 | x += l; | - | ||||||||||||
1257 | } never executed: end of block | 0 | ||||||||||||
1258 | } never executed: end of block | 0 | ||||||||||||
1259 | - | |||||||||||||
1260 | #ifdef __SSE2__ | - | ||||||||||||
1261 | template<QtPixelOrder PixelOrder> | - | ||||||||||||
1262 | static inline void qConvertARGB64PMToA2RGB30PM_sse2(uint *dest, const QRgba64 *buffer, int count) | - | ||||||||||||
1263 | { | - | ||||||||||||
1264 | const __m128i gmask = _mm_set1_epi32(0x000ffc00); | - | ||||||||||||
1265 | const __m128i cmask = _mm_set1_epi32(0x000003ff); | - | ||||||||||||
1266 | int i = 0; | - | ||||||||||||
1267 | __m128i vr, vg, vb, va; | - | ||||||||||||
1268 | for (; i < count && (const uintptr_t)buffer & 0xF; ++i) {
| 0 | ||||||||||||
1269 | *dest++ = qConvertRgb64ToRgb30<PixelOrder>(*buffer++); | - | ||||||||||||
1270 | } never executed: end of block | 0 | ||||||||||||
1271 | - | |||||||||||||
1272 | for (; i < count-15; i += 16) {
| 0 | ||||||||||||
1273 | // Repremultiplying is really expensive and hard to do in SIMD without AVX2, | - | ||||||||||||
1274 | // so we try to avoid it by checking if it is needed 16 samples at a time. | - | ||||||||||||
1275 | __m128i vOr = _mm_set1_epi32(0); | - | ||||||||||||
1276 | __m128i vAnd = _mm_set1_epi32(0xffffffff); | - | ||||||||||||
1277 | for (int j = 0; j < 16; j += 2) {
| 0 | ||||||||||||
1278 | __m128i vs = _mm_load_si128((const __m128i*)(buffer + j)); | - | ||||||||||||
1279 | vOr = _mm_or_si128(vOr, vs); | - | ||||||||||||
1280 | vAnd = _mm_and_si128(vAnd, vs); | - | ||||||||||||
1281 | } never executed: end of block | 0 | ||||||||||||
1282 | const quint16 orAlpha = ((uint)_mm_extract_epi16(vOr, 3)) | ((uint)_mm_extract_epi16(vOr, 7)); | - | ||||||||||||
1283 | const quint16 andAlpha = ((uint)_mm_extract_epi16(vAnd, 3)) & ((uint)_mm_extract_epi16(vAnd, 7)); | - | ||||||||||||
1284 | - | |||||||||||||
1285 | if (andAlpha == 0xffff) {
| 0 | ||||||||||||
1286 | for (int j = 0; j < 16; j += 2) {
| 0 | ||||||||||||
1287 | __m128i vs = _mm_load_si128((const __m128i*)buffer); | - | ||||||||||||
1288 | buffer += 2; | - | ||||||||||||
1289 | vr = _mm_srli_epi64(vs, 6); | - | ||||||||||||
1290 | vg = _mm_srli_epi64(vs, 16 + 6 - 10); | - | ||||||||||||
1291 | vb = _mm_srli_epi64(vs, 32 + 6); | - | ||||||||||||
1292 | vr = _mm_and_si128(vr, cmask); | - | ||||||||||||
1293 | vg = _mm_and_si128(vg, gmask); | - | ||||||||||||
1294 | vb = _mm_and_si128(vb, cmask); | - | ||||||||||||
1295 | va = _mm_srli_epi64(vs, 48 + 14); | - | ||||||||||||
1296 | if (PixelOrder == PixelOrderRGB)
| 0 | ||||||||||||
1297 | vr = _mm_slli_epi32(vr, 20); never executed: vr = _mm_slli_epi32(vr, 20); | 0 | ||||||||||||
1298 | else | - | ||||||||||||
1299 | vb = _mm_slli_epi32(vb, 20); never executed: vb = _mm_slli_epi32(vb, 20); | 0 | ||||||||||||
1300 | va = _mm_slli_epi32(va, 30); | - | ||||||||||||
1301 | __m128i vd = _mm_or_si128(_mm_or_si128(vr, vg), _mm_or_si128(vb, va)); | - | ||||||||||||
1302 | vd = _mm_shuffle_epi32(vd, _MM_SHUFFLE(3, 1, 2, 0)); | - | ||||||||||||
1303 | _mm_storel_epi64((__m128i*)dest, vd); | - | ||||||||||||
1304 | dest += 2; | - | ||||||||||||
1305 | } never executed: end of block | 0 | ||||||||||||
1306 | } else if (orAlpha == 0) { never executed: end of block
| 0 | ||||||||||||
1307 | for (int j = 0; j < 16; ++j) {
| 0 | ||||||||||||
1308 | *dest++ = 0; | - | ||||||||||||
1309 | buffer++; | - | ||||||||||||
1310 | } never executed: end of block | 0 | ||||||||||||
1311 | } else { never executed: end of block | 0 | ||||||||||||
1312 | for (int j = 0; j < 16; ++j)
| 0 | ||||||||||||
1313 | *dest++ = qConvertRgb64ToRgb30<PixelOrder>(*buffer++); never executed: *dest++ = qConvertRgb64ToRgb30<PixelOrder>(*buffer++); | 0 | ||||||||||||
1314 | } never executed: end of block | 0 | ||||||||||||
1315 | } | - | ||||||||||||
1316 | - | |||||||||||||
1317 | for (; i < count; ++i)
| 0 | ||||||||||||
1318 | *dest++ = qConvertRgb64ToRgb30<PixelOrder>(*buffer++); never executed: *dest++ = qConvertRgb64ToRgb30<PixelOrder>(*buffer++); | 0 | ||||||||||||
1319 | } never executed: end of block | 0 | ||||||||||||
1320 | #endif | - | ||||||||||||
1321 | - | |||||||||||||
1322 | static void QT_FASTCALL destStore64ARGB32(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 *buffer, int length) | - | ||||||||||||
1323 | { | - | ||||||||||||
1324 | uint *dest = (uint*)rasterBuffer->scanLine(y) + x; | - | ||||||||||||
1325 | for (int i = 0; i < length; ++i) {
| 0 | ||||||||||||
1326 | dest[i] = buffer[i].unpremultiplied().toArgb32(); | - | ||||||||||||
1327 | } never executed: end of block | 0 | ||||||||||||
1328 | } never executed: end of block | 0 | ||||||||||||
1329 | - | |||||||||||||
1330 | static void QT_FASTCALL destStore64RGBA8888(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 *buffer, int length) | - | ||||||||||||
1331 | { | - | ||||||||||||
1332 | uint *dest = (uint*)rasterBuffer->scanLine(y) + x; | - | ||||||||||||
1333 | for (int i = 0; i < length; ++i) {
| 0 | ||||||||||||
1334 | dest[i] = ARGB2RGBA(buffer[i].unpremultiplied().toArgb32()); | - | ||||||||||||
1335 | } never executed: end of block | 0 | ||||||||||||
1336 | } never executed: end of block | 0 | ||||||||||||
1337 | - | |||||||||||||
1338 | template<QtPixelOrder PixelOrder> | - | ||||||||||||
1339 | static void QT_FASTCALL destStore64RGB30(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 *buffer, int length) | - | ||||||||||||
1340 | { | - | ||||||||||||
1341 | uint *dest = (uint*)rasterBuffer->scanLine(y) + x; | - | ||||||||||||
1342 | #ifdef __SSE2__ | - | ||||||||||||
1343 | qConvertARGB64PMToA2RGB30PM_sse2<PixelOrder>(dest, buffer, length); | - | ||||||||||||
1344 | #else | - | ||||||||||||
1345 | for (int i = 0; i < length; ++i) { | - | ||||||||||||
1346 | dest[i] = qConvertRgb64ToRgb30<PixelOrder>(buffer[i]); | - | ||||||||||||
1347 | } | - | ||||||||||||
1348 | #endif | - | ||||||||||||
1349 | } never executed: end of block | 0 | ||||||||||||
1350 | - | |||||||||||||
1351 | static DestStoreProc destStoreProc[QImage::NImageFormats] = | - | ||||||||||||
1352 | { | - | ||||||||||||
1353 | 0, // Format_Invalid | - | ||||||||||||
1354 | destStoreMono, // Format_Mono, | - | ||||||||||||
1355 | destStoreMonoLsb, // Format_MonoLSB | - | ||||||||||||
1356 | 0, // Format_Indexed8 | - | ||||||||||||
1357 | 0, // Format_RGB32 | - | ||||||||||||
1358 | destStore, // Format_ARGB32, | - | ||||||||||||
1359 | 0, // Format_ARGB32_Premultiplied | - | ||||||||||||
1360 | destStoreRGB16, // Format_RGB16 | - | ||||||||||||
1361 | destStore, // Format_ARGB8565_Premultiplied | - | ||||||||||||
1362 | destStore, // Format_RGB666 | - | ||||||||||||
1363 | destStore, // Format_ARGB6666_Premultiplied | - | ||||||||||||
1364 | destStore, // Format_RGB555 | - | ||||||||||||
1365 | destStore, // Format_ARGB8555_Premultiplied | - | ||||||||||||
1366 | destStore, // Format_RGB888 | - | ||||||||||||
1367 | destStore, // Format_RGB444 | - | ||||||||||||
1368 | destStore, // Format_ARGB4444_Premultiplied | - | ||||||||||||
1369 | destStore, // Format_RGBX8888 | - | ||||||||||||
1370 | destStore, // Format_RGBA8888 | - | ||||||||||||
1371 | destStore, // Format_RGBA8888_Premultiplied | - | ||||||||||||
1372 | destStore, // Format_BGR30 | - | ||||||||||||
1373 | destStore, // Format_A2BGR30_Premultiplied | - | ||||||||||||
1374 | destStore, // Format_RGB30 | - | ||||||||||||
1375 | destStore, // Format_A2RGB30_Premultiplied | - | ||||||||||||
1376 | destStore, // Format_Alpha8 | - | ||||||||||||
1377 | destStore, // Format_Grayscale8 | - | ||||||||||||
1378 | }; | - | ||||||||||||
1379 | - | |||||||||||||
1380 | static DestStoreProc64 destStoreProc64[QImage::NImageFormats] = | - | ||||||||||||
1381 | { | - | ||||||||||||
1382 | 0, // Format_Invalid | - | ||||||||||||
1383 | destStore64, // Format_Mono, | - | ||||||||||||
1384 | destStore64, // Format_MonoLSB | - | ||||||||||||
1385 | 0, // Format_Indexed8 | - | ||||||||||||
1386 | destStore64, // Format_RGB32 | - | ||||||||||||
1387 | destStore64ARGB32, // Format_ARGB32, | - | ||||||||||||
1388 | destStore64, // Format_ARGB32_Premultiplied | - | ||||||||||||
1389 | destStore64, // Format_RGB16 | - | ||||||||||||
1390 | destStore64, // Format_ARGB8565_Premultiplied | - | ||||||||||||
1391 | destStore64, // Format_RGB666 | - | ||||||||||||
1392 | destStore64, // Format_ARGB6666_Premultiplied | - | ||||||||||||
1393 | destStore64, // Format_RGB555 | - | ||||||||||||
1394 | destStore64, // Format_ARGB8555_Premultiplied | - | ||||||||||||
1395 | destStore64, // Format_RGB888 | - | ||||||||||||
1396 | destStore64, // Format_RGB444 | - | ||||||||||||
1397 | destStore64, // Format_ARGB4444_Premultiplied | - | ||||||||||||
1398 | destStore64, // Format_RGBX8888 | - | ||||||||||||
1399 | destStore64RGBA8888, // Format_RGBA8888 | - | ||||||||||||
1400 | destStore64, // Format_RGBA8888_Premultiplied | - | ||||||||||||
1401 | destStore64RGB30<PixelOrderBGR>, // Format_BGR30 | - | ||||||||||||
1402 | destStore64RGB30<PixelOrderBGR>, // Format_A2BGR30_Premultiplied | - | ||||||||||||
1403 | destStore64RGB30<PixelOrderRGB>, // Format_RGB30 | - | ||||||||||||
1404 | destStore64RGB30<PixelOrderRGB>, // Format_A2RGB30_Premultiplied | - | ||||||||||||
1405 | destStore64, // Format_Alpha8 | - | ||||||||||||
1406 | destStore64, // Format_Grayscale8 | - | ||||||||||||
1407 | }; | - | ||||||||||||
1408 | - | |||||||||||||
1409 | /* | - | ||||||||||||
1410 | Source fetches | - | ||||||||||||
1411 | - | |||||||||||||
1412 | This is a bit more complicated, as we need several fetch routines for every surface type | - | ||||||||||||
1413 | - | |||||||||||||
1414 | We need 5 fetch methods per surface type: | - | ||||||||||||
1415 | untransformed | - | ||||||||||||
1416 | transformed (tiled and not tiled) | - | ||||||||||||
1417 | transformed bilinear (tiled and not tiled) | - | ||||||||||||
1418 | - | |||||||||||||
1419 | We don't need bounds checks for untransformed, but we need them for the other ones. | - | ||||||||||||
1420 | - | |||||||||||||
1421 | The generic implementation does pixel by pixel fetches | - | ||||||||||||
1422 | */ | - | ||||||||||||
1423 | - | |||||||||||||
1424 | enum TextureBlendType { | - | ||||||||||||
1425 | BlendUntransformed, | - | ||||||||||||
1426 | BlendTiled, | - | ||||||||||||
1427 | BlendTransformed, | - | ||||||||||||
1428 | BlendTransformedTiled, | - | ||||||||||||
1429 | BlendTransformedBilinear, | - | ||||||||||||
1430 | BlendTransformedBilinearTiled, | - | ||||||||||||
1431 | NBlendTypes | - | ||||||||||||
1432 | }; | - | ||||||||||||
1433 | - | |||||||||||||
1434 | static const uint *QT_FASTCALL fetchUntransformed(uint *buffer, const Operator *, | - | ||||||||||||
1435 | const QSpanData *data, int y, int x, int length) | - | ||||||||||||
1436 | { | - | ||||||||||||
1437 | const QPixelLayout *layout = &qPixelLayouts[data->texture.format]; | - | ||||||||||||
1438 | const uint *ptr = qFetchPixels[layout->bpp](buffer, data->texture.scanLine(y), x, length); | - | ||||||||||||
1439 | const QRgb *clut = data->texture.colorTable ? data->texture.colorTable->constData() : 0;
| 0 | ||||||||||||
1440 | return layout->convertToARGB32PM(buffer, ptr, length, layout, clut); never executed: return layout->convertToARGB32PM(buffer, ptr, length, layout, clut); | 0 | ||||||||||||
1441 | } | - | ||||||||||||
1442 | - | |||||||||||||
1443 | static const uint *QT_FASTCALL fetchUntransformedARGB32PM(uint *, const Operator *, | - | ||||||||||||
1444 | const QSpanData *data, int y, int x, int) | - | ||||||||||||
1445 | { | - | ||||||||||||
1446 | const uchar *scanLine = data->texture.scanLine(y); | - | ||||||||||||
1447 | return ((const uint *)scanLine) + x; never executed: return ((const uint *)scanLine) + x; | 0 | ||||||||||||
1448 | } | - | ||||||||||||
1449 | - | |||||||||||||
1450 | static const uint *QT_FASTCALL fetchUntransformedRGB16(uint *buffer, const Operator *, | - | ||||||||||||
1451 | const QSpanData *data, int y, int x, | - | ||||||||||||
1452 | int length) | - | ||||||||||||
1453 | { | - | ||||||||||||
1454 | const quint16 *scanLine = (const quint16 *)data->texture.scanLine(y) + x; | - | ||||||||||||
1455 | #ifdef QT_COMPILER_SUPPORTS_MIPS_DSPR2 | - | ||||||||||||
1456 | qConvertRgb16To32_asm_mips_dspr2(buffer, scanLine, length); | - | ||||||||||||
1457 | #else | - | ||||||||||||
1458 | for (int i = 0; i < length; ++i)
| 0 | ||||||||||||
1459 | buffer[i] = qConvertRgb16To32(scanLine[i]); never executed: buffer[i] = qConvertRgb16To32(scanLine[i]); | 0 | ||||||||||||
1460 | #endif | - | ||||||||||||
1461 | return buffer; never executed: return buffer; | 0 | ||||||||||||
1462 | } | - | ||||||||||||
1463 | - | |||||||||||||
1464 | static const QRgba64 *QT_FASTCALL fetchUntransformed64(QRgba64 *buffer, const Operator *, | - | ||||||||||||
1465 | const QSpanData *data, int y, int x, int length) | - | ||||||||||||
1466 | { | - | ||||||||||||
1467 | const QPixelLayout *layout = &qPixelLayouts[data->texture.format]; | - | ||||||||||||
1468 | const QRgb *clut = data->texture.colorTable ? data->texture.colorTable->constData() : 0;
| 0 | ||||||||||||
1469 | if (layout->bpp != QPixelLayout::BPP32) {
| 0 | ||||||||||||
1470 | uint buffer32[buffer_size]; | - | ||||||||||||
1471 | const uint *ptr = qFetchPixels[layout->bpp](buffer32, data->texture.scanLine(y), x, length); | - | ||||||||||||
1472 | return layout->convertToARGB64PM(buffer, ptr, length, layout, clut); never executed: return layout->convertToARGB64PM(buffer, ptr, length, layout, clut); | 0 | ||||||||||||
1473 | } else { | - | ||||||||||||
1474 | const uint *src = (const uint *)data->texture.scanLine(y) + x; | - | ||||||||||||
1475 | return layout->convertToARGB64PM(buffer, src, length, layout, clut); never executed: return layout->convertToARGB64PM(buffer, src, length, layout, clut); | 0 | ||||||||||||
1476 | } | - | ||||||||||||
1477 | } | - | ||||||||||||
1478 | - | |||||||||||||
1479 | // blendType is either BlendTransformed or BlendTransformedTiled | - | ||||||||||||
1480 | template<TextureBlendType blendType> | - | ||||||||||||
1481 | static const uint *QT_FASTCALL fetchTransformedARGB32PM(uint *buffer, const Operator *, const QSpanData *data, | - | ||||||||||||
1482 | int y, int x, int length) | - | ||||||||||||
1483 | { | - | ||||||||||||
1484 | int image_width = data->texture.width; | - | ||||||||||||
1485 | int image_height = data->texture.height; | - | ||||||||||||
1486 | - | |||||||||||||
1487 | const qreal cx = x + qreal(0.5); | - | ||||||||||||
1488 | const qreal cy = y + qreal(0.5); | - | ||||||||||||
1489 | - | |||||||||||||
1490 | const uint *end = buffer + length; | - | ||||||||||||
1491 | uint *b = buffer; | - | ||||||||||||
1492 | if (data->fast_matrix) {
| 0 | ||||||||||||
1493 | // The increment pr x in the scanline | - | ||||||||||||
1494 | int fdx = (int)(data->m11 * fixed_scale); | - | ||||||||||||
1495 | int fdy = (int)(data->m12 * fixed_scale); | - | ||||||||||||
1496 | - | |||||||||||||
1497 | int fx = int((data->m21 * cy | - | ||||||||||||
1498 | + data->m11 * cx + data->dx) * fixed_scale); | - | ||||||||||||
1499 | int fy = int((data->m22 * cy | - | ||||||||||||
1500 | + data->m12 * cx + data->dy) * fixed_scale); | - | ||||||||||||
1501 | - | |||||||||||||
1502 | while (b < end) {
| 0 | ||||||||||||
1503 | int px = fx >> 16; | - | ||||||||||||
1504 | int py = fy >> 16; | - | ||||||||||||
1505 | - | |||||||||||||
1506 | if (blendType == BlendTransformedTiled) {
| 0 | ||||||||||||
1507 | px %= image_width; | - | ||||||||||||
1508 | py %= image_height; | - | ||||||||||||
1509 | if (px < 0) px += image_width; never executed: px += image_width;
| 0 | ||||||||||||
1510 | if (py < 0) py += image_height; never executed: py += image_height;
| 0 | ||||||||||||
1511 | } else { never executed: end of block | 0 | ||||||||||||
1512 | px = qBound(0, px, image_width - 1); | - | ||||||||||||
1513 | py = qBound(0, py, image_height - 1); | - | ||||||||||||
1514 | } never executed: end of block | 0 | ||||||||||||
1515 | *b = reinterpret_cast<const uint *>(data->texture.scanLine(py))[px]; | - | ||||||||||||
1516 | - | |||||||||||||
1517 | fx += fdx; | - | ||||||||||||
1518 | fy += fdy; | - | ||||||||||||
1519 | ++b; | - | ||||||||||||
1520 | } never executed: end of block | 0 | ||||||||||||
1521 | } else { never executed: end of block | 0 | ||||||||||||
1522 | const qreal fdx = data->m11; | - | ||||||||||||
1523 | const qreal fdy = data->m12; | - | ||||||||||||
1524 | const qreal fdw = data->m13; | - | ||||||||||||
1525 | - | |||||||||||||
1526 | qreal fx = data->m21 * cy + data->m11 * cx + data->dx; | - | ||||||||||||
1527 | qreal fy = data->m22 * cy + data->m12 * cx + data->dy; | - | ||||||||||||
1528 | qreal fw = data->m23 * cy + data->m13 * cx + data->m33; | - | ||||||||||||
1529 | - | |||||||||||||
1530 | while (b < end) {
| 0 | ||||||||||||
1531 | const qreal iw = fw == 0 ? 1 : 1 / fw; | - | ||||||||||||
1532 | const qreal tx = fx * iw; | - | ||||||||||||
1533 | const qreal ty = fy * iw; | - | ||||||||||||
1534 | int px = int(tx) - (tx < 0); | - | ||||||||||||
1535 | int py = int(ty) - (ty < 0); | - | ||||||||||||
1536 | - | |||||||||||||
1537 | if (blendType == BlendTransformedTiled) {
| 0 | ||||||||||||
1538 | px %= image_width; | - | ||||||||||||
1539 | py %= image_height; | - | ||||||||||||
1540 | if (px < 0) px += image_width; never executed: px += image_width;
| 0 | ||||||||||||
1541 | if (py < 0) py += image_height; never executed: py += image_height;
| 0 | ||||||||||||
1542 | } else { never executed: end of block | 0 | ||||||||||||
1543 | px = qBound(0, px, image_width - 1); | - | ||||||||||||
1544 | py = qBound(0, py, image_height - 1); | - | ||||||||||||
1545 | } never executed: end of block | 0 | ||||||||||||
1546 | *b = reinterpret_cast<const uint *>(data->texture.scanLine(py))[px]; | - | ||||||||||||
1547 | - | |||||||||||||
1548 | fx += fdx; | - | ||||||||||||
1549 | fy += fdy; | - | ||||||||||||
1550 | fw += fdw; | - | ||||||||||||
1551 | //force increment to avoid /0 | - | ||||||||||||
1552 | if (!fw) {
| 0 | ||||||||||||
1553 | fw += fdw; | - | ||||||||||||
1554 | } never executed: end of block | 0 | ||||||||||||
1555 | ++b; | - | ||||||||||||
1556 | } never executed: end of block | 0 | ||||||||||||
1557 | } never executed: end of block | 0 | ||||||||||||
1558 | return buffer; never executed: return buffer; | 0 | ||||||||||||
1559 | } | - | ||||||||||||
1560 | - | |||||||||||||
1561 | template<TextureBlendType blendType> /* either BlendTransformed or BlendTransformedTiled */ | - | ||||||||||||
1562 | static const uint *QT_FASTCALL fetchTransformed(uint *buffer, const Operator *, const QSpanData *data, | - | ||||||||||||
1563 | int y, int x, int length) | - | ||||||||||||
1564 | { | - | ||||||||||||
1565 | int image_width = data->texture.width; | - | ||||||||||||
1566 | int image_height = data->texture.height; | - | ||||||||||||
1567 | - | |||||||||||||
1568 | const qreal cx = x + qreal(0.5); | - | ||||||||||||
1569 | const qreal cy = y + qreal(0.5); | - | ||||||||||||
1570 | - | |||||||||||||
1571 | const QPixelLayout *layout = &qPixelLayouts[data->texture.format]; | - | ||||||||||||
1572 | FetchPixelFunc fetch = qFetchPixel[layout->bpp]; | - | ||||||||||||
1573 | - | |||||||||||||
1574 | const uint *end = buffer + length; | - | ||||||||||||
1575 | uint *b = buffer; | - | ||||||||||||
1576 | if (data->fast_matrix) {
| 0 | ||||||||||||
1577 | // The increment pr x in the scanline | - | ||||||||||||
1578 | int fdx = (int)(data->m11 * fixed_scale); | - | ||||||||||||
1579 | int fdy = (int)(data->m12 * fixed_scale); | - | ||||||||||||
1580 | - | |||||||||||||
1581 | int fx = int((data->m21 * cy | - | ||||||||||||
1582 | + data->m11 * cx + data->dx) * fixed_scale); | - | ||||||||||||
1583 | int fy = int((data->m22 * cy | - | ||||||||||||
1584 | + data->m12 * cx + data->dy) * fixed_scale); | - | ||||||||||||
1585 | - | |||||||||||||
1586 | while (b < end) {
| 0 | ||||||||||||
1587 | int px = fx >> 16; | - | ||||||||||||
1588 | int py = fy >> 16; | - | ||||||||||||
1589 | - | |||||||||||||
1590 | if (blendType == BlendTransformedTiled) {
| 0 | ||||||||||||
1591 | px %= image_width; | - | ||||||||||||
1592 | py %= image_height; | - | ||||||||||||
1593 | if (px < 0) px += image_width; never executed: px += image_width;
| 0 | ||||||||||||
1594 | if (py < 0) py += image_height; never executed: py += image_height;
| 0 | ||||||||||||
1595 | } else { never executed: end of block | 0 | ||||||||||||
1596 | px = qBound(0, px, image_width - 1); | - | ||||||||||||
1597 | py = qBound(0, py, image_height - 1); | - | ||||||||||||
1598 | } never executed: end of block | 0 | ||||||||||||
1599 | *b = fetch(data->texture.scanLine(py), px); | - | ||||||||||||
1600 | - | |||||||||||||
1601 | fx += fdx; | - | ||||||||||||
1602 | fy += fdy; | - | ||||||||||||
1603 | ++b; | - | ||||||||||||
1604 | } never executed: end of block | 0 | ||||||||||||
1605 | } else { never executed: end of block | 0 | ||||||||||||
1606 | const qreal fdx = data->m11; | - | ||||||||||||
1607 | const qreal fdy = data->m12; | - | ||||||||||||
1608 | const qreal fdw = data->m13; | - | ||||||||||||
1609 | - | |||||||||||||
1610 | qreal fx = data->m21 * cy + data->m11 * cx + data->dx; | - | ||||||||||||
1611 | qreal fy = data->m22 * cy + data->m12 * cx + data->dy; | - | ||||||||||||
1612 | qreal fw = data->m23 * cy + data->m13 * cx + data->m33; | - | ||||||||||||
1613 | - | |||||||||||||
1614 | while (b < end) {
| 0 | ||||||||||||
1615 | const qreal iw = fw == 0 ? 1 : 1 / fw; | - | ||||||||||||
1616 | const qreal tx = fx * iw; | - | ||||||||||||
1617 | const qreal ty = fy * iw; | - | ||||||||||||
1618 | int px = int(tx) - (tx < 0); | - | ||||||||||||
1619 | int py = int(ty) - (ty < 0); | - | ||||||||||||
1620 | - | |||||||||||||
1621 | if (blendType == BlendTransformedTiled) {
| 0 | ||||||||||||
1622 | px %= image_width; | - | ||||||||||||
1623 | py %= image_height; | - | ||||||||||||
1624 | if (px < 0) px += image_width; never executed: px += image_width;
| 0 | ||||||||||||
1625 | if (py < 0) py += image_height; never executed: py += image_height;
| 0 | ||||||||||||
1626 | } else { never executed: end of block | 0 | ||||||||||||
1627 | px = qBound(0, px, image_width - 1); | - | ||||||||||||
1628 | py = qBound(0, py, image_height - 1); | - | ||||||||||||
1629 | } never executed: end of block | 0 | ||||||||||||
1630 | *b = fetch(data->texture.scanLine(py), px); | - | ||||||||||||
1631 | - | |||||||||||||
1632 | fx += fdx; | - | ||||||||||||
1633 | fy += fdy; | - | ||||||||||||
1634 | fw += fdw; | - | ||||||||||||
1635 | //force increment to avoid /0 | - | ||||||||||||
1636 | if (!fw) {
| 0 | ||||||||||||
1637 | fw += fdw; | - | ||||||||||||
1638 | } never executed: end of block | 0 | ||||||||||||
1639 | ++b; | - | ||||||||||||
1640 | } never executed: end of block | 0 | ||||||||||||
1641 | } never executed: end of block | 0 | ||||||||||||
1642 | const QRgb *clut = data->texture.colorTable ? data->texture.colorTable->constData() : 0; | - | ||||||||||||
1643 | return layout->convertToARGB32PM(buffer, buffer, length, layout, clut); never executed: return layout->convertToARGB32PM(buffer, buffer, length, layout, clut); | 0 | ||||||||||||
1644 | } | - | ||||||||||||
1645 | - | |||||||||||||
1646 | template<TextureBlendType blendType> /* either BlendTransformed or BlendTransformedTiled */ | - | ||||||||||||
1647 | static const QRgba64 *QT_FASTCALL fetchTransformed64(QRgba64 *buffer, const Operator *, const QSpanData *data, | - | ||||||||||||
1648 | int y, int x, int length) | - | ||||||||||||
1649 | { | - | ||||||||||||
1650 | int image_width = data->texture.width; | - | ||||||||||||
1651 | int image_height = data->texture.height; | - | ||||||||||||
1652 | - | |||||||||||||
1653 | const qreal cx = x + qreal(0.5); | - | ||||||||||||
1654 | const qreal cy = y + qreal(0.5); | - | ||||||||||||
1655 | - | |||||||||||||
1656 | const QPixelLayout *layout = &qPixelLayouts[data->texture.format]; | - | ||||||||||||
1657 | FetchPixelFunc fetch = qFetchPixel[layout->bpp]; | - | ||||||||||||
1658 | const QRgb *clut = data->texture.colorTable ? data->texture.colorTable->constData() : 0; | - | ||||||||||||
1659 | - | |||||||||||||
1660 | uint buffer32[buffer_size]; | - | ||||||||||||
1661 | QRgba64 *b = buffer; | - | ||||||||||||
1662 | if (data->fast_matrix) {
| 0 | ||||||||||||
1663 | // The increment pr x in the scanline | - | ||||||||||||
1664 | int fdx = (int)(data->m11 * fixed_scale); | - | ||||||||||||
1665 | int fdy = (int)(data->m12 * fixed_scale); | - | ||||||||||||
1666 | - | |||||||||||||
1667 | int fx = int((data->m21 * cy | - | ||||||||||||
1668 | + data->m11 * cx + data->dx) * fixed_scale); | - | ||||||||||||
1669 | int fy = int((data->m22 * cy | - | ||||||||||||
1670 | + data->m12 * cx + data->dy) * fixed_scale); | - | ||||||||||||
1671 | - | |||||||||||||
1672 | int i = 0, j = 0; | - | ||||||||||||
1673 | while (i < length) {
| 0 | ||||||||||||
1674 | if (j == buffer_size) {
| 0 | ||||||||||||
1675 | layout->convertToARGB64PM(b, buffer32, buffer_size, layout, clut); | - | ||||||||||||
1676 | b += buffer_size; | - | ||||||||||||
1677 | j = 0; | - | ||||||||||||
1678 | } never executed: end of block | 0 | ||||||||||||
1679 | int px = fx >> 16; | - | ||||||||||||
1680 | int py = fy >> 16; | - | ||||||||||||
1681 | - | |||||||||||||
1682 | if (blendType == BlendTransformedTiled) {
| 0 | ||||||||||||
1683 | px %= image_width; | - | ||||||||||||
1684 | py %= image_height; | - | ||||||||||||
1685 | if (px < 0) px += image_width; never executed: px += image_width;
| 0 | ||||||||||||
1686 | if (py < 0) py += image_height; never executed: py += image_height;
| 0 | ||||||||||||
1687 | } else { never executed: end of block | 0 | ||||||||||||
1688 | px = qBound(0, px, image_width - 1); | - | ||||||||||||
1689 | py = qBound(0, py, image_height - 1); | - | ||||||||||||
1690 | } never executed: end of block | 0 | ||||||||||||
1691 | buffer32[j] = fetch(data->texture.scanLine(py), px); | - | ||||||||||||
1692 | - | |||||||||||||
1693 | fx += fdx; | - | ||||||||||||
1694 | fy += fdy; | - | ||||||||||||
1695 | ++i; ++j; | - | ||||||||||||
1696 | } never executed: end of block | 0 | ||||||||||||
1697 | if (j > 0) {
| 0 | ||||||||||||
1698 | layout->convertToARGB64PM(b, buffer32, j, layout, clut); | - | ||||||||||||
1699 | b += j; | - | ||||||||||||
1700 | } never executed: end of block | 0 | ||||||||||||
1701 | } else { never executed: end of block | 0 | ||||||||||||
1702 | const qreal fdx = data->m11; | - | ||||||||||||
1703 | const qreal fdy = data->m12; | - | ||||||||||||
1704 | const qreal fdw = data->m13; | - | ||||||||||||
1705 | - | |||||||||||||
1706 | qreal fx = data->m21 * cy + data->m11 * cx + data->dx; | - | ||||||||||||
1707 | qreal fy = data->m22 * cy + data->m12 * cx + data->dy; | - | ||||||||||||
1708 | qreal fw = data->m23 * cy + data->m13 * cx + data->m33; | - | ||||||||||||
1709 | - | |||||||||||||
1710 | int i = 0, j = 0; | - | ||||||||||||
1711 | while (i < length) {
| 0 | ||||||||||||
1712 | if (j == buffer_size) {
| 0 | ||||||||||||
1713 | layout->convertToARGB64PM(b, buffer32, buffer_size, layout, clut); | - | ||||||||||||
1714 | b += buffer_size; | - | ||||||||||||
1715 | j = 0; | - | ||||||||||||
1716 | } never executed: end of block | 0 | ||||||||||||
1717 | const qreal iw = fw == 0 ? 1 : 1 / fw; | - | ||||||||||||
1718 | const qreal tx = fx * iw; | - | ||||||||||||
1719 | const qreal ty = fy * iw; | - | ||||||||||||
1720 | int px = int(tx) - (tx < 0); | - | ||||||||||||
1721 | int py = int(ty) - (ty < 0); | - | ||||||||||||
1722 | - | |||||||||||||
1723 | if (blendType == BlendTransformedTiled) {
| 0 | ||||||||||||
1724 | px %= image_width; | - | ||||||||||||
1725 | py %= image_height; | - | ||||||||||||
1726 | if (px < 0) px += image_width; never executed: px += image_width;
| 0 | ||||||||||||
1727 | if (py < 0) py += image_height; never executed: py += image_height;
| 0 | ||||||||||||
1728 | } else { never executed: end of block | 0 | ||||||||||||
1729 | px = qBound(0, px, image_width - 1); | - | ||||||||||||
1730 | py = qBound(0, py, image_height - 1); | - | ||||||||||||
1731 | } never executed: end of block | 0 | ||||||||||||
1732 | buffer32[j] = fetch(data->texture.scanLine(py), px); | - | ||||||||||||
1733 | - | |||||||||||||
1734 | fx += fdx; | - | ||||||||||||
1735 | fy += fdy; | - | ||||||||||||
1736 | fw += fdw; | - | ||||||||||||
1737 | //force increment to avoid /0 | - | ||||||||||||
1738 | if (!fw) {
| 0 | ||||||||||||
1739 | fw += fdw; | - | ||||||||||||
1740 | } never executed: end of block | 0 | ||||||||||||
1741 | ++i; ++j; | - | ||||||||||||
1742 | } never executed: end of block | 0 | ||||||||||||
1743 | if (j > 0) {
| 0 | ||||||||||||
1744 | layout->convertToARGB64PM(b, buffer32, j, layout, clut); | - | ||||||||||||
1745 | b += j; | - | ||||||||||||
1746 | } never executed: end of block | 0 | ||||||||||||
1747 | } never executed: end of block | 0 | ||||||||||||
1748 | return buffer; never executed: return buffer; | 0 | ||||||||||||
1749 | } | - | ||||||||||||
1750 | - | |||||||||||||
1751 | /** \internal | - | ||||||||||||
1752 | interpolate 4 argb pixels with the distx and disty factor. | - | ||||||||||||
1753 | distx and disty bust be between 0 and 16 | - | ||||||||||||
1754 | */ | - | ||||||||||||
1755 | static inline uint interpolate_4_pixels_16(uint tl, uint tr, uint bl, uint br, int distx, int disty) | - | ||||||||||||
1756 | { | - | ||||||||||||
1757 | uint distxy = distx * disty; | - | ||||||||||||
1758 | //idistx * disty = (16-distx) * disty = 16*disty - distxy | - | ||||||||||||
1759 | //idistx * idisty = (16-distx) * (16-disty) = 16*16 - 16*distx -16*disty + distxy | - | ||||||||||||
1760 | uint tlrb = (tl & 0x00ff00ff) * (16*16 - 16*distx - 16*disty + distxy); | - | ||||||||||||
1761 | uint tlag = ((tl & 0xff00ff00) >> 8) * (16*16 - 16*distx - 16*disty + distxy); | - | ||||||||||||
1762 | uint trrb = ((tr & 0x00ff00ff) * (distx*16 - distxy)); | - | ||||||||||||
1763 | uint trag = (((tr & 0xff00ff00) >> 8) * (distx*16 - distxy)); | - | ||||||||||||
1764 | uint blrb = ((bl & 0x00ff00ff) * (disty*16 - distxy)); | - | ||||||||||||
1765 | uint blag = (((bl & 0xff00ff00) >> 8) * (disty*16 - distxy)); | - | ||||||||||||
1766 | uint brrb = ((br & 0x00ff00ff) * (distxy)); | - | ||||||||||||
1767 | uint brag = (((br & 0xff00ff00) >> 8) * (distxy)); | - | ||||||||||||
1768 | return (((tlrb + trrb + blrb + brrb) >> 8) & 0x00ff00ff) | ((tlag + trag + blag + brag) & 0xff00ff00); never executed: return (((tlrb + trrb + blrb + brrb) >> 8) & 0x00ff00ff) | ((tlag + trag + blag + brag) & 0xff00ff00); | 0 | ||||||||||||
1769 | } | - | ||||||||||||
1770 | - | |||||||||||||
1771 | #if defined(__SSE2__) | - | ||||||||||||
1772 | #define interpolate_4_pixels_16_sse2(tl, tr, bl, br, distx, disty, colorMask, v_256, b) \ | - | ||||||||||||
1773 | { \ | - | ||||||||||||
1774 | const __m128i dxdy = _mm_mullo_epi16 (distx, disty); \ | - | ||||||||||||
1775 | const __m128i distx_ = _mm_slli_epi16(distx, 4); \ | - | ||||||||||||
1776 | const __m128i disty_ = _mm_slli_epi16(disty, 4); \ | - | ||||||||||||
1777 | const __m128i idxidy = _mm_add_epi16(dxdy, _mm_sub_epi16(v_256, _mm_add_epi16(distx_, disty_))); \ | - | ||||||||||||
1778 | const __m128i dxidy = _mm_sub_epi16(distx_, dxdy); \ | - | ||||||||||||
1779 | const __m128i idxdy = _mm_sub_epi16(disty_, dxdy); \ | - | ||||||||||||
1780 | \ | - | ||||||||||||
1781 | __m128i tlAG = _mm_srli_epi16(tl, 8); \ | - | ||||||||||||
1782 | __m128i tlRB = _mm_and_si128(tl, colorMask); \ | - | ||||||||||||
1783 | __m128i trAG = _mm_srli_epi16(tr, 8); \ | - | ||||||||||||
1784 | __m128i trRB = _mm_and_si128(tr, colorMask); \ | - | ||||||||||||
1785 | __m128i blAG = _mm_srli_epi16(bl, 8); \ | - | ||||||||||||
1786 | __m128i blRB = _mm_and_si128(bl, colorMask); \ | - | ||||||||||||
1787 | __m128i brAG = _mm_srli_epi16(br, 8); \ | - | ||||||||||||
1788 | __m128i brRB = _mm_and_si128(br, colorMask); \ | - | ||||||||||||
1789 | \ | - | ||||||||||||
1790 | tlAG = _mm_mullo_epi16(tlAG, idxidy); \ | - | ||||||||||||
1791 | tlRB = _mm_mullo_epi16(tlRB, idxidy); \ | - | ||||||||||||
1792 | trAG = _mm_mullo_epi16(trAG, dxidy); \ | - | ||||||||||||
1793 | trRB = _mm_mullo_epi16(trRB, dxidy); \ | - | ||||||||||||
1794 | blAG = _mm_mullo_epi16(blAG, idxdy); \ | - | ||||||||||||
1795 | blRB = _mm_mullo_epi16(blRB, idxdy); \ | - | ||||||||||||
1796 | brAG = _mm_mullo_epi16(brAG, dxdy); \ | - | ||||||||||||
1797 | brRB = _mm_mullo_epi16(brRB, dxdy); \ | - | ||||||||||||
1798 | \ | - | ||||||||||||
1799 | /* Add the values, and shift to only keep 8 significant bits per colors */ \ | - | ||||||||||||
1800 | __m128i rAG =_mm_add_epi16(_mm_add_epi16(tlAG, trAG), _mm_add_epi16(blAG, brAG)); \ | - | ||||||||||||
1801 | __m128i rRB =_mm_add_epi16(_mm_add_epi16(tlRB, trRB), _mm_add_epi16(blRB, brRB)); \ | - | ||||||||||||
1802 | rAG = _mm_andnot_si128(colorMask, rAG); \ | - | ||||||||||||
1803 | rRB = _mm_srli_epi16(rRB, 8); \ | - | ||||||||||||
1804 | _mm_storeu_si128((__m128i*)(b), _mm_or_si128(rAG, rRB)); \ | - | ||||||||||||
1805 | } | - | ||||||||||||
1806 | #endif | - | ||||||||||||
1807 | - | |||||||||||||
1808 | #if defined(__ARM_NEON__) | - | ||||||||||||
1809 | #define interpolate_4_pixels_16_neon(tl, tr, bl, br, distx, disty, disty_, colorMask, invColorMask, v_256, b) \ | - | ||||||||||||
1810 | { \ | - | ||||||||||||
1811 | const int16x8_t dxdy = vmulq_s16(distx, disty); \ | - | ||||||||||||
1812 | const int16x8_t distx_ = vshlq_n_s16(distx, 4); \ | - | ||||||||||||
1813 | const int16x8_t idxidy = vaddq_s16(dxdy, vsubq_s16(v_256, vaddq_s16(distx_, disty_))); \ | - | ||||||||||||
1814 | const int16x8_t dxidy = vsubq_s16(distx_, dxdy); \ | - | ||||||||||||
1815 | const int16x8_t idxdy = vsubq_s16(disty_, dxdy); \ | - | ||||||||||||
1816 | \ | - | ||||||||||||
1817 | int16x8_t tlAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(tl), 8)); \ | - | ||||||||||||
1818 | int16x8_t tlRB = vandq_s16(tl, colorMask); \ | - | ||||||||||||
1819 | int16x8_t trAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(tr), 8)); \ | - | ||||||||||||
1820 | int16x8_t trRB = vandq_s16(tr, colorMask); \ | - | ||||||||||||
1821 | int16x8_t blAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(bl), 8)); \ | - | ||||||||||||
1822 | int16x8_t blRB = vandq_s16(bl, colorMask); \ | - | ||||||||||||
1823 | int16x8_t brAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(br), 8)); \ | - | ||||||||||||
1824 | int16x8_t brRB = vandq_s16(br, colorMask); \ | - | ||||||||||||
1825 | \ | - | ||||||||||||
1826 | int16x8_t rAG = vmulq_s16(tlAG, idxidy); \ | - | ||||||||||||
1827 | int16x8_t rRB = vmulq_s16(tlRB, idxidy); \ | - | ||||||||||||
1828 | rAG = vmlaq_s16(rAG, trAG, dxidy); \ | - | ||||||||||||
1829 | rRB = vmlaq_s16(rRB, trRB, dxidy); \ | - | ||||||||||||
1830 | rAG = vmlaq_s16(rAG, blAG, idxdy); \ | - | ||||||||||||
1831 | rRB = vmlaq_s16(rRB, blRB, idxdy); \ | - | ||||||||||||
1832 | rAG = vmlaq_s16(rAG, brAG, dxdy); \ | - | ||||||||||||
1833 | rRB = vmlaq_s16(rRB, brRB, dxdy); \ | - | ||||||||||||
1834 | \ | - | ||||||||||||
1835 | rAG = vandq_s16(invColorMask, rAG); \ | - | ||||||||||||
1836 | rRB = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(rRB), 8)); \ | - | ||||||||||||
1837 | vst1q_s16((int16_t*)(b), vorrq_s16(rAG, rRB)); \ | - | ||||||||||||
1838 | } | - | ||||||||||||
1839 | #endif | - | ||||||||||||
1840 | - | |||||||||||||
1841 | #if defined(__SSE2__) | - | ||||||||||||
1842 | static inline QRgba64 interpolate_4_pixels_rgb64(QRgba64 t[], QRgba64 b[], uint distx, uint disty) | - | ||||||||||||
1843 | { | - | ||||||||||||
1844 | const __m128i vdistx = _mm_shufflelo_epi16(_mm_cvtsi32_si128(distx), _MM_SHUFFLE(0, 0, 0, 0)); | - | ||||||||||||
1845 | const __m128i vidistx = _mm_shufflelo_epi16(_mm_cvtsi32_si128(0x10000 - distx), _MM_SHUFFLE(0, 0, 0, 0)); | - | ||||||||||||
1846 | - | |||||||||||||
1847 | __m128i vt = _mm_loadu_si128((const __m128i*)t); | - | ||||||||||||
1848 | if (disty) {
| 0 | ||||||||||||
1849 | __m128i vb = _mm_loadu_si128((const __m128i*)b); | - | ||||||||||||
1850 | vt = _mm_mulhi_epu16(vt, _mm_set1_epi16(0x10000 - disty)); | - | ||||||||||||
1851 | vb = _mm_mulhi_epu16(vb, _mm_set1_epi16(disty)); | - | ||||||||||||
1852 | vt = _mm_add_epi16(vt, vb); | - | ||||||||||||
1853 | } never executed: end of block | 0 | ||||||||||||
1854 | vt = _mm_mulhi_epu16(vt, _mm_unpacklo_epi64(vidistx, vdistx)); | - | ||||||||||||
1855 | vt = _mm_add_epi16(vt, _mm_srli_si128(vt, 8)); | - | ||||||||||||
1856 | #ifdef Q_PROCESSOR_X86_64 | - | ||||||||||||
1857 | return QRgba64::fromRgba64(_mm_cvtsi128_si64(vt)); never executed: return QRgba64::fromRgba64(_mm_cvtsi128_si64(vt)); | 0 | ||||||||||||
1858 | #else | - | ||||||||||||
1859 | QRgba64 out; | - | ||||||||||||
1860 | _mm_storel_epi64((__m128i*)&out, vt); | - | ||||||||||||
1861 | return out; | - | ||||||||||||
1862 | #endif | - | ||||||||||||
1863 | } | - | ||||||||||||
1864 | #else | - | ||||||||||||
1865 | static inline QRgba64 interpolate_4_pixels_rgb64(QRgba64 t[], QRgba64 b[], uint distx, uint disty) | - | ||||||||||||
1866 | { | - | ||||||||||||
1867 | const uint dx = distx>>8; | - | ||||||||||||
1868 | const uint dy = disty>>8; | - | ||||||||||||
1869 | const uint idx = 256 - dx; | - | ||||||||||||
1870 | const uint idy = 256 - dy; | - | ||||||||||||
1871 | QRgba64 xtop = interpolate256(t[0], idx, t[1], dx); | - | ||||||||||||
1872 | QRgba64 xbot = interpolate256(b[0], idx, b[1], dx); | - | ||||||||||||
1873 | return interpolate256(xtop, idy, xbot, dy); | - | ||||||||||||
1874 | } | - | ||||||||||||
1875 | #endif | - | ||||||||||||
1876 | - | |||||||||||||
1877 | template<TextureBlendType blendType> | - | ||||||||||||
1878 | void fetchTransformedBilinear_pixelBounds(int max, int l1, int l2, int &v1, int &v2); | - | ||||||||||||
1879 | - | |||||||||||||
1880 | template<> | - | ||||||||||||
1881 | inline void fetchTransformedBilinear_pixelBounds<BlendTransformedBilinearTiled>(int max, int, int, int &v1, int &v2) | - | ||||||||||||
1882 | { | - | ||||||||||||
1883 | v1 %= max; | - | ||||||||||||
1884 | if (v1 < 0)
| 0 | ||||||||||||
1885 | v1 += max; never executed: v1 += max; | 0 | ||||||||||||
1886 | v2 = v1 + 1; | - | ||||||||||||
1887 | if (v2 == max)
| 0 | ||||||||||||
1888 | v2 = 0; never executed: v2 = 0; | 0 | ||||||||||||
1889 | Q_ASSERT(v1 >= 0 && v1 < max); | - | ||||||||||||
1890 | Q_ASSERT(v2 >= 0 && v2 < max); | - | ||||||||||||
1891 | } never executed: end of block | 0 | ||||||||||||
1892 | - | |||||||||||||
1893 | template<> | - | ||||||||||||
1894 | inline void fetchTransformedBilinear_pixelBounds<BlendTransformedBilinear>(int, int l1, int l2, int &v1, int &v2) | - | ||||||||||||
1895 | { | - | ||||||||||||
1896 | if (v1 < l1)
| 0 | ||||||||||||
1897 | v2 = v1 = l1; never executed: v2 = v1 = l1; | 0 | ||||||||||||
1898 | else if (v1 >= l2)
| 0 | ||||||||||||
1899 | v2 = v1 = l2; never executed: v2 = v1 = l2; | 0 | ||||||||||||
1900 | else | - | ||||||||||||
1901 | v2 = v1 + 1; never executed: v2 = v1 + 1; | 0 | ||||||||||||
1902 | Q_ASSERT(v1 >= l1 && v1 <= l2); | - | ||||||||||||
1903 | Q_ASSERT(v2 >= l1 && v2 <= l2); | - | ||||||||||||
1904 | } never executed: end of block | 0 | ||||||||||||
1905 | - | |||||||||||||
1906 | template<TextureBlendType blendType> /* blendType = BlendTransformedBilinear or BlendTransformedBilinearTiled */ | - | ||||||||||||
1907 | static const uint * QT_FASTCALL fetchTransformedBilinearARGB32PM(uint *buffer, const Operator *, | - | ||||||||||||
1908 | const QSpanData *data, int y, int x, | - | ||||||||||||
1909 | int length) | - | ||||||||||||
1910 | { | - | ||||||||||||
1911 | int image_width = data->texture.width; | - | ||||||||||||
1912 | int image_height = data->texture.height; | - | ||||||||||||
1913 | - | |||||||||||||
1914 | int image_x1 = data->texture.x1; | - | ||||||||||||
1915 | int image_y1 = data->texture.y1; | - | ||||||||||||
1916 | int image_x2 = data->texture.x2 - 1; | - | ||||||||||||
1917 | int image_y2 = data->texture.y2 - 1; | - | ||||||||||||
1918 | - | |||||||||||||
1919 | const qreal cx = x + qreal(0.5); | - | ||||||||||||
1920 | const qreal cy = y + qreal(0.5); | - | ||||||||||||
1921 | - | |||||||||||||
1922 | uint *end = buffer + length; | - | ||||||||||||
1923 | uint *b = buffer; | - | ||||||||||||
1924 | if (data->fast_matrix) {
| 0 | ||||||||||||
1925 | // The increment pr x in the scanline | - | ||||||||||||
1926 | int fdx = (int)(data->m11 * fixed_scale); | - | ||||||||||||
1927 | int fdy = (int)(data->m12 * fixed_scale); | - | ||||||||||||
1928 | - | |||||||||||||
1929 | int fx = int((data->m21 * cy | - | ||||||||||||
1930 | + data->m11 * cx + data->dx) * fixed_scale); | - | ||||||||||||
1931 | int fy = int((data->m22 * cy | - | ||||||||||||
1932 | + data->m12 * cx + data->dy) * fixed_scale); | - | ||||||||||||
1933 | - | |||||||||||||
1934 | fx -= half_point; | - | ||||||||||||
1935 | fy -= half_point; | - | ||||||||||||
1936 | - | |||||||||||||
1937 | if (fdy == 0) { //simple scale, no rotation
| 0 | ||||||||||||
1938 | int y1 = (fy >> 16); | - | ||||||||||||
1939 | int y2; | - | ||||||||||||
1940 | fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2); | - | ||||||||||||
1941 | const uint *s1 = (const uint *)data->texture.scanLine(y1); | - | ||||||||||||
1942 | const uint *s2 = (const uint *)data->texture.scanLine(y2); | - | ||||||||||||
1943 | - | |||||||||||||
1944 | if (fdx <= fixed_scale && fdx > 0) { // scale up on X
| 0 | ||||||||||||
1945 | int disty = (fy & 0x0000ffff) >> 8; | - | ||||||||||||
1946 | int idisty = 256 - disty; | - | ||||||||||||
1947 | int x = fx >> 16; | - | ||||||||||||
1948 | - | |||||||||||||
1949 | // The idea is first to do the interpolation between the row s1 and the row s2 | - | ||||||||||||
1950 | // into an intermediate buffer, then we interpolate between two pixel of this buffer. | - | ||||||||||||
1951 | - | |||||||||||||
1952 | // intermediate_buffer[0] is a buffer of red-blue component of the pixel, in the form 0x00RR00BB | - | ||||||||||||
1953 | // intermediate_buffer[1] is the alpha-green component of the pixel, in the form 0x00AA00GG | - | ||||||||||||
1954 | // +1 for the last pixel to interpolate with, and +1 for rounding errors. | - | ||||||||||||
1955 | quint32 intermediate_buffer[2][buffer_size + 2]; | - | ||||||||||||
1956 | // count is the size used in the intermediate_buffer. | - | ||||||||||||
1957 | int count = (qint64(length) * fdx + fixed_scale - 1) / fixed_scale + 2; | - | ||||||||||||
1958 | Q_ASSERT(count <= buffer_size + 2); //length is supposed to be <= buffer_size and data->m11 < 1 in this case | - | ||||||||||||
1959 | int f = 0; | - | ||||||||||||
1960 | int lim = count; | - | ||||||||||||
1961 | if (blendType == BlendTransformedBilinearTiled) {
| 0 | ||||||||||||
1962 | x %= image_width; | - | ||||||||||||
1963 | if (x < 0) x += image_width; never executed: x += image_width;
| 0 | ||||||||||||
1964 | } else { never executed: end of block | 0 | ||||||||||||
1965 | lim = qMin(count, image_x2-x+1); | - | ||||||||||||
1966 | if (x < image_x1) {
| 0 | ||||||||||||
1967 | Q_ASSERT(x <= image_x2); | - | ||||||||||||
1968 | uint t = s1[image_x1]; | - | ||||||||||||
1969 | uint b = s2[image_x1]; | - | ||||||||||||
1970 | quint32 rb = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff; | - | ||||||||||||
1971 | quint32 ag = ((((t>>8) & 0xff00ff) * idisty + ((b>>8) & 0xff00ff) * disty) >> 8) & 0xff00ff; | - | ||||||||||||
1972 | do { | - | ||||||||||||
1973 | intermediate_buffer[0][f] = rb; | - | ||||||||||||
1974 | intermediate_buffer[1][f] = ag; | - | ||||||||||||
1975 | f++; | - | ||||||||||||
1976 | x++; | - | ||||||||||||
1977 | } while (x < image_x1 && f < lim); never executed: end of block
| 0 | ||||||||||||
1978 | } never executed: end of block | 0 | ||||||||||||
1979 | } never executed: end of block | 0 | ||||||||||||
1980 | - | |||||||||||||
1981 | if (blendType != BlendTransformedBilinearTiled) {
| 0 | ||||||||||||
1982 | #if defined(__SSE2__) | - | ||||||||||||
1983 | const __m128i disty_ = _mm_set1_epi16(disty); | - | ||||||||||||
1984 | const __m128i idisty_ = _mm_set1_epi16(idisty); | - | ||||||||||||
1985 | const __m128i colorMask = _mm_set1_epi32(0x00ff00ff); | - | ||||||||||||
1986 | - | |||||||||||||
1987 | lim -= 3; | - | ||||||||||||
1988 | for (; f < lim; x += 4, f += 4) {
| 0 | ||||||||||||
1989 | // Load 4 pixels from s1, and split the alpha-green and red-blue component | - | ||||||||||||
1990 | __m128i top = _mm_loadu_si128((const __m128i*)((const uint *)(s1)+x)); | - | ||||||||||||
1991 | __m128i topAG = _mm_srli_epi16(top, 8); | - | ||||||||||||
1992 | __m128i topRB = _mm_and_si128(top, colorMask); | - | ||||||||||||
1993 | // Multiplies each colour component by idisty | - | ||||||||||||
1994 | topAG = _mm_mullo_epi16 (topAG, idisty_); | - | ||||||||||||
1995 | topRB = _mm_mullo_epi16 (topRB, idisty_); | - | ||||||||||||
1996 | - | |||||||||||||
1997 | // Same for the s2 vector | - | ||||||||||||
1998 | __m128i bottom = _mm_loadu_si128((const __m128i*)((const uint *)(s2)+x)); | - | ||||||||||||
1999 | __m128i bottomAG = _mm_srli_epi16(bottom, 8); | - | ||||||||||||
2000 | __m128i bottomRB = _mm_and_si128(bottom, colorMask); | - | ||||||||||||
2001 | bottomAG = _mm_mullo_epi16 (bottomAG, disty_); | - | ||||||||||||
2002 | bottomRB = _mm_mullo_epi16 (bottomRB, disty_); | - | ||||||||||||
2003 | - | |||||||||||||
2004 | // Add the values, and shift to only keep 8 significant bits per colors | - | ||||||||||||
2005 | __m128i rAG =_mm_add_epi16(topAG, bottomAG); | - | ||||||||||||
2006 | rAG = _mm_srli_epi16(rAG, 8); | - | ||||||||||||
2007 | _mm_storeu_si128((__m128i*)(&intermediate_buffer[1][f]), rAG); | - | ||||||||||||
2008 | __m128i rRB =_mm_add_epi16(topRB, bottomRB); | - | ||||||||||||
2009 | rRB = _mm_srli_epi16(rRB, 8); | - | ||||||||||||
2010 | _mm_storeu_si128((__m128i*)(&intermediate_buffer[0][f]), rRB); | - | ||||||||||||
2011 | } never executed: end of block | 0 | ||||||||||||
2012 | #elif defined(__ARM_NEON__) | - | ||||||||||||
2013 | const int16x8_t disty_ = vdupq_n_s16(disty); | - | ||||||||||||
2014 | const int16x8_t idisty_ = vdupq_n_s16(idisty); | - | ||||||||||||
2015 | const int16x8_t colorMask = vdupq_n_s16(0x00ff); | - | ||||||||||||
2016 | - | |||||||||||||
2017 | lim -= 3; | - | ||||||||||||
2018 | for (; f < lim; x += 4, f += 4) { | - | ||||||||||||
2019 | // Load 4 pixels from s1, and split the alpha-green and red-blue component | - | ||||||||||||
2020 | int16x8_t top = vld1q_s16((int16_t*)((const uint *)(s1)+x)); | - | ||||||||||||
2021 | int16x8_t topAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(top), 8)); | - | ||||||||||||
2022 | int16x8_t topRB = vandq_s16(top, colorMask); | - | ||||||||||||
2023 | // Multiplies each colour component by idisty | - | ||||||||||||
2024 | topAG = vmulq_s16(topAG, idisty_); | - | ||||||||||||
2025 | topRB = vmulq_s16(topRB, idisty_); | - | ||||||||||||
2026 | - | |||||||||||||
2027 | // Same for the s2 vector | - | ||||||||||||
2028 | int16x8_t bottom = vld1q_s16((int16_t*)((const uint *)(s2)+x)); | - | ||||||||||||
2029 | int16x8_t bottomAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(bottom), 8)); | - | ||||||||||||
2030 | int16x8_t bottomRB = vandq_s16(bottom, colorMask); | - | ||||||||||||
2031 | bottomAG = vmulq_s16(bottomAG, disty_); | - | ||||||||||||
2032 | bottomRB = vmulq_s16(bottomRB, disty_); | - | ||||||||||||
2033 | - | |||||||||||||
2034 | // Add the values, and shift to only keep 8 significant bits per colors | - | ||||||||||||
2035 | int16x8_t rAG = vaddq_s16(topAG, bottomAG); | - | ||||||||||||
2036 | rAG = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(rAG), 8)); | - | ||||||||||||
2037 | vst1q_s16((int16_t*)(&intermediate_buffer[1][f]), rAG); | - | ||||||||||||
2038 | int16x8_t rRB = vaddq_s16(topRB, bottomRB); | - | ||||||||||||
2039 | rRB = vreinterpretq_s16_u16(vshrq_n_u16(vreinterpretq_u16_s16(rRB), 8)); | - | ||||||||||||
2040 | vst1q_s16((int16_t*)(&intermediate_buffer[0][f]), rRB); | - | ||||||||||||
2041 | } | - | ||||||||||||
2042 | #endif | - | ||||||||||||
2043 | } never executed: end of block | 0 | ||||||||||||
2044 | for (; f < count; f++) { // Same as above but without sse2
| 0 | ||||||||||||
2045 | if (blendType == BlendTransformedBilinearTiled) {
| 0 | ||||||||||||
2046 | if (x >= image_width) x -= image_width; never executed: x -= image_width;
| 0 | ||||||||||||
2047 | } else { never executed: end of block | 0 | ||||||||||||
2048 | x = qMin(x, image_x2); | - | ||||||||||||
2049 | } never executed: end of block | 0 | ||||||||||||
2050 | - | |||||||||||||
2051 | uint t = s1[x]; | - | ||||||||||||
2052 | uint b = s2[x]; | - | ||||||||||||
2053 | - | |||||||||||||
2054 | intermediate_buffer[0][f] = (((t & 0xff00ff) * idisty + (b & 0xff00ff) * disty) >> 8) & 0xff00ff; | - | ||||||||||||
2055 | intermediate_buffer[1][f] = ((( |