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 *componentsPerPixel = 3;
1459 case GL_BGRA_EXT: // GL_EXT_texture_format_BGRA8888
1460 *componentsPerPixel = 4;
1466 case GL_UNSIGNED_BYTE:
1467 *bytesPerComponent = sizeof(GLubyte);
1469 case GL_UNSIGNED_SHORT:
1470 *bytesPerComponent = sizeof(GLushort);
1472 case GL_UNSIGNED_SHORT_5_6_5:
1473 case GL_UNSIGNED_SHORT_4_4_4_4:
1474 case GL_UNSIGNED_SHORT_5_5_5_1:
1475 *componentsPerPixel = 1;
1476 *bytesPerComponent = sizeof(GLushort);
1478 case GL_UNSIGNED_INT_24_8_OES:
1479 case GL_UNSIGNED_INT:
1480 *bytesPerComponent = sizeof(GLuint);
1482 case GL_FLOAT: // OES_texture_float
1483 *bytesPerComponent = sizeof(GLfloat);
1485 case GL_HALF_FLOAT_OES: // OES_texture_half_float
1486 *bytesPerComponent = sizeof(GLushort);
1494 GLenum WebGLImageConversion::computeImageSizeInBytes(GLenum format, GLenum type, GLsizei width, GLsizei height, GLint alignment, unsigned* imageSizeInBytes, unsigned* paddingInBytes)
1496 ASSERT(imageSizeInBytes);
1497 ASSERT(alignment == 1 || alignment == 2 || alignment == 4 || alignment == 8);
1498 if (width < 0 || height < 0)
1499 return GL_INVALID_VALUE;
1500 unsigned bytesPerComponent, componentsPerPixel;
1501 if (!computeFormatAndTypeParameters(format, type, &bytesPerComponent, &componentsPerPixel))
1502 return GL_INVALID_ENUM;
1503 if (!width || !height) {
1504 *imageSizeInBytes = 0;
1506 *paddingInBytes = 0;
1509 CheckedInt<uint32_t> checkedValue(bytesPerComponent * componentsPerPixel);
1510 checkedValue *= width;
1511 if (!checkedValue.isValid())
1512 return GL_INVALID_VALUE;
1513 unsigned validRowSize = checkedValue.value();
1514 unsigned padding = 0;
1515 unsigned residual = validRowSize % alignment;
1517 padding = alignment - residual;
1518 checkedValue += padding;
1520 // Last row needs no padding.
1521 checkedValue *= (height - 1);
1522 checkedValue += validRowSize;
1523 if (!checkedValue.isValid())
1524 return GL_INVALID_VALUE;
1525 *imageSizeInBytes = checkedValue.value();
1527 *paddingInBytes = padding;
1531 WebGLImageConversion::ImageExtractor::ImageExtractor(Image* image, ImageHtmlDomSource imageHtmlDomSource, bool premultiplyAlpha, bool ignoreGammaAndColorProfile)
1534 m_imageHtmlDomSource = imageHtmlDomSource;
1535 m_extractSucceeded = extractImage(premultiplyAlpha, ignoreGammaAndColorProfile);
1538 WebGLImageConversion::ImageExtractor::~ImageExtractor()
1541 m_skiaImage->bitmap().unlockPixels();
1544 bool WebGLImageConversion::ImageExtractor::extractImage(bool premultiplyAlpha, bool ignoreGammaAndColorProfile)
1548 m_skiaImage = m_image->nativeImageForCurrentFrame();
1549 m_alphaOp = AlphaDoNothing;
1550 bool hasAlpha = m_skiaImage ? !m_skiaImage->bitmap().isOpaque() : true;
1551 if ((!m_skiaImage || ignoreGammaAndColorProfile || (hasAlpha && !premultiplyAlpha)) && m_image->data()) {
1552 // Attempt to get raw unpremultiplied image data.
1553 OwnPtr<ImageDecoder> decoder(ImageDecoder::create(
1554 *(m_image->data()), ImageSource::AlphaNotPremultiplied,
1555 ignoreGammaAndColorProfile ? ImageSource::GammaAndColorProfileIgnored : ImageSource::GammaAndColorProfileApplied));
1558 decoder->setData(m_image->data(), true);
1559 if (!decoder->frameCount())
1561 ImageFrame* frame = decoder->frameBufferAtIndex(0);
1562 if (!frame || frame->status() != ImageFrame::FrameComplete)
1564 hasAlpha = frame->hasAlpha();
1565 m_nativeImage = frame->asNewNativeImage();
1566 if (!m_nativeImage.get() || !m_nativeImage->isDataComplete() || !m_nativeImage->bitmap().width() || !m_nativeImage->bitmap().height())
1568 if (m_nativeImage->bitmap().colorType() != kN32_SkColorType)
1570 m_skiaImage = m_nativeImage.get();
1571 if (hasAlpha && premultiplyAlpha)
1572 m_alphaOp = AlphaDoPremultiply;
1573 } else if (!premultiplyAlpha && hasAlpha) {
1574 // 1. For texImage2D with HTMLVideoElment input, assume no PremultiplyAlpha had been applied and the alpha value for each pixel is 0xFF
1575 // which is true at present and may be changed in the future and needs adjustment accordingly.
1576 // 2. For texImage2D with HTMLCanvasElement input in which Alpha is already Premultiplied in this port,
1577 // do AlphaDoUnmultiply if UNPACK_PREMULTIPLY_ALPHA_WEBGL is set to false.
1578 if (m_imageHtmlDomSource != HtmlDomVideo)
1579 m_alphaOp = AlphaDoUnmultiply;
1584 m_imageSourceFormat = SK_B32_SHIFT ? DataFormatRGBA8 : DataFormatBGRA8;
1585 m_imageWidth = m_skiaImage->bitmap().width();
1586 m_imageHeight = m_skiaImage->bitmap().height();
1587 if (!m_imageWidth || !m_imageHeight) {
1588 m_skiaImage.clear();
1591 // Fail if the image was downsampled because of memory limits.
1592 if (m_imageWidth != (unsigned)m_image->size().width() || m_imageHeight != (unsigned)m_image->size().height()) {
1593 m_skiaImage.clear();
1596 m_imageSourceUnpackAlignment = 0;
1597 m_skiaImage->bitmap().lockPixels();
1598 m_imagePixelData = m_skiaImage->bitmap().getPixels();
1602 unsigned WebGLImageConversion::getClearBitsByFormat(GLenum format)
1607 case GL_LUMINANCE_ALPHA:
1613 return GL_COLOR_BUFFER_BIT;
1614 case GL_DEPTH_COMPONENT16:
1615 case GL_DEPTH_COMPONENT:
1616 return GL_DEPTH_BUFFER_BIT;
1617 case GL_STENCIL_INDEX8:
1618 return GL_STENCIL_BUFFER_BIT;
1619 case GL_DEPTH_STENCIL_OES:
1620 return GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
1626 unsigned WebGLImageConversion::getChannelBitsByFormat(GLenum format)
1630 return ChannelAlpha;
1633 case GL_LUMINANCE_ALPHA:
1642 case GL_DEPTH_COMPONENT16:
1643 case GL_DEPTH_COMPONENT:
1644 return ChannelDepth;
1645 case GL_STENCIL_INDEX8:
1646 return ChannelStencil;
1647 case GL_DEPTH_STENCIL_OES:
1648 return ChannelDepth | ChannelStencil;
1654 bool WebGLImageConversion::packImageData(
1661 DataFormat sourceFormat,
1664 unsigned sourceUnpackAlignment,
1665 Vector<uint8_t>& data)
1670 unsigned packedSize;
1671 // Output data is tightly packed (alignment == 1).
1672 if (computeImageSizeInBytes(format, type, width, height, 1, &packedSize, 0) != GL_NO_ERROR)
1674 data.resize(packedSize);
1676 if (!packPixels(reinterpret_cast<const uint8_t*>(pixels), sourceFormat, width, height, sourceUnpackAlignment, format, type, alphaOp, data.data(), flipY))
1678 if (ImageObserver *observer = image->imageObserver())
1679 observer->didDraw(image);
1683 bool WebGLImageConversion::extractImageData(
1684 const uint8_t* imageData,
1685 const IntSize& imageDataSize,
1689 bool premultiplyAlpha,
1690 Vector<uint8_t>& data)
1694 int width = imageDataSize.width();
1695 int height = imageDataSize.height();
1697 unsigned packedSize;
1698 // Output data is tightly packed (alignment == 1).
1699 if (computeImageSizeInBytes(format, type, width, height, 1, &packedSize, 0) != GL_NO_ERROR)
1701 data.resize(packedSize);
1703 if (!packPixels(imageData, DataFormatRGBA8, width, height, 0, format, type, premultiplyAlpha ? AlphaDoPremultiply : AlphaDoNothing, data.data(), flipY))
1709 bool WebGLImageConversion::extractTextureData(
1712 GLenum format, GLenum type,
1713 unsigned unpackAlignment,
1714 bool flipY, bool premultiplyAlpha,
1716 Vector<uint8_t>& data)
1718 // Assumes format, type, etc. have already been validated.
1719 DataFormat sourceDataFormat = getDataFormat(format, type);
1721 // Resize the output buffer.
1722 unsigned int componentsPerPixel, bytesPerComponent;
1723 if (!computeFormatAndTypeParameters(format, type, &componentsPerPixel, &bytesPerComponent))
1725 unsigned bytesPerPixel = componentsPerPixel * bytesPerComponent;
1726 data.resize(width * height * bytesPerPixel);
1728 if (!packPixels(static_cast<const uint8_t*>(pixels), sourceDataFormat, width, height, unpackAlignment, format, type, (premultiplyAlpha ? AlphaDoPremultiply : AlphaDoNothing), data.data(), flipY))
1734 bool WebGLImageConversion::packPixels(
1735 const uint8_t* sourceData,
1736 DataFormat sourceDataFormat,
1739 unsigned sourceUnpackAlignment,
1740 unsigned destinationFormat,
1741 unsigned destinationType,
1743 void* destinationData,
1746 int validSrc = width * TexelBytesForFormat(sourceDataFormat);
1747 int remainder = sourceUnpackAlignment ? (validSrc % sourceUnpackAlignment) : 0;
1748 int srcStride = remainder ? (validSrc + sourceUnpackAlignment - remainder) : validSrc;
1750 DataFormat dstDataFormat = getDataFormat(destinationFormat, destinationType);
1751 int dstStride = width * TexelBytesForFormat(dstDataFormat);
1753 destinationData = static_cast<uint8_t*>(destinationData) + dstStride*(height - 1);
1754 dstStride = -dstStride;
1756 if (!HasAlpha(sourceDataFormat) || !HasColor(sourceDataFormat) || !HasColor(dstDataFormat))
1757 alphaOp = AlphaDoNothing;
1759 if (sourceDataFormat == dstDataFormat && alphaOp == AlphaDoNothing) {
1760 const uint8_t* ptr = sourceData;
1761 const uint8_t* ptrEnd = sourceData + srcStride * height;
1762 unsigned rowSize = (dstStride > 0) ? dstStride: -dstStride;
1763 uint8_t* dst = static_cast<uint8_t*>(destinationData);
1764 while (ptr < ptrEnd) {
1765 memcpy(dst, ptr, rowSize);
1772 FormatConverter converter(width, height, sourceData, destinationData, srcStride, dstStride);
1773 converter.convert(sourceDataFormat, dstDataFormat, alphaOp);
1774 if (!converter.Success())
1779 } // namespace blink