1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
6 #include "platform/graphics/gpu/WebGLImageConversion.h"
8 #include "platform/CheckedInt.h"
9 #include "platform/graphics/ImageObserver.h"
10 #include "platform/graphics/cpu/arm/WebGLImageConversionNEON.h"
11 #include "platform/image-decoders/ImageDecoder.h"
12 #include "wtf/OwnPtr.h"
13 #include "wtf/PassOwnPtr.h"
19 WebGLImageConversion::DataFormat getDataFormat(GLenum destinationFormat, GLenum destinationType)
21 WebGLImageConversion::DataFormat dstFormat = WebGLImageConversion::DataFormatRGBA8;
22 switch (destinationType) {
23 case GL_UNSIGNED_BYTE:
24 switch (destinationFormat) {
26 dstFormat = WebGLImageConversion::DataFormatRGB8;
29 dstFormat = WebGLImageConversion::DataFormatRGBA8;
32 dstFormat = WebGLImageConversion::DataFormatA8;
35 dstFormat = WebGLImageConversion::DataFormatR8;
37 case GL_LUMINANCE_ALPHA:
38 dstFormat = WebGLImageConversion::DataFormatRA8;
44 case GL_UNSIGNED_SHORT_4_4_4_4:
45 dstFormat = WebGLImageConversion::DataFormatRGBA4444;
47 case GL_UNSIGNED_SHORT_5_5_5_1:
48 dstFormat = WebGLImageConversion::DataFormatRGBA5551;
50 case GL_UNSIGNED_SHORT_5_6_5:
51 dstFormat = WebGLImageConversion::DataFormatRGB565;
53 case GL_HALF_FLOAT_OES: // OES_texture_half_float
54 switch (destinationFormat) {
56 dstFormat = WebGLImageConversion::DataFormatRGB16F;
59 dstFormat = WebGLImageConversion::DataFormatRGBA16F;
62 dstFormat = WebGLImageConversion::DataFormatA16F;
65 dstFormat = WebGLImageConversion::DataFormatR16F;
67 case GL_LUMINANCE_ALPHA:
68 dstFormat = WebGLImageConversion::DataFormatRA16F;
74 case GL_FLOAT: // OES_texture_float
75 switch (destinationFormat) {
77 dstFormat = WebGLImageConversion::DataFormatRGB32F;
80 dstFormat = WebGLImageConversion::DataFormatRGBA32F;
83 dstFormat = WebGLImageConversion::DataFormatA32F;
86 dstFormat = WebGLImageConversion::DataFormatR32F;
88 case GL_LUMINANCE_ALPHA:
89 dstFormat = WebGLImageConversion::DataFormatRA32F;
101 // Following Float to Half-Float converion code is from the implementation of ftp://www.fox-toolkit.org/pub/fasthalffloatconversion.pdf,
102 // "Fast Half Float Conversions" by Jeroen van der Zijp, November 2008 (Revised September 2010).
103 // Specially, the basetable[512] and shifttable[512] are generated as follows:
105 unsigned short basetable[512];
106 unsigned char shifttable[512];
108 void generatetables(){
111 for (i = 0; i < 256; ++i){
113 if (e < -24){ // Very small numbers map to zero
114 basetable[i | 0x000] = 0x0000;
115 basetable[i | 0x100] = 0x8000;
116 shifttable[i | 0x000] = 24;
117 shifttable[i | 0x100] = 24;
119 else if (e < -14) { // Small numbers map to denorms
120 basetable[i | 0x000] = (0x0400>>(-e-14));
121 basetable[i | 0x100] = (0x0400>>(-e-14)) | 0x8000;
122 shifttable[i | 0x000] = -e-1;
123 shifttable[i | 0x100] = -e-1;
125 else if (e <= 15){ // Normal numbers just lose precision
126 basetable[i | 0x000] = ((e+15)<<10);
127 basetable[i| 0x100] = ((e+15)<<10) | 0x8000;
128 shifttable[i|0x000] = 13;
129 shifttable[i|0x100] = 13;
131 else if (e<128){ // Large numbers map to Infinity
132 basetable[i|0x000] = 0x7C00;
133 basetable[i|0x100] = 0xFC00;
134 shifttable[i|0x000] = 24;
135 shifttable[i|0x100] = 24;
137 else { // Infinity and NaN's stay Infinity and NaN's
138 basetable[i|0x000] = 0x7C00;
139 basetable[i|0x100] = 0xFC00;
140 shifttable[i|0x000] = 13;
141 shifttable[i|0x100] = 13;
147 unsigned short baseTable[512] = {
148 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
149 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
150 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
151 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
152 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
153 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
154 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 8, 16, 32, 64, 128, 256,
155 512, 1024, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336, 15360,
156 16384, 17408, 18432, 19456, 20480, 21504, 22528, 23552, 24576, 25600, 26624, 27648, 28672, 29696, 30720, 31744,
157 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
158 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
159 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
160 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
161 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
162 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
163 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
164 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
165 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
166 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
167 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
168 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
169 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
170 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32769, 32770, 32772, 32776, 32784, 32800, 32832, 32896, 33024,
171 33280, 33792, 34816, 35840, 36864, 37888, 38912, 39936, 40960, 41984, 43008, 44032, 45056, 46080, 47104, 48128,
172 49152, 50176, 51200, 52224, 53248, 54272, 55296, 56320, 57344, 58368, 59392, 60416, 61440, 62464, 63488, 64512,
173 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
174 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
175 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
176 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
177 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
178 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
179 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512
182 unsigned char shiftTable[512] = {
183 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
184 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
185 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
186 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
187 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
188 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
189 24, 24, 24, 24, 24, 24, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15,
190 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
191 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 24,
192 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
193 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
194 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
195 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
196 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
197 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
198 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 13,
199 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
200 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
201 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
202 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
203 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
204 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
205 24, 24, 24, 24, 24, 24, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15,
206 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
207 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 24,
208 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
209 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
210 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
211 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
212 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
213 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
214 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 13
217 unsigned short convertFloatToHalfFloat(float f)
219 unsigned temp = *(reinterpret_cast<unsigned *>(&f));
220 unsigned signexp = (temp >> 23) & 0x1ff;
221 return baseTable[signexp] + ((temp & 0x007fffff) >> shiftTable[signexp]);
224 /* BEGIN CODE SHARED WITH MOZILLA FIREFOX */
226 // The following packing and unpacking routines are expressed in terms of function templates and inline functions to achieve generality and speedup.
227 // Explicit template specializations correspond to the cases that would occur.
228 // Some code are merged back from Mozilla code in http://mxr.mozilla.org/mozilla-central/source/content/canvas/src/WebGLTexelConversions.h
230 //----------------------------------------------------------------------
231 // Pixel unpacking routines.
232 template<int format, typename SourceType, typename DstType>
233 void unpack(const SourceType*, DstType*, unsigned)
235 ASSERT_NOT_REACHED();
238 template<> void unpack<WebGLImageConversion::DataFormatRGB8, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
240 for (unsigned i = 0; i < pixelsPerRow; ++i) {
241 destination[0] = source[0];
242 destination[1] = source[1];
243 destination[2] = source[2];
244 destination[3] = 0xFF;
250 template<> void unpack<WebGLImageConversion::DataFormatBGR8, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
252 for (unsigned i = 0; i < pixelsPerRow; ++i) {
253 destination[0] = source[2];
254 destination[1] = source[1];
255 destination[2] = source[0];
256 destination[3] = 0xFF;
262 template<> void unpack<WebGLImageConversion::DataFormatARGB8, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
264 for (unsigned i = 0; i < pixelsPerRow; ++i) {
265 destination[0] = source[1];
266 destination[1] = source[2];
267 destination[2] = source[3];
268 destination[3] = source[0];
274 template<> void unpack<WebGLImageConversion::DataFormatABGR8, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
276 for (unsigned i = 0; i < pixelsPerRow; ++i) {
277 destination[0] = source[3];
278 destination[1] = source[2];
279 destination[2] = source[1];
280 destination[3] = source[0];
286 template<> void unpack<WebGLImageConversion::DataFormatBGRA8, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
288 const uint32_t* source32 = reinterpret_cast_ptr<const uint32_t*>(source);
289 uint32_t* destination32 = reinterpret_cast_ptr<uint32_t*>(destination);
290 for (unsigned i = 0; i < pixelsPerRow; ++i) {
291 uint32_t bgra = source32[i];
293 uint32_t brMask = 0xff00ff00;
294 uint32_t gaMask = 0x00ff00ff;
296 uint32_t brMask = 0x00ff00ff;
297 uint32_t gaMask = 0xff00ff00;
299 uint32_t rgba = (((bgra >> 16) | (bgra << 16)) & brMask) | (bgra & gaMask);
300 destination32[i] = rgba;
304 template<> void unpack<WebGLImageConversion::DataFormatRGBA5551, uint16_t, uint8_t>(const uint16_t* source, uint8_t* destination, unsigned pixelsPerRow)
306 #if HAVE(ARM_NEON_INTRINSICS)
307 SIMD::unpackOneRowOfRGBA5551ToRGBA8(source, destination, pixelsPerRow);
309 for (unsigned i = 0; i < pixelsPerRow; ++i) {
310 uint16_t packedValue = source[0];
311 uint8_t r = packedValue >> 11;
312 uint8_t g = (packedValue >> 6) & 0x1F;
313 uint8_t b = (packedValue >> 1) & 0x1F;
314 destination[0] = (r << 3) | (r & 0x7);
315 destination[1] = (g << 3) | (g & 0x7);
316 destination[2] = (b << 3) | (b & 0x7);
317 destination[3] = (packedValue & 0x1) ? 0xFF : 0x0;
323 template<> void unpack<WebGLImageConversion::DataFormatRGBA4444, uint16_t, uint8_t>(const uint16_t* source, uint8_t* destination, unsigned pixelsPerRow)
325 #if HAVE(ARM_NEON_INTRINSICS)
326 SIMD::unpackOneRowOfRGBA4444ToRGBA8(source, destination, pixelsPerRow);
328 for (unsigned i = 0; i < pixelsPerRow; ++i) {
329 uint16_t packedValue = source[0];
330 uint8_t r = packedValue >> 12;
331 uint8_t g = (packedValue >> 8) & 0x0F;
332 uint8_t b = (packedValue >> 4) & 0x0F;
333 uint8_t a = packedValue & 0x0F;
334 destination[0] = r << 4 | r;
335 destination[1] = g << 4 | g;
336 destination[2] = b << 4 | b;
337 destination[3] = a << 4 | a;
343 template<> void unpack<WebGLImageConversion::DataFormatRGB565, uint16_t, uint8_t>(const uint16_t* source, uint8_t* destination, unsigned pixelsPerRow)
345 #if HAVE(ARM_NEON_INTRINSICS)
346 SIMD::unpackOneRowOfRGB565ToRGBA8(source, destination, pixelsPerRow);
348 for (unsigned i = 0; i < pixelsPerRow; ++i) {
349 uint16_t packedValue = source[0];
350 uint8_t r = packedValue >> 11;
351 uint8_t g = (packedValue >> 5) & 0x3F;
352 uint8_t b = packedValue & 0x1F;
353 destination[0] = (r << 3) | (r & 0x7);
354 destination[1] = (g << 2) | (g & 0x3);
355 destination[2] = (b << 3) | (b & 0x7);
356 destination[3] = 0xFF;
362 template<> void unpack<WebGLImageConversion::DataFormatR8, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
364 for (unsigned i = 0; i < pixelsPerRow; ++i) {
365 destination[0] = source[0];
366 destination[1] = source[0];
367 destination[2] = source[0];
368 destination[3] = 0xFF;
374 template<> void unpack<WebGLImageConversion::DataFormatRA8, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
376 for (unsigned i = 0; i < pixelsPerRow; ++i) {
377 destination[0] = source[0];
378 destination[1] = source[0];
379 destination[2] = source[0];
380 destination[3] = source[1];
386 template<> void unpack<WebGLImageConversion::DataFormatAR8, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
388 for (unsigned i = 0; i < pixelsPerRow; ++i) {
389 destination[0] = source[1];
390 destination[1] = source[1];
391 destination[2] = source[1];
392 destination[3] = source[0];
398 template<> void unpack<WebGLImageConversion::DataFormatA8, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
400 for (unsigned i = 0; i < pixelsPerRow; ++i) {
401 destination[0] = 0x0;
402 destination[1] = 0x0;
403 destination[2] = 0x0;
404 destination[3] = source[0];
410 template<> void unpack<WebGLImageConversion::DataFormatRGBA8, uint8_t, float>(const uint8_t* source, float* destination, unsigned pixelsPerRow)
412 const float scaleFactor = 1.0f / 255.0f;
413 for (unsigned i = 0; i < pixelsPerRow; ++i) {
414 destination[0] = source[0] * scaleFactor;
415 destination[1] = source[1] * scaleFactor;
416 destination[2] = source[2] * scaleFactor;
417 destination[3] = source[3] * scaleFactor;
423 template<> void unpack<WebGLImageConversion::DataFormatBGRA8, uint8_t, float>(const uint8_t* source, float* destination, unsigned pixelsPerRow)
425 const float scaleFactor = 1.0f / 255.0f;
426 for (unsigned i = 0; i < pixelsPerRow; ++i) {
427 destination[0] = source[2] * scaleFactor;
428 destination[1] = source[1] * scaleFactor;
429 destination[2] = source[0] * scaleFactor;
430 destination[3] = source[3] * scaleFactor;
436 template<> void unpack<WebGLImageConversion::DataFormatABGR8, uint8_t, float>(const uint8_t* source, float* destination, unsigned pixelsPerRow)
438 const float scaleFactor = 1.0f / 255.0f;
439 for (unsigned i = 0; i < pixelsPerRow; ++i) {
440 destination[0] = source[3] * scaleFactor;
441 destination[1] = source[2] * scaleFactor;
442 destination[2] = source[1] * scaleFactor;
443 destination[3] = source[0] * scaleFactor;
449 template<> void unpack<WebGLImageConversion::DataFormatARGB8, uint8_t, float>(const uint8_t* source, float* destination, unsigned pixelsPerRow)
451 const float scaleFactor = 1.0f / 255.0f;
452 for (unsigned i = 0; i < pixelsPerRow; ++i) {
453 destination[0] = source[1] * scaleFactor;
454 destination[1] = source[2] * scaleFactor;
455 destination[2] = source[3] * scaleFactor;
456 destination[3] = source[0] * scaleFactor;
462 template<> void unpack<WebGLImageConversion::DataFormatRGB8, uint8_t, float>(const uint8_t* source, float* destination, unsigned pixelsPerRow)
464 const float scaleFactor = 1.0f / 255.0f;
465 for (unsigned i = 0; i < pixelsPerRow; ++i) {
466 destination[0] = source[0] * scaleFactor;
467 destination[1] = source[1] * scaleFactor;
468 destination[2] = source[2] * scaleFactor;
475 template<> void unpack<WebGLImageConversion::DataFormatBGR8, uint8_t, float>(const uint8_t* source, float* destination, unsigned pixelsPerRow)
477 const float scaleFactor = 1.0f / 255.0f;
478 for (unsigned i = 0; i < pixelsPerRow; ++i) {
479 destination[0] = source[2] * scaleFactor;
480 destination[1] = source[1] * scaleFactor;
481 destination[2] = source[0] * scaleFactor;
488 template<> void unpack<WebGLImageConversion::DataFormatRGB32F, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
490 for (unsigned i = 0; i < pixelsPerRow; ++i) {
491 destination[0] = source[0];
492 destination[1] = source[1];
493 destination[2] = source[2];
500 template<> void unpack<WebGLImageConversion::DataFormatR32F, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
502 for (unsigned i = 0; i < pixelsPerRow; ++i) {
503 destination[0] = source[0];
504 destination[1] = source[0];
505 destination[2] = source[0];
512 template<> void unpack<WebGLImageConversion::DataFormatRA32F, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
514 for (unsigned i = 0; i < pixelsPerRow; ++i) {
515 destination[0] = source[0];
516 destination[1] = source[0];
517 destination[2] = source[0];
518 destination[3] = source[1];
524 template<> void unpack<WebGLImageConversion::DataFormatA32F, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
526 for (unsigned i = 0; i < pixelsPerRow; ++i) {
530 destination[3] = source[0];
536 //----------------------------------------------------------------------
537 // Pixel packing routines.
540 template<int format, int alphaOp, typename SourceType, typename DstType>
541 void pack(const SourceType*, DstType*, unsigned)
543 ASSERT_NOT_REACHED();
546 template<> void pack<WebGLImageConversion::DataFormatA8, WebGLImageConversion::AlphaDoNothing, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
548 for (unsigned i = 0; i < pixelsPerRow; ++i) {
549 destination[0] = source[3];
555 template<> void pack<WebGLImageConversion::DataFormatR8, WebGLImageConversion::AlphaDoNothing, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
557 for (unsigned i = 0; i < pixelsPerRow; ++i) {
558 destination[0] = source[0];
564 template<> void pack<WebGLImageConversion::DataFormatR8, WebGLImageConversion::AlphaDoPremultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
566 for (unsigned i = 0; i < pixelsPerRow; ++i) {
567 float scaleFactor = source[3] / 255.0f;
568 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * scaleFactor);
569 destination[0] = sourceR;
575 // FIXME: this routine is lossy and must be removed.
576 template<> void pack<WebGLImageConversion::DataFormatR8, WebGLImageConversion::AlphaDoUnmultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
578 for (unsigned i = 0; i < pixelsPerRow; ++i) {
579 float scaleFactor = source[3] ? 255.0f / source[3] : 1.0f;
580 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * scaleFactor);
581 destination[0] = sourceR;
587 template<> void pack<WebGLImageConversion::DataFormatRA8, WebGLImageConversion::AlphaDoNothing, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
589 for (unsigned i = 0; i < pixelsPerRow; ++i) {
590 destination[0] = source[0];
591 destination[1] = source[3];
597 template<> void pack<WebGLImageConversion::DataFormatRA8, WebGLImageConversion::AlphaDoPremultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
599 for (unsigned i = 0; i < pixelsPerRow; ++i) {
600 float scaleFactor = source[3] / 255.0f;
601 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * scaleFactor);
602 destination[0] = sourceR;
603 destination[1] = source[3];
609 // FIXME: this routine is lossy and must be removed.
610 template<> void pack<WebGLImageConversion::DataFormatRA8, WebGLImageConversion::AlphaDoUnmultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
612 for (unsigned i = 0; i < pixelsPerRow; ++i) {
613 float scaleFactor = source[3] ? 255.0f / source[3] : 1.0f;
614 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * scaleFactor);
615 destination[0] = sourceR;
616 destination[1] = source[3];
622 template<> void pack<WebGLImageConversion::DataFormatRGB8, WebGLImageConversion::AlphaDoNothing, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
624 for (unsigned i = 0; i < pixelsPerRow; ++i) {
625 destination[0] = source[0];
626 destination[1] = source[1];
627 destination[2] = source[2];
633 template<> void pack<WebGLImageConversion::DataFormatRGB8, WebGLImageConversion::AlphaDoPremultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
635 for (unsigned i = 0; i < pixelsPerRow; ++i) {
636 float scaleFactor = source[3] / 255.0f;
637 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * scaleFactor);
638 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * scaleFactor);
639 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * scaleFactor);
640 destination[0] = sourceR;
641 destination[1] = sourceG;
642 destination[2] = sourceB;
648 // FIXME: this routine is lossy and must be removed.
649 template<> void pack<WebGLImageConversion::DataFormatRGB8, WebGLImageConversion::AlphaDoUnmultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
651 for (unsigned i = 0; i < pixelsPerRow; ++i) {
652 float scaleFactor = source[3] ? 255.0f / source[3] : 1.0f;
653 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * scaleFactor);
654 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * scaleFactor);
655 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * scaleFactor);
656 destination[0] = sourceR;
657 destination[1] = sourceG;
658 destination[2] = sourceB;
665 template<> void pack<WebGLImageConversion::DataFormatRGBA8, WebGLImageConversion::AlphaDoNothing, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
667 memcpy(destination, source, pixelsPerRow * 4);
670 template<> void pack<WebGLImageConversion::DataFormatRGBA8, WebGLImageConversion::AlphaDoPremultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
672 for (unsigned i = 0; i < pixelsPerRow; ++i) {
673 float scaleFactor = source[3] / 255.0f;
674 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * scaleFactor);
675 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * scaleFactor);
676 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * scaleFactor);
677 destination[0] = sourceR;
678 destination[1] = sourceG;
679 destination[2] = sourceB;
680 destination[3] = source[3];
686 // FIXME: this routine is lossy and must be removed.
687 template<> void pack<WebGLImageConversion::DataFormatRGBA8, WebGLImageConversion::AlphaDoUnmultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
689 for (unsigned i = 0; i < pixelsPerRow; ++i) {
690 float scaleFactor = source[3] ? 255.0f / source[3] : 1.0f;
691 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * scaleFactor);
692 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * scaleFactor);
693 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * scaleFactor);
694 destination[0] = sourceR;
695 destination[1] = sourceG;
696 destination[2] = sourceB;
697 destination[3] = source[3];
703 template<> void pack<WebGLImageConversion::DataFormatRGBA4444, WebGLImageConversion::AlphaDoNothing, uint8_t, uint16_t>(const uint8_t* source, uint16_t* destination, unsigned pixelsPerRow)
705 #if HAVE(ARM_NEON_INTRINSICS)
706 SIMD::packOneRowOfRGBA8ToUnsignedShort4444(source, destination, pixelsPerRow);
708 for (unsigned i = 0; i < pixelsPerRow; ++i) {
709 *destination = (((source[0] & 0xF0) << 8)
710 | ((source[1] & 0xF0) << 4)
718 template<> void pack<WebGLImageConversion::DataFormatRGBA4444, WebGLImageConversion::AlphaDoPremultiply, uint8_t, uint16_t>(const uint8_t* source, uint16_t* destination, unsigned pixelsPerRow)
720 for (unsigned i = 0; i < pixelsPerRow; ++i) {
721 float scaleFactor = source[3] / 255.0f;
722 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * scaleFactor);
723 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * scaleFactor);
724 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * scaleFactor);
725 *destination = (((sourceR & 0xF0) << 8)
726 | ((sourceG & 0xF0) << 4)
734 // FIXME: this routine is lossy and must be removed.
735 template<> void pack<WebGLImageConversion::DataFormatRGBA4444, WebGLImageConversion::AlphaDoUnmultiply, uint8_t, uint16_t>(const uint8_t* source, uint16_t* destination, unsigned pixelsPerRow)
737 for (unsigned i = 0; i < pixelsPerRow; ++i) {
738 float scaleFactor = source[3] ? 255.0f / source[3] : 1.0f;
739 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * scaleFactor);
740 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * scaleFactor);
741 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * scaleFactor);
742 *destination = (((sourceR & 0xF0) << 8)
743 | ((sourceG & 0xF0) << 4)
751 template<> void pack<WebGLImageConversion::DataFormatRGBA5551, WebGLImageConversion::AlphaDoNothing, uint8_t, uint16_t>(const uint8_t* source, uint16_t* destination, unsigned pixelsPerRow)
753 #if HAVE(ARM_NEON_INTRINSICS)
754 SIMD::packOneRowOfRGBA8ToUnsignedShort5551(source, destination, pixelsPerRow);
756 for (unsigned i = 0; i < pixelsPerRow; ++i) {
757 *destination = (((source[0] & 0xF8) << 8)
758 | ((source[1] & 0xF8) << 3)
759 | ((source[2] & 0xF8) >> 2)
766 template<> void pack<WebGLImageConversion::DataFormatRGBA5551, WebGLImageConversion::AlphaDoPremultiply, uint8_t, uint16_t>(const uint8_t* source, uint16_t* destination, unsigned pixelsPerRow)
768 for (unsigned i = 0; i < pixelsPerRow; ++i) {
769 float scaleFactor = source[3] / 255.0f;
770 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * scaleFactor);
771 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * scaleFactor);
772 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * scaleFactor);
773 *destination = (((sourceR & 0xF8) << 8)
774 | ((sourceG & 0xF8) << 3)
775 | ((sourceB & 0xF8) >> 2)
782 // FIXME: this routine is lossy and must be removed.
783 template<> void pack<WebGLImageConversion::DataFormatRGBA5551, WebGLImageConversion::AlphaDoUnmultiply, uint8_t, uint16_t>(const uint8_t* source, uint16_t* destination, unsigned pixelsPerRow)
785 for (unsigned i = 0; i < pixelsPerRow; ++i) {
786 float scaleFactor = source[3] ? 255.0f / source[3] : 1.0f;
787 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * scaleFactor);
788 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * scaleFactor);
789 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * scaleFactor);
790 *destination = (((sourceR & 0xF8) << 8)
791 | ((sourceG & 0xF8) << 3)
792 | ((sourceB & 0xF8) >> 2)
799 template<> void pack<WebGLImageConversion::DataFormatRGB565, WebGLImageConversion::AlphaDoNothing, uint8_t, uint16_t>(const uint8_t* source, uint16_t* destination, unsigned pixelsPerRow)
801 #if HAVE(ARM_NEON_INTRINSICS)
802 SIMD::packOneRowOfRGBA8ToUnsignedShort565(source, destination, pixelsPerRow);
804 for (unsigned i = 0; i < pixelsPerRow; ++i) {
805 *destination = (((source[0] & 0xF8) << 8)
806 | ((source[1] & 0xFC) << 3)
807 | ((source[2] & 0xF8) >> 3));
813 template<> void pack<WebGLImageConversion::DataFormatRGB565, WebGLImageConversion::AlphaDoPremultiply, uint8_t, uint16_t>(const uint8_t* source, uint16_t* destination, unsigned pixelsPerRow)
815 for (unsigned i = 0; i < pixelsPerRow; ++i) {
816 float scaleFactor = source[3] / 255.0f;
817 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * scaleFactor);
818 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * scaleFactor);
819 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * scaleFactor);
820 *destination = (((sourceR & 0xF8) << 8)
821 | ((sourceG & 0xFC) << 3)
822 | ((sourceB & 0xF8) >> 3));
828 // FIXME: this routine is lossy and must be removed.
829 template<> void pack<WebGLImageConversion::DataFormatRGB565, WebGLImageConversion::AlphaDoUnmultiply, uint8_t, uint16_t>(const uint8_t* source, uint16_t* destination, unsigned pixelsPerRow)
831 for (unsigned i = 0; i < pixelsPerRow; ++i) {
832 float scaleFactor = source[3] ? 255.0f / source[3] : 1.0f;
833 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * scaleFactor);
834 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * scaleFactor);
835 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * scaleFactor);
836 *destination = (((sourceR & 0xF8) << 8)
837 | ((sourceG & 0xFC) << 3)
838 | ((sourceB & 0xF8) >> 3));
844 template<> void pack<WebGLImageConversion::DataFormatRGB32F, WebGLImageConversion::AlphaDoNothing, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
846 for (unsigned i = 0; i < pixelsPerRow; ++i) {
847 destination[0] = source[0];
848 destination[1] = source[1];
849 destination[2] = source[2];
855 template<> void pack<WebGLImageConversion::DataFormatRGB32F, WebGLImageConversion::AlphaDoPremultiply, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
857 for (unsigned i = 0; i < pixelsPerRow; ++i) {
858 float scaleFactor = source[3];
859 destination[0] = source[0] * scaleFactor;
860 destination[1] = source[1] * scaleFactor;
861 destination[2] = source[2] * scaleFactor;
867 template<> void pack<WebGLImageConversion::DataFormatRGB32F, WebGLImageConversion::AlphaDoUnmultiply, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
869 for (unsigned i = 0; i < pixelsPerRow; ++i) {
870 float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f;
871 destination[0] = source[0] * scaleFactor;
872 destination[1] = source[1] * scaleFactor;
873 destination[2] = source[2] * scaleFactor;
879 // Used only during RGBA8 or BGRA8 -> floating-point uploads.
880 template<> void pack<WebGLImageConversion::DataFormatRGBA32F, WebGLImageConversion::AlphaDoNothing, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
882 memcpy(destination, source, pixelsPerRow * 4 * sizeof(float));
885 template<> void pack<WebGLImageConversion::DataFormatRGBA32F, WebGLImageConversion::AlphaDoPremultiply, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
887 for (unsigned i = 0; i < pixelsPerRow; ++i) {
888 float scaleFactor = source[3];
889 destination[0] = source[0] * scaleFactor;
890 destination[1] = source[1] * scaleFactor;
891 destination[2] = source[2] * scaleFactor;
892 destination[3] = source[3];
898 template<> void pack<WebGLImageConversion::DataFormatRGBA32F, WebGLImageConversion::AlphaDoUnmultiply, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
900 for (unsigned i = 0; i < pixelsPerRow; ++i) {
901 float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f;
902 destination[0] = source[0] * scaleFactor;
903 destination[1] = source[1] * scaleFactor;
904 destination[2] = source[2] * scaleFactor;
905 destination[3] = source[3];
911 template<> void pack<WebGLImageConversion::DataFormatA32F, WebGLImageConversion::AlphaDoNothing, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
913 for (unsigned i = 0; i < pixelsPerRow; ++i) {
914 destination[0] = source[3];
920 template<> void pack<WebGLImageConversion::DataFormatR32F, WebGLImageConversion::AlphaDoNothing, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
922 for (unsigned i = 0; i < pixelsPerRow; ++i) {
923 destination[0] = source[0];
929 template<> void pack<WebGLImageConversion::DataFormatR32F, WebGLImageConversion::AlphaDoPremultiply, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
931 for (unsigned i = 0; i < pixelsPerRow; ++i) {
932 float scaleFactor = source[3];
933 destination[0] = source[0] * scaleFactor;
939 template<> void pack<WebGLImageConversion::DataFormatR32F, WebGLImageConversion::AlphaDoUnmultiply, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
941 for (unsigned i = 0; i < pixelsPerRow; ++i) {
942 float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f;
943 destination[0] = source[0] * scaleFactor;
949 template<> void pack<WebGLImageConversion::DataFormatRA32F, WebGLImageConversion::AlphaDoNothing, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
951 for (unsigned i = 0; i < pixelsPerRow; ++i) {
952 destination[0] = source[0];
953 destination[1] = source[3];
959 template<> void pack<WebGLImageConversion::DataFormatRA32F, WebGLImageConversion::AlphaDoPremultiply, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
961 for (unsigned i = 0; i < pixelsPerRow; ++i) {
962 float scaleFactor = source[3];
963 destination[0] = source[0] * scaleFactor;
964 destination[1] = source[3];
970 template<> void pack<WebGLImageConversion::DataFormatRA32F, WebGLImageConversion::AlphaDoUnmultiply, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
972 for (unsigned i = 0; i < pixelsPerRow; ++i) {
973 float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f;
974 destination[0] = source[0] * scaleFactor;
975 destination[1] = source[3];
981 template<> void pack<WebGLImageConversion::DataFormatRGBA16F, WebGLImageConversion::AlphaDoNothing, float, uint16_t>(const float* source, uint16_t* destination, unsigned pixelsPerRow)
983 for (unsigned i = 0; i < pixelsPerRow; ++i) {
984 destination[0] = convertFloatToHalfFloat(source[0]);
985 destination[1] = convertFloatToHalfFloat(source[1]);
986 destination[2] = convertFloatToHalfFloat(source[2]);
987 destination[3] = convertFloatToHalfFloat(source[3]);
993 template<> void pack<WebGLImageConversion::DataFormatRGBA16F, WebGLImageConversion::AlphaDoPremultiply, float, uint16_t>(const float* source, uint16_t* destination, unsigned pixelsPerRow)
995 for (unsigned i = 0; i < pixelsPerRow; ++i) {
996 float scaleFactor = source[3];
997 destination[0] = convertFloatToHalfFloat(source[0] * scaleFactor);
998 destination[1] = convertFloatToHalfFloat(source[1] * scaleFactor);
999 destination[2] = convertFloatToHalfFloat(source[2] * scaleFactor);
1000 destination[3] = convertFloatToHalfFloat(source[3]);
1006 template<> void pack<WebGLImageConversion::DataFormatRGBA16F, WebGLImageConversion::AlphaDoUnmultiply, float, uint16_t>(const float* source, uint16_t* destination, unsigned pixelsPerRow)
1008 for (unsigned i = 0; i < pixelsPerRow; ++i) {
1009 float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f;
1010 destination[0] = convertFloatToHalfFloat(source[0] * scaleFactor);
1011 destination[1] = convertFloatToHalfFloat(source[1] * scaleFactor);
1012 destination[2] = convertFloatToHalfFloat(source[2] * scaleFactor);
1013 destination[3] = convertFloatToHalfFloat(source[3]);
1019 template<> void pack<WebGLImageConversion::DataFormatRGB16F, WebGLImageConversion::AlphaDoNothing, float, uint16_t>(const float* source, uint16_t* destination, unsigned pixelsPerRow)
1021 for (unsigned i = 0; i < pixelsPerRow; ++i) {
1022 destination[0] = convertFloatToHalfFloat(source[0]);
1023 destination[1] = convertFloatToHalfFloat(source[1]);
1024 destination[2] = convertFloatToHalfFloat(source[2]);
1030 template<> void pack<WebGLImageConversion::DataFormatRGB16F, WebGLImageConversion::AlphaDoPremultiply, float, uint16_t>(const float* source, uint16_t* destination, unsigned pixelsPerRow)
1032 for (unsigned i = 0; i < pixelsPerRow; ++i) {
1033 float scaleFactor = source[3];
1034 destination[0] = convertFloatToHalfFloat(source[0] * scaleFactor);
1035 destination[1] = convertFloatToHalfFloat(source[1] * scaleFactor);
1036 destination[2] = convertFloatToHalfFloat(source[2] * scaleFactor);
1042 template<> void pack<WebGLImageConversion::DataFormatRGB16F, WebGLImageConversion::AlphaDoUnmultiply, float, uint16_t>(const float* source, uint16_t* destination, unsigned pixelsPerRow)
1044 for (unsigned i = 0; i < pixelsPerRow; ++i) {
1045 float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f;
1046 destination[0] = convertFloatToHalfFloat(source[0] * scaleFactor);
1047 destination[1] = convertFloatToHalfFloat(source[1] * scaleFactor);
1048 destination[2] = convertFloatToHalfFloat(source[2] * scaleFactor);
1054 template<> void pack<WebGLImageConversion::DataFormatRA16F, WebGLImageConversion::AlphaDoNothing, float, uint16_t>(const float* source, uint16_t* destination, unsigned pixelsPerRow)
1056 for (unsigned i = 0; i < pixelsPerRow; ++i) {
1057 destination[0] = convertFloatToHalfFloat(source[0]);
1058 destination[1] = convertFloatToHalfFloat(source[3]);
1064 template<> void pack<WebGLImageConversion::DataFormatRA16F, WebGLImageConversion::AlphaDoPremultiply, float, uint16_t>(const float* source, uint16_t* destination, unsigned pixelsPerRow)
1066 for (unsigned i = 0; i < pixelsPerRow; ++i) {
1067 float scaleFactor = source[3];
1068 destination[0] = convertFloatToHalfFloat(source[0] * scaleFactor);
1069 destination[1] = convertFloatToHalfFloat(source[3]);
1075 template<> void pack<WebGLImageConversion::DataFormatRA16F, WebGLImageConversion::AlphaDoUnmultiply, float, uint16_t>(const float* source, uint16_t* destination, unsigned pixelsPerRow)
1077 for (unsigned i = 0; i < pixelsPerRow; ++i) {
1078 float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f;
1079 destination[0] = convertFloatToHalfFloat(source[0] * scaleFactor);
1080 destination[1] = convertFloatToHalfFloat(source[3]);
1086 template<> void pack<WebGLImageConversion::DataFormatR16F, WebGLImageConversion::AlphaDoNothing, float, uint16_t>(const float* source, uint16_t* destination, unsigned pixelsPerRow)
1088 for (unsigned i = 0; i < pixelsPerRow; ++i) {
1089 destination[0] = convertFloatToHalfFloat(source[0]);
1095 template<> void pack<WebGLImageConversion::DataFormatR16F, WebGLImageConversion::AlphaDoPremultiply, float, uint16_t>(const float* source, uint16_t* destination, unsigned pixelsPerRow)
1097 for (unsigned i = 0; i < pixelsPerRow; ++i) {
1098 float scaleFactor = source[3];
1099 destination[0] = convertFloatToHalfFloat(source[0] * scaleFactor);
1105 template<> void pack<WebGLImageConversion::DataFormatR16F, WebGLImageConversion::AlphaDoUnmultiply, float, uint16_t>(const float* source, uint16_t* destination, unsigned pixelsPerRow)
1107 for (unsigned i = 0; i < pixelsPerRow; ++i) {
1108 float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f;
1109 destination[0] = convertFloatToHalfFloat(source[0] * scaleFactor);
1115 template<> void pack<WebGLImageConversion::DataFormatA16F, WebGLImageConversion::AlphaDoNothing, float, uint16_t>(const float* source, uint16_t* destination, unsigned pixelsPerRow)
1117 for (unsigned i = 0; i < pixelsPerRow; ++i) {
1118 destination[0] = convertFloatToHalfFloat(source[3]);
1124 bool HasAlpha(int format)
1126 return format == WebGLImageConversion::DataFormatA8
1127 || format == WebGLImageConversion::DataFormatA16F
1128 || format == WebGLImageConversion::DataFormatA32F
1129 || format == WebGLImageConversion::DataFormatRA8
1130 || format == WebGLImageConversion::DataFormatAR8
1131 || format == WebGLImageConversion::DataFormatRA16F
1132 || format == WebGLImageConversion::DataFormatRA32F
1133 || format == WebGLImageConversion::DataFormatRGBA8
1134 || format == WebGLImageConversion::DataFormatBGRA8
1135 || format == WebGLImageConversion::DataFormatARGB8
1136 || format == WebGLImageConversion::DataFormatABGR8
1137 || format == WebGLImageConversion::DataFormatRGBA16F
1138 || format == WebGLImageConversion::DataFormatRGBA32F
1139 || format == WebGLImageConversion::DataFormatRGBA4444
1140 || format == WebGLImageConversion::DataFormatRGBA5551;
1143 bool HasColor(int format)
1145 return format == WebGLImageConversion::DataFormatRGBA8
1146 || format == WebGLImageConversion::DataFormatRGBA16F
1147 || format == WebGLImageConversion::DataFormatRGBA32F
1148 || format == WebGLImageConversion::DataFormatRGB8
1149 || format == WebGLImageConversion::DataFormatRGB16F
1150 || format == WebGLImageConversion::DataFormatRGB32F
1151 || format == WebGLImageConversion::DataFormatBGR8
1152 || format == WebGLImageConversion::DataFormatBGRA8
1153 || format == WebGLImageConversion::DataFormatARGB8
1154 || format == WebGLImageConversion::DataFormatABGR8
1155 || format == WebGLImageConversion::DataFormatRGBA5551
1156 || format == WebGLImageConversion::DataFormatRGBA4444
1157 || format == WebGLImageConversion::DataFormatRGB565
1158 || format == WebGLImageConversion::DataFormatR8
1159 || format == WebGLImageConversion::DataFormatR16F
1160 || format == WebGLImageConversion::DataFormatR32F
1161 || format == WebGLImageConversion::DataFormatRA8
1162 || format == WebGLImageConversion::DataFormatRA16F
1163 || format == WebGLImageConversion::DataFormatRA32F
1164 || format == WebGLImageConversion::DataFormatAR8;
1167 template<int Format>
1168 struct IsFloatFormat {
1169 static const bool Value =
1170 Format == WebGLImageConversion::DataFormatRGBA32F
1171 || Format == WebGLImageConversion::DataFormatRGB32F
1172 || Format == WebGLImageConversion::DataFormatRA32F
1173 || Format == WebGLImageConversion::DataFormatR32F
1174 || Format == WebGLImageConversion::DataFormatA32F;
1177 template<int Format>
1178 struct IsHalfFloatFormat {
1179 static const bool Value =
1180 Format == WebGLImageConversion::DataFormatRGBA16F
1181 || Format == WebGLImageConversion::DataFormatRGB16F
1182 || Format == WebGLImageConversion::DataFormatRA16F
1183 || Format == WebGLImageConversion::DataFormatR16F
1184 || Format == WebGLImageConversion::DataFormatA16F;
1187 template<int Format>
1188 struct Is16bppFormat {
1189 static const bool Value =
1190 Format == WebGLImageConversion::DataFormatRGBA5551
1191 || Format == WebGLImageConversion::DataFormatRGBA4444
1192 || Format == WebGLImageConversion::DataFormatRGB565;
1195 template<int Format, bool IsFloat = IsFloatFormat<Format>::Value, bool IsHalfFloat = IsHalfFloatFormat<Format>::Value, bool Is16bpp = Is16bppFormat<Format>::Value>
1196 struct DataTypeForFormat {
1197 typedef uint8_t Type;
1200 template<int Format>
1201 struct DataTypeForFormat<Format, true, false, false> {
1205 template<int Format>
1206 struct DataTypeForFormat<Format, false, true, false> {
1207 typedef uint16_t Type;
1210 template<int Format>
1211 struct DataTypeForFormat<Format, false, false, true> {
1212 typedef uint16_t Type;
1215 template<int Format>
1216 struct IntermediateFormat {
1217 static const int Value = (IsFloatFormat<Format>::Value || IsHalfFloatFormat<Format>::Value) ? WebGLImageConversion::DataFormatRGBA32F : WebGLImageConversion::DataFormatRGBA8;
1220 unsigned TexelBytesForFormat(WebGLImageConversion::DataFormat format)
1223 case WebGLImageConversion::DataFormatR8:
1224 case WebGLImageConversion::DataFormatA8:
1226 case WebGLImageConversion::DataFormatRA8:
1227 case WebGLImageConversion::DataFormatAR8:
1228 case WebGLImageConversion::DataFormatRGBA5551:
1229 case WebGLImageConversion::DataFormatRGBA4444:
1230 case WebGLImageConversion::DataFormatRGB565:
1231 case WebGLImageConversion::DataFormatA16F:
1232 case WebGLImageConversion::DataFormatR16F:
1234 case WebGLImageConversion::DataFormatRGB8:
1235 case WebGLImageConversion::DataFormatBGR8:
1237 case WebGLImageConversion::DataFormatRGBA8:
1238 case WebGLImageConversion::DataFormatARGB8:
1239 case WebGLImageConversion::DataFormatABGR8:
1240 case WebGLImageConversion::DataFormatBGRA8:
1241 case WebGLImageConversion::DataFormatR32F:
1242 case WebGLImageConversion::DataFormatA32F:
1243 case WebGLImageConversion::DataFormatRA16F:
1245 case WebGLImageConversion::DataFormatRGB16F:
1247 case WebGLImageConversion::DataFormatRA32F:
1248 case WebGLImageConversion::DataFormatRGBA16F:
1250 case WebGLImageConversion::DataFormatRGB32F:
1252 case WebGLImageConversion::DataFormatRGBA32F:
1259 /* END CODE SHARED WITH MOZILLA FIREFOX */
1261 class FormatConverter {
1263 FormatConverter(unsigned width, unsigned height,
1264 const void* srcStart, void* dstStart, int srcStride, int dstStride)
1265 : m_width(width), m_height(height), m_srcStart(srcStart), m_dstStart(dstStart), m_srcStride(srcStride), m_dstStride(dstStride), m_success(false)
1267 const unsigned MaxNumberOfComponents = 4;
1268 const unsigned MaxBytesPerComponent = 4;
1269 m_unpackedIntermediateSrcData = adoptArrayPtr(new uint8_t[m_width * MaxNumberOfComponents *MaxBytesPerComponent]);
1270 ASSERT(m_unpackedIntermediateSrcData.get());
1273 void convert(WebGLImageConversion::DataFormat srcFormat, WebGLImageConversion::DataFormat dstFormat, WebGLImageConversion::AlphaOp);
1274 bool Success() const { return m_success; }
1277 template<WebGLImageConversion::DataFormat SrcFormat>
1278 void convert(WebGLImageConversion::DataFormat dstFormat, WebGLImageConversion::AlphaOp);
1280 template<WebGLImageConversion::DataFormat SrcFormat, WebGLImageConversion::DataFormat DstFormat>
1281 void convert(WebGLImageConversion::AlphaOp);
1283 template<WebGLImageConversion::DataFormat SrcFormat, WebGLImageConversion::DataFormat DstFormat, WebGLImageConversion::AlphaOp alphaOp>
1286 const unsigned m_width, m_height;
1287 const void* const m_srcStart;
1288 void* const m_dstStart;
1289 const int m_srcStride, m_dstStride;
1291 OwnPtr<uint8_t[]> m_unpackedIntermediateSrcData;
1294 void FormatConverter::convert(WebGLImageConversion::DataFormat srcFormat, WebGLImageConversion::DataFormat dstFormat, WebGLImageConversion::AlphaOp alphaOp)
1296 #define FORMATCONVERTER_CASE_SRCFORMAT(SrcFormat) \
1298 return convert<SrcFormat>(dstFormat, alphaOp);
1300 switch (srcFormat) {
1301 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatR8)
1302 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatA8)
1303 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatR32F)
1304 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatA32F)
1305 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatRA8)
1306 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatRA32F)
1307 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatRGB8)
1308 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatBGR8)
1309 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatRGB565)
1310 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatRGB32F)
1311 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatRGBA8)
1312 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatARGB8)
1313 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatABGR8)
1314 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatAR8)
1315 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatBGRA8)
1316 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatRGBA5551)
1317 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatRGBA4444)
1318 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatRGBA32F)
1320 ASSERT_NOT_REACHED();
1322 #undef FORMATCONVERTER_CASE_SRCFORMAT
1325 template<WebGLImageConversion::DataFormat SrcFormat>
1326 void FormatConverter::convert(WebGLImageConversion::DataFormat dstFormat, WebGLImageConversion::AlphaOp alphaOp)
1328 #define FORMATCONVERTER_CASE_DSTFORMAT(DstFormat) \
1330 return convert<SrcFormat, DstFormat>(alphaOp);
1332 switch (dstFormat) {
1333 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatR8)
1334 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatR16F)
1335 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatR32F)
1336 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatA8)
1337 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatA16F)
1338 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatA32F)
1339 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatRA8)
1340 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatRA16F)
1341 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatRA32F)
1342 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatRGB8)
1343 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatRGB565)
1344 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatRGB16F)
1345 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatRGB32F)
1346 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatRGBA8)
1347 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatRGBA5551)
1348 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatRGBA4444)
1349 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatRGBA16F)
1350 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatRGBA32F)
1352 ASSERT_NOT_REACHED();
1355 #undef FORMATCONVERTER_CASE_DSTFORMAT
1358 template<WebGLImageConversion::DataFormat SrcFormat, WebGLImageConversion::DataFormat DstFormat>
1359 void FormatConverter::convert(WebGLImageConversion::AlphaOp alphaOp)
1361 #define FORMATCONVERTER_CASE_ALPHAOP(alphaOp) \
1363 return convert<SrcFormat, DstFormat, alphaOp>();
1366 FORMATCONVERTER_CASE_ALPHAOP(WebGLImageConversion::AlphaDoNothing)
1367 FORMATCONVERTER_CASE_ALPHAOP(WebGLImageConversion::AlphaDoPremultiply)
1368 FORMATCONVERTER_CASE_ALPHAOP(WebGLImageConversion::AlphaDoUnmultiply)
1370 ASSERT_NOT_REACHED();
1372 #undef FORMATCONVERTER_CASE_ALPHAOP
1375 template<WebGLImageConversion::DataFormat SrcFormat, WebGLImageConversion::DataFormat DstFormat, WebGLImageConversion::AlphaOp alphaOp>
1376 void FormatConverter::convert()
1378 // Many instantiations of this template function will never be entered, so we try
1379 // to return immediately in these cases to avoid the compiler to generate useless code.
1380 if (SrcFormat == DstFormat && alphaOp == WebGLImageConversion::AlphaDoNothing) {
1381 ASSERT_NOT_REACHED();
1384 if (!IsFloatFormat<DstFormat>::Value && IsFloatFormat<SrcFormat>::Value) {
1385 ASSERT_NOT_REACHED();
1389 // Only textures uploaded from DOM elements or ImageData can allow DstFormat != SrcFormat.
1390 const bool srcFormatComesFromDOMElementOrImageData = WebGLImageConversion::srcFormatComeFromDOMElementOrImageData(SrcFormat);
1391 if (!srcFormatComesFromDOMElementOrImageData && SrcFormat != DstFormat) {
1392 ASSERT_NOT_REACHED();
1395 // Likewise, only textures uploaded from DOM elements or ImageData can possibly have to be unpremultiplied.
1396 if (!srcFormatComesFromDOMElementOrImageData && alphaOp == WebGLImageConversion::AlphaDoUnmultiply) {
1397 ASSERT_NOT_REACHED();
1400 if ((!HasAlpha(SrcFormat) || !HasColor(SrcFormat) || !HasColor(DstFormat)) && alphaOp != WebGLImageConversion::AlphaDoNothing) {
1401 ASSERT_NOT_REACHED();
1405 typedef typename DataTypeForFormat<SrcFormat>::Type SrcType;
1406 typedef typename DataTypeForFormat<DstFormat>::Type DstType;
1407 const int IntermediateSrcFormat = IntermediateFormat<DstFormat>::Value;
1408 typedef typename DataTypeForFormat<IntermediateSrcFormat>::Type IntermediateSrcType;
1409 const ptrdiff_t srcStrideInElements = m_srcStride / sizeof(SrcType);
1410 const ptrdiff_t dstStrideInElements = m_dstStride / sizeof(DstType);
1411 const bool trivialUnpack = (SrcFormat == WebGLImageConversion::DataFormatRGBA8 && !IsFloatFormat<DstFormat>::Value && !IsHalfFloatFormat<DstFormat>::Value) || SrcFormat == WebGLImageConversion::DataFormatRGBA32F;
1412 const bool trivialPack = (DstFormat == WebGLImageConversion::DataFormatRGBA8 || DstFormat == WebGLImageConversion::DataFormatRGBA32F) && alphaOp == WebGLImageConversion::AlphaDoNothing && m_dstStride > 0;
1413 ASSERT(!trivialUnpack || !trivialPack);
1415 const SrcType *srcRowStart = static_cast<const SrcType*>(m_srcStart);
1416 DstType* dstRowStart = static_cast<DstType*>(m_dstStart);
1417 if (!trivialUnpack && trivialPack) {
1418 for (size_t i = 0; i < m_height; ++i) {
1419 unpack<SrcFormat>(srcRowStart, dstRowStart, m_width);
1420 srcRowStart += srcStrideInElements;
1421 dstRowStart += dstStrideInElements;
1423 } else if (!trivialUnpack && !trivialPack) {
1424 for (size_t i = 0; i < m_height; ++i) {
1425 unpack<SrcFormat>(srcRowStart, reinterpret_cast<IntermediateSrcType*>(m_unpackedIntermediateSrcData.get()), m_width);
1426 pack<DstFormat, alphaOp>(reinterpret_cast<IntermediateSrcType*>(m_unpackedIntermediateSrcData.get()), dstRowStart, m_width);
1427 srcRowStart += srcStrideInElements;
1428 dstRowStart += dstStrideInElements;
1431 for (size_t i = 0; i < m_height; ++i) {
1432 pack<DstFormat, alphaOp>(srcRowStart, dstRowStart, m_width);
1433 srcRowStart += srcStrideInElements;
1434 dstRowStart += dstStrideInElements;
1441 } // anonymous namespace
1443 bool WebGLImageConversion::computeFormatAndTypeParameters(GLenum format, GLenum type, unsigned* componentsPerPixel, unsigned* bytesPerComponent)
1448 case GL_DEPTH_COMPONENT:
1449 case GL_DEPTH_STENCIL_OES:
1450 *componentsPerPixel = 1;
1452 case GL_LUMINANCE_ALPHA:
1453 *componentsPerPixel = 2;
1456 case GL_SRGB_EXT: // GL_EXT_sRGB
1457 *componentsPerPixel = 3;
1460 case GL_BGRA_EXT: // GL_EXT_texture_format_BGRA8888
1461 case GL_SRGB_ALPHA_EXT: // GL_EXT_sRGB
1462 *componentsPerPixel = 4;
1468 case GL_UNSIGNED_BYTE:
1469 *bytesPerComponent = sizeof(GLubyte);
1471 case GL_UNSIGNED_SHORT:
1472 *bytesPerComponent = sizeof(GLushort);
1474 case GL_UNSIGNED_SHORT_5_6_5:
1475 case GL_UNSIGNED_SHORT_4_4_4_4:
1476 case GL_UNSIGNED_SHORT_5_5_5_1:
1477 *componentsPerPixel = 1;
1478 *bytesPerComponent = sizeof(GLushort);
1480 case GL_UNSIGNED_INT_24_8_OES:
1481 case GL_UNSIGNED_INT:
1482 *bytesPerComponent = sizeof(GLuint);
1484 case GL_FLOAT: // OES_texture_float
1485 *bytesPerComponent = sizeof(GLfloat);
1487 case GL_HALF_FLOAT_OES: // OES_texture_half_float
1488 *bytesPerComponent = sizeof(GLushort);
1496 GLenum WebGLImageConversion::computeImageSizeInBytes(GLenum format, GLenum type, GLsizei width, GLsizei height, GLint alignment, unsigned* imageSizeInBytes, unsigned* paddingInBytes)
1498 ASSERT(imageSizeInBytes);
1499 ASSERT(alignment == 1 || alignment == 2 || alignment == 4 || alignment == 8);
1500 if (width < 0 || height < 0)
1501 return GL_INVALID_VALUE;
1502 unsigned bytesPerComponent, componentsPerPixel;
1503 if (!computeFormatAndTypeParameters(format, type, &bytesPerComponent, &componentsPerPixel))
1504 return GL_INVALID_ENUM;
1505 if (!width || !height) {
1506 *imageSizeInBytes = 0;
1508 *paddingInBytes = 0;
1511 CheckedInt<uint32_t> checkedValue(bytesPerComponent * componentsPerPixel);
1512 checkedValue *= width;
1513 if (!checkedValue.isValid())
1514 return GL_INVALID_VALUE;
1515 unsigned validRowSize = checkedValue.value();
1516 unsigned padding = 0;
1517 unsigned residual = validRowSize % alignment;
1519 padding = alignment - residual;
1520 checkedValue += padding;
1522 // Last row needs no padding.
1523 checkedValue *= (height - 1);
1524 checkedValue += validRowSize;
1525 if (!checkedValue.isValid())
1526 return GL_INVALID_VALUE;
1527 *imageSizeInBytes = checkedValue.value();
1529 *paddingInBytes = padding;
1533 WebGLImageConversion::ImageExtractor::ImageExtractor(Image* image, ImageHtmlDomSource imageHtmlDomSource, bool premultiplyAlpha, bool ignoreGammaAndColorProfile)
1536 m_imageHtmlDomSource = imageHtmlDomSource;
1537 m_extractSucceeded = extractImage(premultiplyAlpha, ignoreGammaAndColorProfile);
1540 WebGLImageConversion::ImageExtractor::~ImageExtractor()
1543 m_skiaImage->bitmap().unlockPixels();
1546 bool WebGLImageConversion::ImageExtractor::extractImage(bool premultiplyAlpha, bool ignoreGammaAndColorProfile)
1550 m_skiaImage = m_image->nativeImageForCurrentFrame();
1551 m_alphaOp = AlphaDoNothing;
1552 bool hasAlpha = m_skiaImage ? !m_skiaImage->bitmap().isOpaque() : true;
1553 if ((!m_skiaImage || ignoreGammaAndColorProfile || (hasAlpha && !premultiplyAlpha)) && m_image->data()) {
1554 // Attempt to get raw unpremultiplied image data.
1555 OwnPtr<ImageDecoder> decoder(ImageDecoder::create(
1556 *(m_image->data()), ImageSource::AlphaNotPremultiplied,
1557 ignoreGammaAndColorProfile ? ImageSource::GammaAndColorProfileIgnored : ImageSource::GammaAndColorProfileApplied));
1560 decoder->setData(m_image->data(), true);
1561 if (!decoder->frameCount())
1563 ImageFrame* frame = decoder->frameBufferAtIndex(0);
1564 if (!frame || frame->status() != ImageFrame::FrameComplete)
1566 hasAlpha = frame->hasAlpha();
1567 m_nativeImage = frame->asNewNativeImage();
1568 if (!m_nativeImage.get() || !m_nativeImage->isDataComplete() || !m_nativeImage->bitmap().width() || !m_nativeImage->bitmap().height())
1570 if (m_nativeImage->bitmap().colorType() != kN32_SkColorType)
1572 m_skiaImage = m_nativeImage.get();
1573 if (hasAlpha && premultiplyAlpha)
1574 m_alphaOp = AlphaDoPremultiply;
1575 } else if (!premultiplyAlpha && hasAlpha) {
1576 // 1. For texImage2D with HTMLVideoElment input, assume no PremultiplyAlpha had been applied and the alpha value for each pixel is 0xFF
1577 // which is true at present and may be changed in the future and needs adjustment accordingly.
1578 // 2. For texImage2D with HTMLCanvasElement input in which Alpha is already Premultiplied in this port,
1579 // do AlphaDoUnmultiply if UNPACK_PREMULTIPLY_ALPHA_WEBGL is set to false.
1580 if (m_imageHtmlDomSource != HtmlDomVideo)
1581 m_alphaOp = AlphaDoUnmultiply;
1586 m_imageSourceFormat = SK_B32_SHIFT ? DataFormatRGBA8 : DataFormatBGRA8;
1587 m_imageWidth = m_skiaImage->bitmap().width();
1588 m_imageHeight = m_skiaImage->bitmap().height();
1589 if (!m_imageWidth || !m_imageHeight) {
1590 m_skiaImage.clear();
1593 // Fail if the image was downsampled because of memory limits.
1594 if (m_imageWidth != (unsigned)m_image->size().width() || m_imageHeight != (unsigned)m_image->size().height()) {
1595 m_skiaImage.clear();
1598 m_imageSourceUnpackAlignment = 0;
1599 m_skiaImage->bitmap().lockPixels();
1600 m_imagePixelData = m_skiaImage->bitmap().getPixels();
1604 unsigned WebGLImageConversion::getClearBitsByFormat(GLenum format)
1609 case GL_LUMINANCE_ALPHA:
1616 case GL_SRGB_ALPHA_EXT:
1617 return GL_COLOR_BUFFER_BIT;
1618 case GL_DEPTH_COMPONENT16:
1619 case GL_DEPTH_COMPONENT:
1620 return GL_DEPTH_BUFFER_BIT;
1621 case GL_STENCIL_INDEX8:
1622 return GL_STENCIL_BUFFER_BIT;
1623 case GL_DEPTH_STENCIL_OES:
1624 return GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
1630 unsigned WebGLImageConversion::getChannelBitsByFormat(GLenum format)
1634 return ChannelAlpha;
1637 case GL_LUMINANCE_ALPHA:
1646 case GL_SRGB_ALPHA_EXT:
1648 case GL_DEPTH_COMPONENT16:
1649 case GL_DEPTH_COMPONENT:
1650 return ChannelDepth;
1651 case GL_STENCIL_INDEX8:
1652 return ChannelStencil;
1653 case GL_DEPTH_STENCIL_OES:
1654 return ChannelDepth | ChannelStencil;
1660 bool WebGLImageConversion::packImageData(
1667 DataFormat sourceFormat,
1670 unsigned sourceUnpackAlignment,
1671 Vector<uint8_t>& data)
1676 unsigned packedSize;
1677 // Output data is tightly packed (alignment == 1).
1678 if (computeImageSizeInBytes(format, type, width, height, 1, &packedSize, 0) != GL_NO_ERROR)
1680 data.resize(packedSize);
1682 if (!packPixels(reinterpret_cast<const uint8_t*>(pixels), sourceFormat, width, height, sourceUnpackAlignment, format, type, alphaOp, data.data(), flipY))
1684 if (ImageObserver *observer = image->imageObserver())
1685 observer->didDraw(image);
1689 bool WebGLImageConversion::extractImageData(
1690 const uint8_t* imageData,
1691 const IntSize& imageDataSize,
1695 bool premultiplyAlpha,
1696 Vector<uint8_t>& data)
1700 int width = imageDataSize.width();
1701 int height = imageDataSize.height();
1703 unsigned packedSize;
1704 // Output data is tightly packed (alignment == 1).
1705 if (computeImageSizeInBytes(format, type, width, height, 1, &packedSize, 0) != GL_NO_ERROR)
1707 data.resize(packedSize);
1709 if (!packPixels(imageData, DataFormatRGBA8, width, height, 0, format, type, premultiplyAlpha ? AlphaDoPremultiply : AlphaDoNothing, data.data(), flipY))
1715 bool WebGLImageConversion::extractTextureData(
1718 GLenum format, GLenum type,
1719 unsigned unpackAlignment,
1720 bool flipY, bool premultiplyAlpha,
1722 Vector<uint8_t>& data)
1724 // Assumes format, type, etc. have already been validated.
1725 DataFormat sourceDataFormat = getDataFormat(format, type);
1727 // Resize the output buffer.
1728 unsigned int componentsPerPixel, bytesPerComponent;
1729 if (!computeFormatAndTypeParameters(format, type, &componentsPerPixel, &bytesPerComponent))
1731 unsigned bytesPerPixel = componentsPerPixel * bytesPerComponent;
1732 data.resize(width * height * bytesPerPixel);
1734 if (!packPixels(static_cast<const uint8_t*>(pixels), sourceDataFormat, width, height, unpackAlignment, format, type, (premultiplyAlpha ? AlphaDoPremultiply : AlphaDoNothing), data.data(), flipY))
1740 bool WebGLImageConversion::packPixels(
1741 const uint8_t* sourceData,
1742 DataFormat sourceDataFormat,
1745 unsigned sourceUnpackAlignment,
1746 unsigned destinationFormat,
1747 unsigned destinationType,
1749 void* destinationData,
1752 int validSrc = width * TexelBytesForFormat(sourceDataFormat);
1753 int remainder = sourceUnpackAlignment ? (validSrc % sourceUnpackAlignment) : 0;
1754 int srcStride = remainder ? (validSrc + sourceUnpackAlignment - remainder) : validSrc;
1756 DataFormat dstDataFormat = getDataFormat(destinationFormat, destinationType);
1757 int dstStride = width * TexelBytesForFormat(dstDataFormat);
1759 destinationData = static_cast<uint8_t*>(destinationData) + dstStride*(height - 1);
1760 dstStride = -dstStride;
1762 if (!HasAlpha(sourceDataFormat) || !HasColor(sourceDataFormat) || !HasColor(dstDataFormat))
1763 alphaOp = AlphaDoNothing;
1765 if (sourceDataFormat == dstDataFormat && alphaOp == AlphaDoNothing) {
1766 const uint8_t* ptr = sourceData;
1767 const uint8_t* ptrEnd = sourceData + srcStride * height;
1768 unsigned rowSize = (dstStride > 0) ? dstStride: -dstStride;
1769 uint8_t* dst = static_cast<uint8_t*>(destinationData);
1770 while (ptr < ptrEnd) {
1771 memcpy(dst, ptr, rowSize);
1778 FormatConverter converter(width, height, sourceData, destinationData, srcStride, dstStride);
1779 converter.convert(sourceDataFormat, dstDataFormat, alphaOp);
1780 if (!converter.Success())
1785 } // namespace blink