| OLD | NEW |
| (Empty) |
| 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. | |
| 4 | |
| 5 #include "sky/engine/platform/graphics/gpu/WebGLImageConversion.h" | |
| 6 | |
| 7 #include "platform/image-decoders/ImageDecoder.h" | |
| 8 #include "sky/engine/platform/CheckedInt.h" | |
| 9 #include "sky/engine/platform/graphics/ImageObserver.h" | |
| 10 #include "sky/engine/platform/graphics/cpu/arm/WebGLImageConversionNEON.h" | |
| 11 #include "sky/engine/wtf/OwnPtr.h" | |
| 12 #include "sky/engine/wtf/PassOwnPtr.h" | |
| 13 | |
| 14 namespace blink { | |
| 15 | |
| 16 namespace { | |
| 17 | |
| 18 WebGLImageConversion::DataFormat getDataFormat(GLenum destinationFormat, GLenum
destinationType) | |
| 19 { | |
| 20 WebGLImageConversion::DataFormat dstFormat = WebGLImageConversion::DataForma
tRGBA8; | |
| 21 switch (destinationType) { | |
| 22 case GL_UNSIGNED_BYTE: | |
| 23 switch (destinationFormat) { | |
| 24 case GL_RGB: | |
| 25 dstFormat = WebGLImageConversion::DataFormatRGB8; | |
| 26 break; | |
| 27 case GL_RGBA: | |
| 28 dstFormat = WebGLImageConversion::DataFormatRGBA8; | |
| 29 break; | |
| 30 case GL_ALPHA: | |
| 31 dstFormat = WebGLImageConversion::DataFormatA8; | |
| 32 break; | |
| 33 case GL_LUMINANCE: | |
| 34 dstFormat = WebGLImageConversion::DataFormatR8; | |
| 35 break; | |
| 36 case GL_LUMINANCE_ALPHA: | |
| 37 dstFormat = WebGLImageConversion::DataFormatRA8; | |
| 38 break; | |
| 39 default: | |
| 40 ASSERT_NOT_REACHED(); | |
| 41 } | |
| 42 break; | |
| 43 case GL_UNSIGNED_SHORT_4_4_4_4: | |
| 44 dstFormat = WebGLImageConversion::DataFormatRGBA4444; | |
| 45 break; | |
| 46 case GL_UNSIGNED_SHORT_5_5_5_1: | |
| 47 dstFormat = WebGLImageConversion::DataFormatRGBA5551; | |
| 48 break; | |
| 49 case GL_UNSIGNED_SHORT_5_6_5: | |
| 50 dstFormat = WebGLImageConversion::DataFormatRGB565; | |
| 51 break; | |
| 52 case GL_HALF_FLOAT_OES: // OES_texture_half_float | |
| 53 switch (destinationFormat) { | |
| 54 case GL_RGB: | |
| 55 dstFormat = WebGLImageConversion::DataFormatRGB16F; | |
| 56 break; | |
| 57 case GL_RGBA: | |
| 58 dstFormat = WebGLImageConversion::DataFormatRGBA16F; | |
| 59 break; | |
| 60 case GL_ALPHA: | |
| 61 dstFormat = WebGLImageConversion::DataFormatA16F; | |
| 62 break; | |
| 63 case GL_LUMINANCE: | |
| 64 dstFormat = WebGLImageConversion::DataFormatR16F; | |
| 65 break; | |
| 66 case GL_LUMINANCE_ALPHA: | |
| 67 dstFormat = WebGLImageConversion::DataFormatRA16F; | |
| 68 break; | |
| 69 default: | |
| 70 ASSERT_NOT_REACHED(); | |
| 71 } | |
| 72 break; | |
| 73 case GL_FLOAT: // OES_texture_float | |
| 74 switch (destinationFormat) { | |
| 75 case GL_RGB: | |
| 76 dstFormat = WebGLImageConversion::DataFormatRGB32F; | |
| 77 break; | |
| 78 case GL_RGBA: | |
| 79 dstFormat = WebGLImageConversion::DataFormatRGBA32F; | |
| 80 break; | |
| 81 case GL_ALPHA: | |
| 82 dstFormat = WebGLImageConversion::DataFormatA32F; | |
| 83 break; | |
| 84 case GL_LUMINANCE: | |
| 85 dstFormat = WebGLImageConversion::DataFormatR32F; | |
| 86 break; | |
| 87 case GL_LUMINANCE_ALPHA: | |
| 88 dstFormat = WebGLImageConversion::DataFormatRA32F; | |
| 89 break; | |
| 90 default: | |
| 91 ASSERT_NOT_REACHED(); | |
| 92 } | |
| 93 break; | |
| 94 default: | |
| 95 ASSERT_NOT_REACHED(); | |
| 96 } | |
| 97 return dstFormat; | |
| 98 } | |
| 99 | |
| 100 // Following Float to Half-Float converion code is from the implementation of ft
p://www.fox-toolkit.org/pub/fasthalffloatconversion.pdf, | |
| 101 // "Fast Half Float Conversions" by Jeroen van der Zijp, November 2008 (Revised
September 2010). | |
| 102 // Specially, the basetable[512] and shifttable[512] are generated as follows: | |
| 103 /* | |
| 104 unsigned short basetable[512]; | |
| 105 unsigned char shifttable[512]; | |
| 106 | |
| 107 void generatetables(){ | |
| 108 unsigned int i; | |
| 109 int e; | |
| 110 for (i = 0; i < 256; ++i){ | |
| 111 e = i - 127; | |
| 112 if (e < -24){ // Very small numbers map to zero | |
| 113 basetable[i | 0x000] = 0x0000; | |
| 114 basetable[i | 0x100] = 0x8000; | |
| 115 shifttable[i | 0x000] = 24; | |
| 116 shifttable[i | 0x100] = 24; | |
| 117 } | |
| 118 else if (e < -14) { // Small numbers map to denorms | |
| 119 basetable[i | 0x000] = (0x0400>>(-e-14)); | |
| 120 basetable[i | 0x100] = (0x0400>>(-e-14)) | 0x8000; | |
| 121 shifttable[i | 0x000] = -e-1; | |
| 122 shifttable[i | 0x100] = -e-1; | |
| 123 } | |
| 124 else if (e <= 15){ // Normal numbers just lose precision | |
| 125 basetable[i | 0x000] = ((e+15)<<10); | |
| 126 basetable[i| 0x100] = ((e+15)<<10) | 0x8000; | |
| 127 shifttable[i|0x000] = 13; | |
| 128 shifttable[i|0x100] = 13; | |
| 129 } | |
| 130 else if (e<128){ // Large numbers map to Infinity | |
| 131 basetable[i|0x000] = 0x7C00; | |
| 132 basetable[i|0x100] = 0xFC00; | |
| 133 shifttable[i|0x000] = 24; | |
| 134 shifttable[i|0x100] = 24; | |
| 135 } | |
| 136 else { // Infinity and NaN's stay Infinity and NaN's | |
| 137 basetable[i|0x000] = 0x7C00; | |
| 138 basetable[i|0x100] = 0xFC00; | |
| 139 shifttable[i|0x000] = 13; | |
| 140 shifttable[i|0x100] = 13; | |
| 141 } | |
| 142 } | |
| 143 } | |
| 144 */ | |
| 145 | |
| 146 unsigned short baseTable[512] = { | |
| 147 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, | |
| 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, 1, 2, 4,
8, 16, 32, 64, 128, 256, | |
| 154 512, 1024, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216,
10240, 11264, 12288, 13312, 14336, 15360, | |
| 155 16384, 17408, 18432, 19456, 20480, 21504, 22528, 23552, 24576, 25600,
26624, 27648, 28672, 29696, 30720, 31744, | |
| 156 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
31744, 31744, 31744, 31744, 31744, 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 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
32768, 32768, 32768, 32768, 32768, 32768, | |
| 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, 32769, 32770, 32772,
32776, 32784, 32800, 32832, 32896, 33024, | |
| 170 33280, 33792, 34816, 35840, 36864, 37888, 38912, 39936, 40960, 41984,
43008, 44032, 45056, 46080, 47104, 48128, | |
| 171 49152, 50176, 51200, 52224, 53248, 54272, 55296, 56320, 57344, 58368,
59392, 60416, 61440, 62464, 63488, 64512, | |
| 172 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
64512, 64512, 64512, 64512, 64512, 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 }; | |
| 180 | |
| 181 unsigned char shiftTable[512] = { | |
| 182 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, | |
| 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, 23, 22, 21,
20, 19, 18, 17, 16, 15, | |
| 189 14, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, | |
| 190 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 24, | |
| 191 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 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, 13, | |
| 198 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, | |
| 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, 23, 22, 21,
20, 19, 18, 17, 16, 15, | |
| 205 14, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, | |
| 206 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 24, | |
| 207 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 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, 13 | |
| 214 }; | |
| 215 | |
| 216 unsigned short convertFloatToHalfFloat(float f) | |
| 217 { | |
| 218 unsigned temp = *(reinterpret_cast<unsigned *>(&f)); | |
| 219 unsigned signexp = (temp >> 23) & 0x1ff; | |
| 220 return baseTable[signexp] + ((temp & 0x007fffff) >> shiftTable[signexp]); | |
| 221 } | |
| 222 | |
| 223 /* BEGIN CODE SHARED WITH MOZILLA FIREFOX */ | |
| 224 | |
| 225 // The following packing and unpacking routines are expressed in terms of functi
on templates and inline functions to achieve generality and speedup. | |
| 226 // Explicit template specializations correspond to the cases that would occur. | |
| 227 // Some code are merged back from Mozilla code in http://mxr.mozilla.org/mozilla
-central/source/content/canvas/src/WebGLTexelConversions.h | |
| 228 | |
| 229 //---------------------------------------------------------------------- | |
| 230 // Pixel unpacking routines. | |
| 231 template<int format, typename SourceType, typename DstType> | |
| 232 void unpack(const SourceType*, DstType*, unsigned) | |
| 233 { | |
| 234 ASSERT_NOT_REACHED(); | |
| 235 } | |
| 236 | |
| 237 template<> void unpack<WebGLImageConversion::DataFormatRGB8, uint8_t, uint8_t>(c
onst uint8_t* source, uint8_t* destination, unsigned pixelsPerRow) | |
| 238 { | |
| 239 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 240 destination[0] = source[0]; | |
| 241 destination[1] = source[1]; | |
| 242 destination[2] = source[2]; | |
| 243 destination[3] = 0xFF; | |
| 244 source += 3; | |
| 245 destination += 4; | |
| 246 } | |
| 247 } | |
| 248 | |
| 249 template<> void unpack<WebGLImageConversion::DataFormatBGR8, uint8_t, uint8_t>(c
onst uint8_t* source, uint8_t* destination, unsigned pixelsPerRow) | |
| 250 { | |
| 251 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 252 destination[0] = source[2]; | |
| 253 destination[1] = source[1]; | |
| 254 destination[2] = source[0]; | |
| 255 destination[3] = 0xFF; | |
| 256 source += 3; | |
| 257 destination += 4; | |
| 258 } | |
| 259 } | |
| 260 | |
| 261 template<> void unpack<WebGLImageConversion::DataFormatARGB8, uint8_t, uint8_t>(
const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow) | |
| 262 { | |
| 263 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 264 destination[0] = source[1]; | |
| 265 destination[1] = source[2]; | |
| 266 destination[2] = source[3]; | |
| 267 destination[3] = source[0]; | |
| 268 source += 4; | |
| 269 destination += 4; | |
| 270 } | |
| 271 } | |
| 272 | |
| 273 template<> void unpack<WebGLImageConversion::DataFormatABGR8, uint8_t, uint8_t>(
const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow) | |
| 274 { | |
| 275 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 276 destination[0] = source[3]; | |
| 277 destination[1] = source[2]; | |
| 278 destination[2] = source[1]; | |
| 279 destination[3] = source[0]; | |
| 280 source += 4; | |
| 281 destination += 4; | |
| 282 } | |
| 283 } | |
| 284 | |
| 285 template<> void unpack<WebGLImageConversion::DataFormatBGRA8, uint8_t, uint8_t>(
const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow) | |
| 286 { | |
| 287 const uint32_t* source32 = reinterpret_cast_ptr<const uint32_t*>(source); | |
| 288 uint32_t* destination32 = reinterpret_cast_ptr<uint32_t*>(destination); | |
| 289 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 290 uint32_t bgra = source32[i]; | |
| 291 #if CPU(BIG_ENDIAN) | |
| 292 uint32_t brMask = 0xff00ff00; | |
| 293 uint32_t gaMask = 0x00ff00ff; | |
| 294 #else | |
| 295 uint32_t brMask = 0x00ff00ff; | |
| 296 uint32_t gaMask = 0xff00ff00; | |
| 297 #endif | |
| 298 uint32_t rgba = (((bgra >> 16) | (bgra << 16)) & brMask) | (bgra & gaMas
k); | |
| 299 destination32[i] = rgba; | |
| 300 } | |
| 301 } | |
| 302 | |
| 303 template<> void unpack<WebGLImageConversion::DataFormatRGBA5551, uint16_t, uint8
_t>(const uint16_t* source, uint8_t* destination, unsigned pixelsPerRow) | |
| 304 { | |
| 305 #if HAVE(ARM_NEON_INTRINSICS) | |
| 306 SIMD::unpackOneRowOfRGBA5551ToRGBA8(source, destination, pixelsPerRow); | |
| 307 #endif | |
| 308 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 309 uint16_t packedValue = source[0]; | |
| 310 uint8_t r = packedValue >> 11; | |
| 311 uint8_t g = (packedValue >> 6) & 0x1F; | |
| 312 uint8_t b = (packedValue >> 1) & 0x1F; | |
| 313 destination[0] = (r << 3) | (r & 0x7); | |
| 314 destination[1] = (g << 3) | (g & 0x7); | |
| 315 destination[2] = (b << 3) | (b & 0x7); | |
| 316 destination[3] = (packedValue & 0x1) ? 0xFF : 0x0; | |
| 317 source += 1; | |
| 318 destination += 4; | |
| 319 } | |
| 320 } | |
| 321 | |
| 322 template<> void unpack<WebGLImageConversion::DataFormatRGBA4444, uint16_t, uint8
_t>(const uint16_t* source, uint8_t* destination, unsigned pixelsPerRow) | |
| 323 { | |
| 324 #if HAVE(ARM_NEON_INTRINSICS) | |
| 325 SIMD::unpackOneRowOfRGBA4444ToRGBA8(source, destination, pixelsPerRow); | |
| 326 #endif | |
| 327 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 328 uint16_t packedValue = source[0]; | |
| 329 uint8_t r = packedValue >> 12; | |
| 330 uint8_t g = (packedValue >> 8) & 0x0F; | |
| 331 uint8_t b = (packedValue >> 4) & 0x0F; | |
| 332 uint8_t a = packedValue & 0x0F; | |
| 333 destination[0] = r << 4 | r; | |
| 334 destination[1] = g << 4 | g; | |
| 335 destination[2] = b << 4 | b; | |
| 336 destination[3] = a << 4 | a; | |
| 337 source += 1; | |
| 338 destination += 4; | |
| 339 } | |
| 340 } | |
| 341 | |
| 342 template<> void unpack<WebGLImageConversion::DataFormatRGB565, uint16_t, uint8_t
>(const uint16_t* source, uint8_t* destination, unsigned pixelsPerRow) | |
| 343 { | |
| 344 #if HAVE(ARM_NEON_INTRINSICS) | |
| 345 SIMD::unpackOneRowOfRGB565ToRGBA8(source, destination, pixelsPerRow); | |
| 346 #endif | |
| 347 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 348 uint16_t packedValue = source[0]; | |
| 349 uint8_t r = packedValue >> 11; | |
| 350 uint8_t g = (packedValue >> 5) & 0x3F; | |
| 351 uint8_t b = packedValue & 0x1F; | |
| 352 destination[0] = (r << 3) | (r & 0x7); | |
| 353 destination[1] = (g << 2) | (g & 0x3); | |
| 354 destination[2] = (b << 3) | (b & 0x7); | |
| 355 destination[3] = 0xFF; | |
| 356 source += 1; | |
| 357 destination += 4; | |
| 358 } | |
| 359 } | |
| 360 | |
| 361 template<> void unpack<WebGLImageConversion::DataFormatR8, uint8_t, uint8_t>(con
st uint8_t* source, uint8_t* destination, unsigned pixelsPerRow) | |
| 362 { | |
| 363 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 364 destination[0] = source[0]; | |
| 365 destination[1] = source[0]; | |
| 366 destination[2] = source[0]; | |
| 367 destination[3] = 0xFF; | |
| 368 source += 1; | |
| 369 destination += 4; | |
| 370 } | |
| 371 } | |
| 372 | |
| 373 template<> void unpack<WebGLImageConversion::DataFormatRA8, uint8_t, uint8_t>(co
nst uint8_t* source, uint8_t* destination, unsigned pixelsPerRow) | |
| 374 { | |
| 375 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 376 destination[0] = source[0]; | |
| 377 destination[1] = source[0]; | |
| 378 destination[2] = source[0]; | |
| 379 destination[3] = source[1]; | |
| 380 source += 2; | |
| 381 destination += 4; | |
| 382 } | |
| 383 } | |
| 384 | |
| 385 template<> void unpack<WebGLImageConversion::DataFormatAR8, uint8_t, uint8_t>(co
nst uint8_t* source, uint8_t* destination, unsigned pixelsPerRow) | |
| 386 { | |
| 387 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 388 destination[0] = source[1]; | |
| 389 destination[1] = source[1]; | |
| 390 destination[2] = source[1]; | |
| 391 destination[3] = source[0]; | |
| 392 source += 2; | |
| 393 destination += 4; | |
| 394 } | |
| 395 } | |
| 396 | |
| 397 template<> void unpack<WebGLImageConversion::DataFormatA8, uint8_t, uint8_t>(con
st uint8_t* source, uint8_t* destination, unsigned pixelsPerRow) | |
| 398 { | |
| 399 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 400 destination[0] = 0x0; | |
| 401 destination[1] = 0x0; | |
| 402 destination[2] = 0x0; | |
| 403 destination[3] = source[0]; | |
| 404 source += 1; | |
| 405 destination += 4; | |
| 406 } | |
| 407 } | |
| 408 | |
| 409 template<> void unpack<WebGLImageConversion::DataFormatRGBA8, uint8_t, float>(co
nst uint8_t* source, float* destination, unsigned pixelsPerRow) | |
| 410 { | |
| 411 const float scaleFactor = 1.0f / 255.0f; | |
| 412 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 413 destination[0] = source[0] * scaleFactor; | |
| 414 destination[1] = source[1] * scaleFactor; | |
| 415 destination[2] = source[2] * scaleFactor; | |
| 416 destination[3] = source[3] * scaleFactor; | |
| 417 source += 4; | |
| 418 destination += 4; | |
| 419 } | |
| 420 } | |
| 421 | |
| 422 template<> void unpack<WebGLImageConversion::DataFormatBGRA8, uint8_t, float>(co
nst uint8_t* source, float* destination, unsigned pixelsPerRow) | |
| 423 { | |
| 424 const float scaleFactor = 1.0f / 255.0f; | |
| 425 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 426 destination[0] = source[2] * scaleFactor; | |
| 427 destination[1] = source[1] * scaleFactor; | |
| 428 destination[2] = source[0] * scaleFactor; | |
| 429 destination[3] = source[3] * scaleFactor; | |
| 430 source += 4; | |
| 431 destination += 4; | |
| 432 } | |
| 433 } | |
| 434 | |
| 435 template<> void unpack<WebGLImageConversion::DataFormatABGR8, uint8_t, float>(co
nst uint8_t* source, float* destination, unsigned pixelsPerRow) | |
| 436 { | |
| 437 const float scaleFactor = 1.0f / 255.0f; | |
| 438 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 439 destination[0] = source[3] * scaleFactor; | |
| 440 destination[1] = source[2] * scaleFactor; | |
| 441 destination[2] = source[1] * scaleFactor; | |
| 442 destination[3] = source[0] * scaleFactor; | |
| 443 source += 4; | |
| 444 destination += 4; | |
| 445 } | |
| 446 } | |
| 447 | |
| 448 template<> void unpack<WebGLImageConversion::DataFormatARGB8, uint8_t, float>(co
nst uint8_t* source, float* destination, unsigned pixelsPerRow) | |
| 449 { | |
| 450 const float scaleFactor = 1.0f / 255.0f; | |
| 451 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 452 destination[0] = source[1] * scaleFactor; | |
| 453 destination[1] = source[2] * scaleFactor; | |
| 454 destination[2] = source[3] * scaleFactor; | |
| 455 destination[3] = source[0] * scaleFactor; | |
| 456 source += 4; | |
| 457 destination += 4; | |
| 458 } | |
| 459 } | |
| 460 | |
| 461 template<> void unpack<WebGLImageConversion::DataFormatRGB8, uint8_t, float>(con
st uint8_t* source, float* destination, unsigned pixelsPerRow) | |
| 462 { | |
| 463 const float scaleFactor = 1.0f / 255.0f; | |
| 464 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 465 destination[0] = source[0] * scaleFactor; | |
| 466 destination[1] = source[1] * scaleFactor; | |
| 467 destination[2] = source[2] * scaleFactor; | |
| 468 destination[3] = 1; | |
| 469 source += 3; | |
| 470 destination += 4; | |
| 471 } | |
| 472 } | |
| 473 | |
| 474 template<> void unpack<WebGLImageConversion::DataFormatBGR8, uint8_t, float>(con
st uint8_t* source, float* destination, unsigned pixelsPerRow) | |
| 475 { | |
| 476 const float scaleFactor = 1.0f / 255.0f; | |
| 477 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 478 destination[0] = source[2] * scaleFactor; | |
| 479 destination[1] = source[1] * scaleFactor; | |
| 480 destination[2] = source[0] * scaleFactor; | |
| 481 destination[3] = 1; | |
| 482 source += 3; | |
| 483 destination += 4; | |
| 484 } | |
| 485 } | |
| 486 | |
| 487 template<> void unpack<WebGLImageConversion::DataFormatRGB32F, float, float>(con
st float* source, float* destination, unsigned pixelsPerRow) | |
| 488 { | |
| 489 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 490 destination[0] = source[0]; | |
| 491 destination[1] = source[1]; | |
| 492 destination[2] = source[2]; | |
| 493 destination[3] = 1; | |
| 494 source += 3; | |
| 495 destination += 4; | |
| 496 } | |
| 497 } | |
| 498 | |
| 499 template<> void unpack<WebGLImageConversion::DataFormatR32F, float, float>(const
float* source, float* destination, unsigned pixelsPerRow) | |
| 500 { | |
| 501 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 502 destination[0] = source[0]; | |
| 503 destination[1] = source[0]; | |
| 504 destination[2] = source[0]; | |
| 505 destination[3] = 1; | |
| 506 source += 1; | |
| 507 destination += 4; | |
| 508 } | |
| 509 } | |
| 510 | |
| 511 template<> void unpack<WebGLImageConversion::DataFormatRA32F, float, float>(cons
t float* source, float* destination, unsigned pixelsPerRow) | |
| 512 { | |
| 513 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 514 destination[0] = source[0]; | |
| 515 destination[1] = source[0]; | |
| 516 destination[2] = source[0]; | |
| 517 destination[3] = source[1]; | |
| 518 source += 2; | |
| 519 destination += 4; | |
| 520 } | |
| 521 } | |
| 522 | |
| 523 template<> void unpack<WebGLImageConversion::DataFormatA32F, float, float>(const
float* source, float* destination, unsigned pixelsPerRow) | |
| 524 { | |
| 525 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 526 destination[0] = 0; | |
| 527 destination[1] = 0; | |
| 528 destination[2] = 0; | |
| 529 destination[3] = source[0]; | |
| 530 source += 1; | |
| 531 destination += 4; | |
| 532 } | |
| 533 } | |
| 534 | |
| 535 //---------------------------------------------------------------------- | |
| 536 // Pixel packing routines. | |
| 537 // | |
| 538 | |
| 539 template<int format, int alphaOp, typename SourceType, typename DstType> | |
| 540 void pack(const SourceType*, DstType*, unsigned) | |
| 541 { | |
| 542 ASSERT_NOT_REACHED(); | |
| 543 } | |
| 544 | |
| 545 template<> void pack<WebGLImageConversion::DataFormatA8, WebGLImageConversion::A
lphaDoNothing, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, un
signed pixelsPerRow) | |
| 546 { | |
| 547 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 548 destination[0] = source[3]; | |
| 549 source += 4; | |
| 550 destination += 1; | |
| 551 } | |
| 552 } | |
| 553 | |
| 554 template<> void pack<WebGLImageConversion::DataFormatR8, WebGLImageConversion::A
lphaDoNothing, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, un
signed pixelsPerRow) | |
| 555 { | |
| 556 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 557 destination[0] = source[0]; | |
| 558 source += 4; | |
| 559 destination += 1; | |
| 560 } | |
| 561 } | |
| 562 | |
| 563 template<> void pack<WebGLImageConversion::DataFormatR8, WebGLImageConversion::A
lphaDoPremultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination
, unsigned pixelsPerRow) | |
| 564 { | |
| 565 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 566 float scaleFactor = source[3] / 255.0f; | |
| 567 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s
caleFactor); | |
| 568 destination[0] = sourceR; | |
| 569 source += 4; | |
| 570 destination += 1; | |
| 571 } | |
| 572 } | |
| 573 | |
| 574 // FIXME: this routine is lossy and must be removed. | |
| 575 template<> void pack<WebGLImageConversion::DataFormatR8, WebGLImageConversion::A
lphaDoUnmultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination,
unsigned pixelsPerRow) | |
| 576 { | |
| 577 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 578 float scaleFactor = source[3] ? 255.0f / source[3] : 1.0f; | |
| 579 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s
caleFactor); | |
| 580 destination[0] = sourceR; | |
| 581 source += 4; | |
| 582 destination += 1; | |
| 583 } | |
| 584 } | |
| 585 | |
| 586 template<> void pack<WebGLImageConversion::DataFormatRA8, WebGLImageConversion::
AlphaDoNothing, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, u
nsigned pixelsPerRow) | |
| 587 { | |
| 588 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 589 destination[0] = source[0]; | |
| 590 destination[1] = source[3]; | |
| 591 source += 4; | |
| 592 destination += 2; | |
| 593 } | |
| 594 } | |
| 595 | |
| 596 template<> void pack<WebGLImageConversion::DataFormatRA8, WebGLImageConversion::
AlphaDoPremultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destinatio
n, unsigned pixelsPerRow) | |
| 597 { | |
| 598 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 599 float scaleFactor = source[3] / 255.0f; | |
| 600 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s
caleFactor); | |
| 601 destination[0] = sourceR; | |
| 602 destination[1] = source[3]; | |
| 603 source += 4; | |
| 604 destination += 2; | |
| 605 } | |
| 606 } | |
| 607 | |
| 608 // FIXME: this routine is lossy and must be removed. | |
| 609 template<> void pack<WebGLImageConversion::DataFormatRA8, WebGLImageConversion::
AlphaDoUnmultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination
, unsigned pixelsPerRow) | |
| 610 { | |
| 611 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 612 float scaleFactor = source[3] ? 255.0f / source[3] : 1.0f; | |
| 613 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s
caleFactor); | |
| 614 destination[0] = sourceR; | |
| 615 destination[1] = source[3]; | |
| 616 source += 4; | |
| 617 destination += 2; | |
| 618 } | |
| 619 } | |
| 620 | |
| 621 template<> void pack<WebGLImageConversion::DataFormatRGB8, WebGLImageConversion:
:AlphaDoNothing, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination,
unsigned pixelsPerRow) | |
| 622 { | |
| 623 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 624 destination[0] = source[0]; | |
| 625 destination[1] = source[1]; | |
| 626 destination[2] = source[2]; | |
| 627 source += 4; | |
| 628 destination += 3; | |
| 629 } | |
| 630 } | |
| 631 | |
| 632 template<> void pack<WebGLImageConversion::DataFormatRGB8, WebGLImageConversion:
:AlphaDoPremultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destinati
on, unsigned pixelsPerRow) | |
| 633 { | |
| 634 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 635 float scaleFactor = source[3] / 255.0f; | |
| 636 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s
caleFactor); | |
| 637 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * s
caleFactor); | |
| 638 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * s
caleFactor); | |
| 639 destination[0] = sourceR; | |
| 640 destination[1] = sourceG; | |
| 641 destination[2] = sourceB; | |
| 642 source += 4; | |
| 643 destination += 3; | |
| 644 } | |
| 645 } | |
| 646 | |
| 647 // FIXME: this routine is lossy and must be removed. | |
| 648 template<> void pack<WebGLImageConversion::DataFormatRGB8, WebGLImageConversion:
:AlphaDoUnmultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destinatio
n, unsigned pixelsPerRow) | |
| 649 { | |
| 650 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 651 float scaleFactor = source[3] ? 255.0f / source[3] : 1.0f; | |
| 652 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s
caleFactor); | |
| 653 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * s
caleFactor); | |
| 654 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * s
caleFactor); | |
| 655 destination[0] = sourceR; | |
| 656 destination[1] = sourceG; | |
| 657 destination[2] = sourceB; | |
| 658 source += 4; | |
| 659 destination += 3; | |
| 660 } | |
| 661 } | |
| 662 | |
| 663 | |
| 664 template<> void pack<WebGLImageConversion::DataFormatRGBA8, WebGLImageConversion
::AlphaDoNothing, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination,
unsigned pixelsPerRow) | |
| 665 { | |
| 666 memcpy(destination, source, pixelsPerRow * 4); | |
| 667 } | |
| 668 | |
| 669 template<> void pack<WebGLImageConversion::DataFormatRGBA8, WebGLImageConversion
::AlphaDoPremultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destinat
ion, unsigned pixelsPerRow) | |
| 670 { | |
| 671 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 672 float scaleFactor = source[3] / 255.0f; | |
| 673 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s
caleFactor); | |
| 674 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * s
caleFactor); | |
| 675 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * s
caleFactor); | |
| 676 destination[0] = sourceR; | |
| 677 destination[1] = sourceG; | |
| 678 destination[2] = sourceB; | |
| 679 destination[3] = source[3]; | |
| 680 source += 4; | |
| 681 destination += 4; | |
| 682 } | |
| 683 } | |
| 684 | |
| 685 // FIXME: this routine is lossy and must be removed. | |
| 686 template<> void pack<WebGLImageConversion::DataFormatRGBA8, WebGLImageConversion
::AlphaDoUnmultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destinati
on, unsigned pixelsPerRow) | |
| 687 { | |
| 688 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 689 float scaleFactor = source[3] ? 255.0f / source[3] : 1.0f; | |
| 690 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s
caleFactor); | |
| 691 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * s
caleFactor); | |
| 692 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * s
caleFactor); | |
| 693 destination[0] = sourceR; | |
| 694 destination[1] = sourceG; | |
| 695 destination[2] = sourceB; | |
| 696 destination[3] = source[3]; | |
| 697 source += 4; | |
| 698 destination += 4; | |
| 699 } | |
| 700 } | |
| 701 | |
| 702 template<> void pack<WebGLImageConversion::DataFormatRGBA4444, WebGLImageConvers
ion::AlphaDoNothing, uint8_t, uint16_t>(const uint8_t* source, uint16_t* destina
tion, unsigned pixelsPerRow) | |
| 703 { | |
| 704 #if HAVE(ARM_NEON_INTRINSICS) | |
| 705 SIMD::packOneRowOfRGBA8ToUnsignedShort4444(source, destination, pixelsPerRow
); | |
| 706 #endif | |
| 707 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 708 *destination = (((source[0] & 0xF0) << 8) | |
| 709 | ((source[1] & 0xF0) << 4) | |
| 710 | (source[2] & 0xF0) | |
| 711 | (source[3] >> 4)); | |
| 712 source += 4; | |
| 713 destination += 1; | |
| 714 } | |
| 715 } | |
| 716 | |
| 717 template<> void pack<WebGLImageConversion::DataFormatRGBA4444, WebGLImageConvers
ion::AlphaDoPremultiply, uint8_t, uint16_t>(const uint8_t* source, uint16_t* des
tination, unsigned pixelsPerRow) | |
| 718 { | |
| 719 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 720 float scaleFactor = source[3] / 255.0f; | |
| 721 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s
caleFactor); | |
| 722 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * s
caleFactor); | |
| 723 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * s
caleFactor); | |
| 724 *destination = (((sourceR & 0xF0) << 8) | |
| 725 | ((sourceG & 0xF0) << 4) | |
| 726 | (sourceB & 0xF0) | |
| 727 | (source[3] >> 4)); | |
| 728 source += 4; | |
| 729 destination += 1; | |
| 730 } | |
| 731 } | |
| 732 | |
| 733 // FIXME: this routine is lossy and must be removed. | |
| 734 template<> void pack<WebGLImageConversion::DataFormatRGBA4444, WebGLImageConvers
ion::AlphaDoUnmultiply, uint8_t, uint16_t>(const uint8_t* source, uint16_t* dest
ination, unsigned pixelsPerRow) | |
| 735 { | |
| 736 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 737 float scaleFactor = source[3] ? 255.0f / source[3] : 1.0f; | |
| 738 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s
caleFactor); | |
| 739 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * s
caleFactor); | |
| 740 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * s
caleFactor); | |
| 741 *destination = (((sourceR & 0xF0) << 8) | |
| 742 | ((sourceG & 0xF0) << 4) | |
| 743 | (sourceB & 0xF0) | |
| 744 | (source[3] >> 4)); | |
| 745 source += 4; | |
| 746 destination += 1; | |
| 747 } | |
| 748 } | |
| 749 | |
| 750 template<> void pack<WebGLImageConversion::DataFormatRGBA5551, WebGLImageConvers
ion::AlphaDoNothing, uint8_t, uint16_t>(const uint8_t* source, uint16_t* destina
tion, unsigned pixelsPerRow) | |
| 751 { | |
| 752 #if HAVE(ARM_NEON_INTRINSICS) | |
| 753 SIMD::packOneRowOfRGBA8ToUnsignedShort5551(source, destination, pixelsPerRow
); | |
| 754 #endif | |
| 755 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 756 *destination = (((source[0] & 0xF8) << 8) | |
| 757 | ((source[1] & 0xF8) << 3) | |
| 758 | ((source[2] & 0xF8) >> 2) | |
| 759 | (source[3] >> 7)); | |
| 760 source += 4; | |
| 761 destination += 1; | |
| 762 } | |
| 763 } | |
| 764 | |
| 765 template<> void pack<WebGLImageConversion::DataFormatRGBA5551, WebGLImageConvers
ion::AlphaDoPremultiply, uint8_t, uint16_t>(const uint8_t* source, uint16_t* des
tination, unsigned pixelsPerRow) | |
| 766 { | |
| 767 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 768 float scaleFactor = source[3] / 255.0f; | |
| 769 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s
caleFactor); | |
| 770 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * s
caleFactor); | |
| 771 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * s
caleFactor); | |
| 772 *destination = (((sourceR & 0xF8) << 8) | |
| 773 | ((sourceG & 0xF8) << 3) | |
| 774 | ((sourceB & 0xF8) >> 2) | |
| 775 | (source[3] >> 7)); | |
| 776 source += 4; | |
| 777 destination += 1; | |
| 778 } | |
| 779 } | |
| 780 | |
| 781 // FIXME: this routine is lossy and must be removed. | |
| 782 template<> void pack<WebGLImageConversion::DataFormatRGBA5551, WebGLImageConvers
ion::AlphaDoUnmultiply, uint8_t, uint16_t>(const uint8_t* source, uint16_t* dest
ination, unsigned pixelsPerRow) | |
| 783 { | |
| 784 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 785 float scaleFactor = source[3] ? 255.0f / source[3] : 1.0f; | |
| 786 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s
caleFactor); | |
| 787 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * s
caleFactor); | |
| 788 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * s
caleFactor); | |
| 789 *destination = (((sourceR & 0xF8) << 8) | |
| 790 | ((sourceG & 0xF8) << 3) | |
| 791 | ((sourceB & 0xF8) >> 2) | |
| 792 | (source[3] >> 7)); | |
| 793 source += 4; | |
| 794 destination += 1; | |
| 795 } | |
| 796 } | |
| 797 | |
| 798 template<> void pack<WebGLImageConversion::DataFormatRGB565, WebGLImageConversio
n::AlphaDoNothing, uint8_t, uint16_t>(const uint8_t* source, uint16_t* destinati
on, unsigned pixelsPerRow) | |
| 799 { | |
| 800 #if HAVE(ARM_NEON_INTRINSICS) | |
| 801 SIMD::packOneRowOfRGBA8ToUnsignedShort565(source, destination, pixelsPerRow)
; | |
| 802 #endif | |
| 803 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 804 *destination = (((source[0] & 0xF8) << 8) | |
| 805 | ((source[1] & 0xFC) << 3) | |
| 806 | ((source[2] & 0xF8) >> 3)); | |
| 807 source += 4; | |
| 808 destination += 1; | |
| 809 } | |
| 810 } | |
| 811 | |
| 812 template<> void pack<WebGLImageConversion::DataFormatRGB565, WebGLImageConversio
n::AlphaDoPremultiply, uint8_t, uint16_t>(const uint8_t* source, uint16_t* desti
nation, unsigned pixelsPerRow) | |
| 813 { | |
| 814 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 815 float scaleFactor = source[3] / 255.0f; | |
| 816 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s
caleFactor); | |
| 817 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * s
caleFactor); | |
| 818 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * s
caleFactor); | |
| 819 *destination = (((sourceR & 0xF8) << 8) | |
| 820 | ((sourceG & 0xFC) << 3) | |
| 821 | ((sourceB & 0xF8) >> 3)); | |
| 822 source += 4; | |
| 823 destination += 1; | |
| 824 } | |
| 825 } | |
| 826 | |
| 827 // FIXME: this routine is lossy and must be removed. | |
| 828 template<> void pack<WebGLImageConversion::DataFormatRGB565, WebGLImageConversio
n::AlphaDoUnmultiply, uint8_t, uint16_t>(const uint8_t* source, uint16_t* destin
ation, unsigned pixelsPerRow) | |
| 829 { | |
| 830 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 831 float scaleFactor = source[3] ? 255.0f / source[3] : 1.0f; | |
| 832 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s
caleFactor); | |
| 833 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * s
caleFactor); | |
| 834 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * s
caleFactor); | |
| 835 *destination = (((sourceR & 0xF8) << 8) | |
| 836 | ((sourceG & 0xFC) << 3) | |
| 837 | ((sourceB & 0xF8) >> 3)); | |
| 838 source += 4; | |
| 839 destination += 1; | |
| 840 } | |
| 841 } | |
| 842 | |
| 843 template<> void pack<WebGLImageConversion::DataFormatRGB32F, WebGLImageConversio
n::AlphaDoNothing, float, float>(const float* source, float* destination, unsign
ed pixelsPerRow) | |
| 844 { | |
| 845 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 846 destination[0] = source[0]; | |
| 847 destination[1] = source[1]; | |
| 848 destination[2] = source[2]; | |
| 849 source += 4; | |
| 850 destination += 3; | |
| 851 } | |
| 852 } | |
| 853 | |
| 854 template<> void pack<WebGLImageConversion::DataFormatRGB32F, WebGLImageConversio
n::AlphaDoPremultiply, float, float>(const float* source, float* destination, un
signed pixelsPerRow) | |
| 855 { | |
| 856 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 857 float scaleFactor = source[3]; | |
| 858 destination[0] = source[0] * scaleFactor; | |
| 859 destination[1] = source[1] * scaleFactor; | |
| 860 destination[2] = source[2] * scaleFactor; | |
| 861 source += 4; | |
| 862 destination += 3; | |
| 863 } | |
| 864 } | |
| 865 | |
| 866 template<> void pack<WebGLImageConversion::DataFormatRGB32F, WebGLImageConversio
n::AlphaDoUnmultiply, float, float>(const float* source, float* destination, uns
igned pixelsPerRow) | |
| 867 { | |
| 868 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 869 float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f; | |
| 870 destination[0] = source[0] * scaleFactor; | |
| 871 destination[1] = source[1] * scaleFactor; | |
| 872 destination[2] = source[2] * scaleFactor; | |
| 873 source += 4; | |
| 874 destination += 3; | |
| 875 } | |
| 876 } | |
| 877 | |
| 878 // Used only during RGBA8 or BGRA8 -> floating-point uploads. | |
| 879 template<> void pack<WebGLImageConversion::DataFormatRGBA32F, WebGLImageConversi
on::AlphaDoNothing, float, float>(const float* source, float* destination, unsig
ned pixelsPerRow) | |
| 880 { | |
| 881 memcpy(destination, source, pixelsPerRow * 4 * sizeof(float)); | |
| 882 } | |
| 883 | |
| 884 template<> void pack<WebGLImageConversion::DataFormatRGBA32F, WebGLImageConversi
on::AlphaDoPremultiply, float, float>(const float* source, float* destination, u
nsigned pixelsPerRow) | |
| 885 { | |
| 886 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 887 float scaleFactor = source[3]; | |
| 888 destination[0] = source[0] * scaleFactor; | |
| 889 destination[1] = source[1] * scaleFactor; | |
| 890 destination[2] = source[2] * scaleFactor; | |
| 891 destination[3] = source[3]; | |
| 892 source += 4; | |
| 893 destination += 4; | |
| 894 } | |
| 895 } | |
| 896 | |
| 897 template<> void pack<WebGLImageConversion::DataFormatRGBA32F, WebGLImageConversi
on::AlphaDoUnmultiply, float, float>(const float* source, float* destination, un
signed pixelsPerRow) | |
| 898 { | |
| 899 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 900 float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f; | |
| 901 destination[0] = source[0] * scaleFactor; | |
| 902 destination[1] = source[1] * scaleFactor; | |
| 903 destination[2] = source[2] * scaleFactor; | |
| 904 destination[3] = source[3]; | |
| 905 source += 4; | |
| 906 destination += 4; | |
| 907 } | |
| 908 } | |
| 909 | |
| 910 template<> void pack<WebGLImageConversion::DataFormatA32F, WebGLImageConversion:
:AlphaDoNothing, float, float>(const float* source, float* destination, unsigned
pixelsPerRow) | |
| 911 { | |
| 912 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 913 destination[0] = source[3]; | |
| 914 source += 4; | |
| 915 destination += 1; | |
| 916 } | |
| 917 } | |
| 918 | |
| 919 template<> void pack<WebGLImageConversion::DataFormatR32F, WebGLImageConversion:
:AlphaDoNothing, float, float>(const float* source, float* destination, unsigned
pixelsPerRow) | |
| 920 { | |
| 921 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 922 destination[0] = source[0]; | |
| 923 source += 4; | |
| 924 destination += 1; | |
| 925 } | |
| 926 } | |
| 927 | |
| 928 template<> void pack<WebGLImageConversion::DataFormatR32F, WebGLImageConversion:
:AlphaDoPremultiply, float, float>(const float* source, float* destination, unsi
gned pixelsPerRow) | |
| 929 { | |
| 930 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 931 float scaleFactor = source[3]; | |
| 932 destination[0] = source[0] * scaleFactor; | |
| 933 source += 4; | |
| 934 destination += 1; | |
| 935 } | |
| 936 } | |
| 937 | |
| 938 template<> void pack<WebGLImageConversion::DataFormatR32F, WebGLImageConversion:
:AlphaDoUnmultiply, float, float>(const float* source, float* destination, unsig
ned pixelsPerRow) | |
| 939 { | |
| 940 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 941 float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f; | |
| 942 destination[0] = source[0] * scaleFactor; | |
| 943 source += 4; | |
| 944 destination += 1; | |
| 945 } | |
| 946 } | |
| 947 | |
| 948 template<> void pack<WebGLImageConversion::DataFormatRA32F, WebGLImageConversion
::AlphaDoNothing, float, float>(const float* source, float* destination, unsigne
d pixelsPerRow) | |
| 949 { | |
| 950 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 951 destination[0] = source[0]; | |
| 952 destination[1] = source[3]; | |
| 953 source += 4; | |
| 954 destination += 2; | |
| 955 } | |
| 956 } | |
| 957 | |
| 958 template<> void pack<WebGLImageConversion::DataFormatRA32F, WebGLImageConversion
::AlphaDoPremultiply, float, float>(const float* source, float* destination, uns
igned pixelsPerRow) | |
| 959 { | |
| 960 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 961 float scaleFactor = source[3]; | |
| 962 destination[0] = source[0] * scaleFactor; | |
| 963 destination[1] = source[3]; | |
| 964 source += 4; | |
| 965 destination += 2; | |
| 966 } | |
| 967 } | |
| 968 | |
| 969 template<> void pack<WebGLImageConversion::DataFormatRA32F, WebGLImageConversion
::AlphaDoUnmultiply, float, float>(const float* source, float* destination, unsi
gned pixelsPerRow) | |
| 970 { | |
| 971 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 972 float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f; | |
| 973 destination[0] = source[0] * scaleFactor; | |
| 974 destination[1] = source[3]; | |
| 975 source += 4; | |
| 976 destination += 2; | |
| 977 } | |
| 978 } | |
| 979 | |
| 980 template<> void pack<WebGLImageConversion::DataFormatRGBA16F, WebGLImageConversi
on::AlphaDoNothing, float, uint16_t>(const float* source, uint16_t* destination,
unsigned pixelsPerRow) | |
| 981 { | |
| 982 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 983 destination[0] = convertFloatToHalfFloat(source[0]); | |
| 984 destination[1] = convertFloatToHalfFloat(source[1]); | |
| 985 destination[2] = convertFloatToHalfFloat(source[2]); | |
| 986 destination[3] = convertFloatToHalfFloat(source[3]); | |
| 987 source += 4; | |
| 988 destination += 4; | |
| 989 } | |
| 990 } | |
| 991 | |
| 992 template<> void pack<WebGLImageConversion::DataFormatRGBA16F, WebGLImageConversi
on::AlphaDoPremultiply, float, uint16_t>(const float* source, uint16_t* destinat
ion, unsigned pixelsPerRow) | |
| 993 { | |
| 994 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 995 float scaleFactor = source[3]; | |
| 996 destination[0] = convertFloatToHalfFloat(source[0] * scaleFactor); | |
| 997 destination[1] = convertFloatToHalfFloat(source[1] * scaleFactor); | |
| 998 destination[2] = convertFloatToHalfFloat(source[2] * scaleFactor); | |
| 999 destination[3] = convertFloatToHalfFloat(source[3]); | |
| 1000 source += 4; | |
| 1001 destination += 4; | |
| 1002 } | |
| 1003 } | |
| 1004 | |
| 1005 template<> void pack<WebGLImageConversion::DataFormatRGBA16F, WebGLImageConversi
on::AlphaDoUnmultiply, float, uint16_t>(const float* source, uint16_t* destinati
on, unsigned pixelsPerRow) | |
| 1006 { | |
| 1007 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 1008 float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f; | |
| 1009 destination[0] = convertFloatToHalfFloat(source[0] * scaleFactor); | |
| 1010 destination[1] = convertFloatToHalfFloat(source[1] * scaleFactor); | |
| 1011 destination[2] = convertFloatToHalfFloat(source[2] * scaleFactor); | |
| 1012 destination[3] = convertFloatToHalfFloat(source[3]); | |
| 1013 source += 4; | |
| 1014 destination += 4; | |
| 1015 } | |
| 1016 } | |
| 1017 | |
| 1018 template<> void pack<WebGLImageConversion::DataFormatRGB16F, WebGLImageConversio
n::AlphaDoNothing, float, uint16_t>(const float* source, uint16_t* destination,
unsigned pixelsPerRow) | |
| 1019 { | |
| 1020 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 1021 destination[0] = convertFloatToHalfFloat(source[0]); | |
| 1022 destination[1] = convertFloatToHalfFloat(source[1]); | |
| 1023 destination[2] = convertFloatToHalfFloat(source[2]); | |
| 1024 source += 4; | |
| 1025 destination += 3; | |
| 1026 } | |
| 1027 } | |
| 1028 | |
| 1029 template<> void pack<WebGLImageConversion::DataFormatRGB16F, WebGLImageConversio
n::AlphaDoPremultiply, float, uint16_t>(const float* source, uint16_t* destinati
on, unsigned pixelsPerRow) | |
| 1030 { | |
| 1031 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 1032 float scaleFactor = source[3]; | |
| 1033 destination[0] = convertFloatToHalfFloat(source[0] * scaleFactor); | |
| 1034 destination[1] = convertFloatToHalfFloat(source[1] * scaleFactor); | |
| 1035 destination[2] = convertFloatToHalfFloat(source[2] * scaleFactor); | |
| 1036 source += 4; | |
| 1037 destination += 3; | |
| 1038 } | |
| 1039 } | |
| 1040 | |
| 1041 template<> void pack<WebGLImageConversion::DataFormatRGB16F, WebGLImageConversio
n::AlphaDoUnmultiply, float, uint16_t>(const float* source, uint16_t* destinatio
n, unsigned pixelsPerRow) | |
| 1042 { | |
| 1043 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 1044 float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f; | |
| 1045 destination[0] = convertFloatToHalfFloat(source[0] * scaleFactor); | |
| 1046 destination[1] = convertFloatToHalfFloat(source[1] * scaleFactor); | |
| 1047 destination[2] = convertFloatToHalfFloat(source[2] * scaleFactor); | |
| 1048 source += 4; | |
| 1049 destination += 3; | |
| 1050 } | |
| 1051 } | |
| 1052 | |
| 1053 template<> void pack<WebGLImageConversion::DataFormatRA16F, WebGLImageConversion
::AlphaDoNothing, float, uint16_t>(const float* source, uint16_t* destination, u
nsigned pixelsPerRow) | |
| 1054 { | |
| 1055 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 1056 destination[0] = convertFloatToHalfFloat(source[0]); | |
| 1057 destination[1] = convertFloatToHalfFloat(source[3]); | |
| 1058 source += 4; | |
| 1059 destination += 2; | |
| 1060 } | |
| 1061 } | |
| 1062 | |
| 1063 template<> void pack<WebGLImageConversion::DataFormatRA16F, WebGLImageConversion
::AlphaDoPremultiply, float, uint16_t>(const float* source, uint16_t* destinatio
n, unsigned pixelsPerRow) | |
| 1064 { | |
| 1065 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 1066 float scaleFactor = source[3]; | |
| 1067 destination[0] = convertFloatToHalfFloat(source[0] * scaleFactor); | |
| 1068 destination[1] = convertFloatToHalfFloat(source[3]); | |
| 1069 source += 4; | |
| 1070 destination += 2; | |
| 1071 } | |
| 1072 } | |
| 1073 | |
| 1074 template<> void pack<WebGLImageConversion::DataFormatRA16F, WebGLImageConversion
::AlphaDoUnmultiply, float, uint16_t>(const float* source, uint16_t* destination
, unsigned pixelsPerRow) | |
| 1075 { | |
| 1076 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 1077 float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f; | |
| 1078 destination[0] = convertFloatToHalfFloat(source[0] * scaleFactor); | |
| 1079 destination[1] = convertFloatToHalfFloat(source[3]); | |
| 1080 source += 4; | |
| 1081 destination += 2; | |
| 1082 } | |
| 1083 } | |
| 1084 | |
| 1085 template<> void pack<WebGLImageConversion::DataFormatR16F, WebGLImageConversion:
:AlphaDoNothing, float, uint16_t>(const float* source, uint16_t* destination, un
signed pixelsPerRow) | |
| 1086 { | |
| 1087 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 1088 destination[0] = convertFloatToHalfFloat(source[0]); | |
| 1089 source += 4; | |
| 1090 destination += 1; | |
| 1091 } | |
| 1092 } | |
| 1093 | |
| 1094 template<> void pack<WebGLImageConversion::DataFormatR16F, WebGLImageConversion:
:AlphaDoPremultiply, float, uint16_t>(const float* source, uint16_t* destination
, unsigned pixelsPerRow) | |
| 1095 { | |
| 1096 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 1097 float scaleFactor = source[3]; | |
| 1098 destination[0] = convertFloatToHalfFloat(source[0] * scaleFactor); | |
| 1099 source += 4; | |
| 1100 destination += 1; | |
| 1101 } | |
| 1102 } | |
| 1103 | |
| 1104 template<> void pack<WebGLImageConversion::DataFormatR16F, WebGLImageConversion:
:AlphaDoUnmultiply, float, uint16_t>(const float* source, uint16_t* destination,
unsigned pixelsPerRow) | |
| 1105 { | |
| 1106 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 1107 float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f; | |
| 1108 destination[0] = convertFloatToHalfFloat(source[0] * scaleFactor); | |
| 1109 source += 4; | |
| 1110 destination += 1; | |
| 1111 } | |
| 1112 } | |
| 1113 | |
| 1114 template<> void pack<WebGLImageConversion::DataFormatA16F, WebGLImageConversion:
:AlphaDoNothing, float, uint16_t>(const float* source, uint16_t* destination, un
signed pixelsPerRow) | |
| 1115 { | |
| 1116 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
| 1117 destination[0] = convertFloatToHalfFloat(source[3]); | |
| 1118 source += 4; | |
| 1119 destination += 1; | |
| 1120 } | |
| 1121 } | |
| 1122 | |
| 1123 bool HasAlpha(int format) | |
| 1124 { | |
| 1125 return format == WebGLImageConversion::DataFormatA8 | |
| 1126 || format == WebGLImageConversion::DataFormatA16F | |
| 1127 || format == WebGLImageConversion::DataFormatA32F | |
| 1128 || format == WebGLImageConversion::DataFormatRA8 | |
| 1129 || format == WebGLImageConversion::DataFormatAR8 | |
| 1130 || format == WebGLImageConversion::DataFormatRA16F | |
| 1131 || format == WebGLImageConversion::DataFormatRA32F | |
| 1132 || format == WebGLImageConversion::DataFormatRGBA8 | |
| 1133 || format == WebGLImageConversion::DataFormatBGRA8 | |
| 1134 || format == WebGLImageConversion::DataFormatARGB8 | |
| 1135 || format == WebGLImageConversion::DataFormatABGR8 | |
| 1136 || format == WebGLImageConversion::DataFormatRGBA16F | |
| 1137 || format == WebGLImageConversion::DataFormatRGBA32F | |
| 1138 || format == WebGLImageConversion::DataFormatRGBA4444 | |
| 1139 || format == WebGLImageConversion::DataFormatRGBA5551; | |
| 1140 } | |
| 1141 | |
| 1142 bool HasColor(int format) | |
| 1143 { | |
| 1144 return format == WebGLImageConversion::DataFormatRGBA8 | |
| 1145 || format == WebGLImageConversion::DataFormatRGBA16F | |
| 1146 || format == WebGLImageConversion::DataFormatRGBA32F | |
| 1147 || format == WebGLImageConversion::DataFormatRGB8 | |
| 1148 || format == WebGLImageConversion::DataFormatRGB16F | |
| 1149 || format == WebGLImageConversion::DataFormatRGB32F | |
| 1150 || format == WebGLImageConversion::DataFormatBGR8 | |
| 1151 || format == WebGLImageConversion::DataFormatBGRA8 | |
| 1152 || format == WebGLImageConversion::DataFormatARGB8 | |
| 1153 || format == WebGLImageConversion::DataFormatABGR8 | |
| 1154 || format == WebGLImageConversion::DataFormatRGBA5551 | |
| 1155 || format == WebGLImageConversion::DataFormatRGBA4444 | |
| 1156 || format == WebGLImageConversion::DataFormatRGB565 | |
| 1157 || format == WebGLImageConversion::DataFormatR8 | |
| 1158 || format == WebGLImageConversion::DataFormatR16F | |
| 1159 || format == WebGLImageConversion::DataFormatR32F | |
| 1160 || format == WebGLImageConversion::DataFormatRA8 | |
| 1161 || format == WebGLImageConversion::DataFormatRA16F | |
| 1162 || format == WebGLImageConversion::DataFormatRA32F | |
| 1163 || format == WebGLImageConversion::DataFormatAR8; | |
| 1164 } | |
| 1165 | |
| 1166 template<int Format> | |
| 1167 struct IsFloatFormat { | |
| 1168 static const bool Value = | |
| 1169 Format == WebGLImageConversion::DataFormatRGBA32F | |
| 1170 || Format == WebGLImageConversion::DataFormatRGB32F | |
| 1171 || Format == WebGLImageConversion::DataFormatRA32F | |
| 1172 || Format == WebGLImageConversion::DataFormatR32F | |
| 1173 || Format == WebGLImageConversion::DataFormatA32F; | |
| 1174 }; | |
| 1175 | |
| 1176 template<int Format> | |
| 1177 struct IsHalfFloatFormat { | |
| 1178 static const bool Value = | |
| 1179 Format == WebGLImageConversion::DataFormatRGBA16F | |
| 1180 || Format == WebGLImageConversion::DataFormatRGB16F | |
| 1181 || Format == WebGLImageConversion::DataFormatRA16F | |
| 1182 || Format == WebGLImageConversion::DataFormatR16F | |
| 1183 || Format == WebGLImageConversion::DataFormatA16F; | |
| 1184 }; | |
| 1185 | |
| 1186 template<int Format> | |
| 1187 struct Is16bppFormat { | |
| 1188 static const bool Value = | |
| 1189 Format == WebGLImageConversion::DataFormatRGBA5551 | |
| 1190 || Format == WebGLImageConversion::DataFormatRGBA4444 | |
| 1191 || Format == WebGLImageConversion::DataFormatRGB565; | |
| 1192 }; | |
| 1193 | |
| 1194 template<int Format, bool IsFloat = IsFloatFormat<Format>::Value, bool IsHalfFlo
at = IsHalfFloatFormat<Format>::Value, bool Is16bpp = Is16bppFormat<Format>::Val
ue> | |
| 1195 struct DataTypeForFormat { | |
| 1196 typedef uint8_t Type; | |
| 1197 }; | |
| 1198 | |
| 1199 template<int Format> | |
| 1200 struct DataTypeForFormat<Format, true, false, false> { | |
| 1201 typedef float Type; | |
| 1202 }; | |
| 1203 | |
| 1204 template<int Format> | |
| 1205 struct DataTypeForFormat<Format, false, true, false> { | |
| 1206 typedef uint16_t Type; | |
| 1207 }; | |
| 1208 | |
| 1209 template<int Format> | |
| 1210 struct DataTypeForFormat<Format, false, false, true> { | |
| 1211 typedef uint16_t Type; | |
| 1212 }; | |
| 1213 | |
| 1214 template<int Format> | |
| 1215 struct IntermediateFormat { | |
| 1216 static const int Value = (IsFloatFormat<Format>::Value || IsHalfFloatFormat<
Format>::Value) ? WebGLImageConversion::DataFormatRGBA32F : WebGLImageConversion
::DataFormatRGBA8; | |
| 1217 }; | |
| 1218 | |
| 1219 unsigned TexelBytesForFormat(WebGLImageConversion::DataFormat format) | |
| 1220 { | |
| 1221 switch (format) { | |
| 1222 case WebGLImageConversion::DataFormatR8: | |
| 1223 case WebGLImageConversion::DataFormatA8: | |
| 1224 return 1; | |
| 1225 case WebGLImageConversion::DataFormatRA8: | |
| 1226 case WebGLImageConversion::DataFormatAR8: | |
| 1227 case WebGLImageConversion::DataFormatRGBA5551: | |
| 1228 case WebGLImageConversion::DataFormatRGBA4444: | |
| 1229 case WebGLImageConversion::DataFormatRGB565: | |
| 1230 case WebGLImageConversion::DataFormatA16F: | |
| 1231 case WebGLImageConversion::DataFormatR16F: | |
| 1232 return 2; | |
| 1233 case WebGLImageConversion::DataFormatRGB8: | |
| 1234 case WebGLImageConversion::DataFormatBGR8: | |
| 1235 return 3; | |
| 1236 case WebGLImageConversion::DataFormatRGBA8: | |
| 1237 case WebGLImageConversion::DataFormatARGB8: | |
| 1238 case WebGLImageConversion::DataFormatABGR8: | |
| 1239 case WebGLImageConversion::DataFormatBGRA8: | |
| 1240 case WebGLImageConversion::DataFormatR32F: | |
| 1241 case WebGLImageConversion::DataFormatA32F: | |
| 1242 case WebGLImageConversion::DataFormatRA16F: | |
| 1243 return 4; | |
| 1244 case WebGLImageConversion::DataFormatRGB16F: | |
| 1245 return 6; | |
| 1246 case WebGLImageConversion::DataFormatRA32F: | |
| 1247 case WebGLImageConversion::DataFormatRGBA16F: | |
| 1248 return 8; | |
| 1249 case WebGLImageConversion::DataFormatRGB32F: | |
| 1250 return 12; | |
| 1251 case WebGLImageConversion::DataFormatRGBA32F: | |
| 1252 return 16; | |
| 1253 default: | |
| 1254 return 0; | |
| 1255 } | |
| 1256 } | |
| 1257 | |
| 1258 /* END CODE SHARED WITH MOZILLA FIREFOX */ | |
| 1259 | |
| 1260 class FormatConverter { | |
| 1261 public: | |
| 1262 FormatConverter(unsigned width, unsigned height, | |
| 1263 const void* srcStart, void* dstStart, int srcStride, int dstStride) | |
| 1264 : m_width(width), m_height(height), m_srcStart(srcStart), m_dstStart(dst
Start), m_srcStride(srcStride), m_dstStride(dstStride), m_success(false) | |
| 1265 { | |
| 1266 const unsigned MaxNumberOfComponents = 4; | |
| 1267 const unsigned MaxBytesPerComponent = 4; | |
| 1268 m_unpackedIntermediateSrcData = adoptArrayPtr(new uint8_t[m_width * MaxN
umberOfComponents *MaxBytesPerComponent]); | |
| 1269 ASSERT(m_unpackedIntermediateSrcData.get()); | |
| 1270 } | |
| 1271 | |
| 1272 void convert(WebGLImageConversion::DataFormat srcFormat, WebGLImageConversio
n::DataFormat dstFormat, WebGLImageConversion::AlphaOp); | |
| 1273 bool Success() const { return m_success; } | |
| 1274 | |
| 1275 private: | |
| 1276 template<WebGLImageConversion::DataFormat SrcFormat> | |
| 1277 void convert(WebGLImageConversion::DataFormat dstFormat, WebGLImageConversio
n::AlphaOp); | |
| 1278 | |
| 1279 template<WebGLImageConversion::DataFormat SrcFormat, WebGLImageConversion::D
ataFormat DstFormat> | |
| 1280 void convert(WebGLImageConversion::AlphaOp); | |
| 1281 | |
| 1282 template<WebGLImageConversion::DataFormat SrcFormat, WebGLImageConversion::D
ataFormat DstFormat, WebGLImageConversion::AlphaOp alphaOp> | |
| 1283 void convert(); | |
| 1284 | |
| 1285 const unsigned m_width, m_height; | |
| 1286 const void* const m_srcStart; | |
| 1287 void* const m_dstStart; | |
| 1288 const int m_srcStride, m_dstStride; | |
| 1289 bool m_success; | |
| 1290 OwnPtr<uint8_t[]> m_unpackedIntermediateSrcData; | |
| 1291 }; | |
| 1292 | |
| 1293 void FormatConverter::convert(WebGLImageConversion::DataFormat srcFormat, WebGLI
mageConversion::DataFormat dstFormat, WebGLImageConversion::AlphaOp alphaOp) | |
| 1294 { | |
| 1295 #define FORMATCONVERTER_CASE_SRCFORMAT(SrcFormat) \ | |
| 1296 case SrcFormat: \ | |
| 1297 return convert<SrcFormat>(dstFormat, alphaOp); | |
| 1298 | |
| 1299 switch (srcFormat) { | |
| 1300 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatR8) | |
| 1301 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatA8) | |
| 1302 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatR32F) | |
| 1303 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatA32F) | |
| 1304 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatRA8) | |
| 1305 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatRA32F
) | |
| 1306 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatRGB8) | |
| 1307 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatBGR8) | |
| 1308 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatRGB56
5) | |
| 1309 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatRGB32
F) | |
| 1310 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatRGBA8
) | |
| 1311 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatARGB8
) | |
| 1312 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatABGR8
) | |
| 1313 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatAR8) | |
| 1314 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatBGRA8
) | |
| 1315 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatRGBA5
551) | |
| 1316 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatRGBA4
444) | |
| 1317 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatRGBA3
2F) | |
| 1318 default: | |
| 1319 ASSERT_NOT_REACHED(); | |
| 1320 } | |
| 1321 #undef FORMATCONVERTER_CASE_SRCFORMAT | |
| 1322 } | |
| 1323 | |
| 1324 template<WebGLImageConversion::DataFormat SrcFormat> | |
| 1325 void FormatConverter::convert(WebGLImageConversion::DataFormat dstFormat, WebGLI
mageConversion::AlphaOp alphaOp) | |
| 1326 { | |
| 1327 #define FORMATCONVERTER_CASE_DSTFORMAT(DstFormat) \ | |
| 1328 case DstFormat: \ | |
| 1329 return convert<SrcFormat, DstFormat>(alphaOp); | |
| 1330 | |
| 1331 switch (dstFormat) { | |
| 1332 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatR8) | |
| 1333 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatR16F) | |
| 1334 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatR32F) | |
| 1335 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatA8) | |
| 1336 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatA16F) | |
| 1337 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatA32F) | |
| 1338 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatRA8) | |
| 1339 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatRA16F
) | |
| 1340 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatRA32F
) | |
| 1341 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatRGB8) | |
| 1342 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatRGB56
5) | |
| 1343 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatRGB16
F) | |
| 1344 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatRGB32
F) | |
| 1345 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatRGBA8
) | |
| 1346 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatRGBA5
551) | |
| 1347 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatRGBA4
444) | |
| 1348 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatRGBA1
6F) | |
| 1349 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatRGBA3
2F) | |
| 1350 default: | |
| 1351 ASSERT_NOT_REACHED(); | |
| 1352 } | |
| 1353 | |
| 1354 #undef FORMATCONVERTER_CASE_DSTFORMAT | |
| 1355 } | |
| 1356 | |
| 1357 template<WebGLImageConversion::DataFormat SrcFormat, WebGLImageConversion::DataF
ormat DstFormat> | |
| 1358 void FormatConverter::convert(WebGLImageConversion::AlphaOp alphaOp) | |
| 1359 { | |
| 1360 #define FORMATCONVERTER_CASE_ALPHAOP(alphaOp) \ | |
| 1361 case alphaOp: \ | |
| 1362 return convert<SrcFormat, DstFormat, alphaOp>(); | |
| 1363 | |
| 1364 switch (alphaOp) { | |
| 1365 FORMATCONVERTER_CASE_ALPHAOP(WebGLImageConversion::AlphaDoNothing) | |
| 1366 FORMATCONVERTER_CASE_ALPHAOP(WebGLImageConversion::AlphaDoPremultipl
y) | |
| 1367 FORMATCONVERTER_CASE_ALPHAOP(WebGLImageConversion::AlphaDoUnmultiply
) | |
| 1368 default: | |
| 1369 ASSERT_NOT_REACHED(); | |
| 1370 } | |
| 1371 #undef FORMATCONVERTER_CASE_ALPHAOP | |
| 1372 } | |
| 1373 | |
| 1374 template<WebGLImageConversion::DataFormat SrcFormat, WebGLImageConversion::DataF
ormat DstFormat, WebGLImageConversion::AlphaOp alphaOp> | |
| 1375 void FormatConverter::convert() | |
| 1376 { | |
| 1377 // Many instantiations of this template function will never be entered, so w
e try | |
| 1378 // to return immediately in these cases to avoid the compiler to generate us
eless code. | |
| 1379 if (SrcFormat == DstFormat && alphaOp == WebGLImageConversion::AlphaDoNothin
g) { | |
| 1380 ASSERT_NOT_REACHED(); | |
| 1381 return; | |
| 1382 } | |
| 1383 if (!IsFloatFormat<DstFormat>::Value && IsFloatFormat<SrcFormat>::Value) { | |
| 1384 ASSERT_NOT_REACHED(); | |
| 1385 return; | |
| 1386 } | |
| 1387 | |
| 1388 // Only textures uploaded from DOM elements or ImageData can allow DstFormat
!= SrcFormat. | |
| 1389 const bool srcFormatComesFromDOMElementOrImageData = WebGLImageConversion::s
rcFormatComeFromDOMElementOrImageData(SrcFormat); | |
| 1390 if (!srcFormatComesFromDOMElementOrImageData && SrcFormat != DstFormat) { | |
| 1391 ASSERT_NOT_REACHED(); | |
| 1392 return; | |
| 1393 } | |
| 1394 // Likewise, only textures uploaded from DOM elements or ImageData can possi
bly have to be unpremultiplied. | |
| 1395 if (!srcFormatComesFromDOMElementOrImageData && alphaOp == WebGLImageConvers
ion::AlphaDoUnmultiply) { | |
| 1396 ASSERT_NOT_REACHED(); | |
| 1397 return; | |
| 1398 } | |
| 1399 if ((!HasAlpha(SrcFormat) || !HasColor(SrcFormat) || !HasColor(DstFormat)) &
& alphaOp != WebGLImageConversion::AlphaDoNothing) { | |
| 1400 ASSERT_NOT_REACHED(); | |
| 1401 return; | |
| 1402 } | |
| 1403 | |
| 1404 typedef typename DataTypeForFormat<SrcFormat>::Type SrcType; | |
| 1405 typedef typename DataTypeForFormat<DstFormat>::Type DstType; | |
| 1406 const int IntermediateSrcFormat = IntermediateFormat<DstFormat>::Value; | |
| 1407 typedef typename DataTypeForFormat<IntermediateSrcFormat>::Type Intermediate
SrcType; | |
| 1408 const ptrdiff_t srcStrideInElements = m_srcStride / sizeof(SrcType); | |
| 1409 const ptrdiff_t dstStrideInElements = m_dstStride / sizeof(DstType); | |
| 1410 const bool trivialUnpack = (SrcFormat == WebGLImageConversion::DataFormatRGB
A8 && !IsFloatFormat<DstFormat>::Value && !IsHalfFloatFormat<DstFormat>::Value)
|| SrcFormat == WebGLImageConversion::DataFormatRGBA32F; | |
| 1411 const bool trivialPack = (DstFormat == WebGLImageConversion::DataFormatRGBA8
|| DstFormat == WebGLImageConversion::DataFormatRGBA32F) && alphaOp == WebGLIma
geConversion::AlphaDoNothing && m_dstStride > 0; | |
| 1412 ASSERT(!trivialUnpack || !trivialPack); | |
| 1413 | |
| 1414 const SrcType *srcRowStart = static_cast<const SrcType*>(m_srcStart); | |
| 1415 DstType* dstRowStart = static_cast<DstType*>(m_dstStart); | |
| 1416 if (!trivialUnpack && trivialPack) { | |
| 1417 for (size_t i = 0; i < m_height; ++i) { | |
| 1418 unpack<SrcFormat>(srcRowStart, dstRowStart, m_width); | |
| 1419 srcRowStart += srcStrideInElements; | |
| 1420 dstRowStart += dstStrideInElements; | |
| 1421 } | |
| 1422 } else if (!trivialUnpack && !trivialPack) { | |
| 1423 for (size_t i = 0; i < m_height; ++i) { | |
| 1424 unpack<SrcFormat>(srcRowStart, reinterpret_cast<IntermediateSrcType*
>(m_unpackedIntermediateSrcData.get()), m_width); | |
| 1425 pack<DstFormat, alphaOp>(reinterpret_cast<IntermediateSrcType*>(m_un
packedIntermediateSrcData.get()), dstRowStart, m_width); | |
| 1426 srcRowStart += srcStrideInElements; | |
| 1427 dstRowStart += dstStrideInElements; | |
| 1428 } | |
| 1429 } else { | |
| 1430 for (size_t i = 0; i < m_height; ++i) { | |
| 1431 pack<DstFormat, alphaOp>(srcRowStart, dstRowStart, m_width); | |
| 1432 srcRowStart += srcStrideInElements; | |
| 1433 dstRowStart += dstStrideInElements; | |
| 1434 } | |
| 1435 } | |
| 1436 m_success = true; | |
| 1437 return; | |
| 1438 } | |
| 1439 | |
| 1440 } // anonymous namespace | |
| 1441 | |
| 1442 bool WebGLImageConversion::computeFormatAndTypeParameters(GLenum format, GLenum
type, unsigned* componentsPerPixel, unsigned* bytesPerComponent) | |
| 1443 { | |
| 1444 switch (format) { | |
| 1445 case GL_ALPHA: | |
| 1446 case GL_LUMINANCE: | |
| 1447 case GL_DEPTH_COMPONENT: | |
| 1448 case GL_DEPTH_STENCIL_OES: | |
| 1449 *componentsPerPixel = 1; | |
| 1450 break; | |
| 1451 case GL_LUMINANCE_ALPHA: | |
| 1452 *componentsPerPixel = 2; | |
| 1453 break; | |
| 1454 case GL_RGB: | |
| 1455 *componentsPerPixel = 3; | |
| 1456 break; | |
| 1457 case GL_RGBA: | |
| 1458 case GL_BGRA_EXT: // GL_EXT_texture_format_BGRA8888 | |
| 1459 *componentsPerPixel = 4; | |
| 1460 break; | |
| 1461 default: | |
| 1462 return false; | |
| 1463 } | |
| 1464 switch (type) { | |
| 1465 case GL_UNSIGNED_BYTE: | |
| 1466 *bytesPerComponent = sizeof(GLubyte); | |
| 1467 break; | |
| 1468 case GL_UNSIGNED_SHORT: | |
| 1469 *bytesPerComponent = sizeof(GLushort); | |
| 1470 break; | |
| 1471 case GL_UNSIGNED_SHORT_5_6_5: | |
| 1472 case GL_UNSIGNED_SHORT_4_4_4_4: | |
| 1473 case GL_UNSIGNED_SHORT_5_5_5_1: | |
| 1474 *componentsPerPixel = 1; | |
| 1475 *bytesPerComponent = sizeof(GLushort); | |
| 1476 break; | |
| 1477 case GL_UNSIGNED_INT_24_8_OES: | |
| 1478 case GL_UNSIGNED_INT: | |
| 1479 *bytesPerComponent = sizeof(GLuint); | |
| 1480 break; | |
| 1481 case GL_FLOAT: // OES_texture_float | |
| 1482 *bytesPerComponent = sizeof(GLfloat); | |
| 1483 break; | |
| 1484 case GL_HALF_FLOAT_OES: // OES_texture_half_float | |
| 1485 *bytesPerComponent = sizeof(GLushort); | |
| 1486 break; | |
| 1487 default: | |
| 1488 return false; | |
| 1489 } | |
| 1490 return true; | |
| 1491 } | |
| 1492 | |
| 1493 GLenum WebGLImageConversion::computeImageSizeInBytes(GLenum format, GLenum type,
GLsizei width, GLsizei height, GLint alignment, unsigned* imageSizeInBytes, uns
igned* paddingInBytes) | |
| 1494 { | |
| 1495 ASSERT(imageSizeInBytes); | |
| 1496 ASSERT(alignment == 1 || alignment == 2 || alignment == 4 || alignment == 8)
; | |
| 1497 if (width < 0 || height < 0) | |
| 1498 return GL_INVALID_VALUE; | |
| 1499 unsigned bytesPerComponent, componentsPerPixel; | |
| 1500 if (!computeFormatAndTypeParameters(format, type, &bytesPerComponent, &compo
nentsPerPixel)) | |
| 1501 return GL_INVALID_ENUM; | |
| 1502 if (!width || !height) { | |
| 1503 *imageSizeInBytes = 0; | |
| 1504 if (paddingInBytes) | |
| 1505 *paddingInBytes = 0; | |
| 1506 return GL_NO_ERROR; | |
| 1507 } | |
| 1508 CheckedInt<uint32_t> checkedValue(bytesPerComponent * componentsPerPixel); | |
| 1509 checkedValue *= width; | |
| 1510 if (!checkedValue.isValid()) | |
| 1511 return GL_INVALID_VALUE; | |
| 1512 unsigned validRowSize = checkedValue.value(); | |
| 1513 unsigned padding = 0; | |
| 1514 unsigned residual = validRowSize % alignment; | |
| 1515 if (residual) { | |
| 1516 padding = alignment - residual; | |
| 1517 checkedValue += padding; | |
| 1518 } | |
| 1519 // Last row needs no padding. | |
| 1520 checkedValue *= (height - 1); | |
| 1521 checkedValue += validRowSize; | |
| 1522 if (!checkedValue.isValid()) | |
| 1523 return GL_INVALID_VALUE; | |
| 1524 *imageSizeInBytes = checkedValue.value(); | |
| 1525 if (paddingInBytes) | |
| 1526 *paddingInBytes = padding; | |
| 1527 return GL_NO_ERROR; | |
| 1528 } | |
| 1529 | |
| 1530 WebGLImageConversion::ImageExtractor::ImageExtractor(Image* image, ImageHtmlDomS
ource imageHtmlDomSource, bool premultiplyAlpha, bool ignoreGammaAndColorProfile
) | |
| 1531 { | |
| 1532 m_image = image; | |
| 1533 m_imageHtmlDomSource = imageHtmlDomSource; | |
| 1534 m_extractSucceeded = extractImage(premultiplyAlpha, ignoreGammaAndColorProfi
le); | |
| 1535 } | |
| 1536 | |
| 1537 WebGLImageConversion::ImageExtractor::~ImageExtractor() | |
| 1538 { | |
| 1539 if (m_skiaImage) | |
| 1540 m_skiaImage->bitmap().unlockPixels(); | |
| 1541 } | |
| 1542 | |
| 1543 bool WebGLImageConversion::ImageExtractor::extractImage(bool premultiplyAlpha, b
ool ignoreGammaAndColorProfile) | |
| 1544 { | |
| 1545 if (!m_image) | |
| 1546 return false; | |
| 1547 m_skiaImage = m_image->nativeImageForCurrentFrame(); | |
| 1548 m_alphaOp = AlphaDoNothing; | |
| 1549 bool hasAlpha = m_skiaImage ? !m_skiaImage->bitmap().isOpaque() : true; | |
| 1550 if ((!m_skiaImage || ignoreGammaAndColorProfile || (hasAlpha && !premultiply
Alpha)) && m_image->data()) { | |
| 1551 // Attempt to get raw unpremultiplied image data. | |
| 1552 OwnPtr<ImageDecoder> decoder(ImageDecoder::create( | |
| 1553 *(m_image->data()), ImageSource::AlphaNotPremultiplied, | |
| 1554 ignoreGammaAndColorProfile ? ImageSource::GammaAndColorProfileIgnore
d : ImageSource::GammaAndColorProfileApplied)); | |
| 1555 if (!decoder) | |
| 1556 return false; | |
| 1557 decoder->setData(m_image->data(), true); | |
| 1558 if (!decoder->frameCount()) | |
| 1559 return false; | |
| 1560 ImageFrame* frame = decoder->frameBufferAtIndex(0); | |
| 1561 if (!frame || frame->status() != ImageFrame::FrameComplete) | |
| 1562 return false; | |
| 1563 hasAlpha = frame->hasAlpha(); | |
| 1564 m_nativeImage = frame->asNewNativeImage(); | |
| 1565 if (!m_nativeImage.get() || !m_nativeImage->isDataComplete() || !m_nativ
eImage->bitmap().width() || !m_nativeImage->bitmap().height()) | |
| 1566 return false; | |
| 1567 if (m_nativeImage->bitmap().colorType() != kN32_SkColorType) | |
| 1568 return false; | |
| 1569 m_skiaImage = m_nativeImage.get(); | |
| 1570 if (hasAlpha && premultiplyAlpha) | |
| 1571 m_alphaOp = AlphaDoPremultiply; | |
| 1572 } else if (!premultiplyAlpha && hasAlpha) { | |
| 1573 // 1. For texImage2D with HTMLVideoElment input, assume no PremultiplyAl
pha had been applied and the alpha value for each pixel is 0xFF | |
| 1574 // which is true at present and may be changed in the future and needs a
djustment accordingly. | |
| 1575 // 2. For texImage2D with HTMLCanvasElement input in which Alpha is alre
ady Premultiplied in this port, | |
| 1576 // do AlphaDoUnmultiply if UNPACK_PREMULTIPLY_ALPHA_WEBGL is set to fals
e. | |
| 1577 if (m_imageHtmlDomSource != HtmlDomVideo) | |
| 1578 m_alphaOp = AlphaDoUnmultiply; | |
| 1579 } | |
| 1580 if (!m_skiaImage) | |
| 1581 return false; | |
| 1582 | |
| 1583 m_imageSourceFormat = SK_B32_SHIFT ? DataFormatRGBA8 : DataFormatBGRA8; | |
| 1584 m_imageWidth = m_skiaImage->bitmap().width(); | |
| 1585 m_imageHeight = m_skiaImage->bitmap().height(); | |
| 1586 if (!m_imageWidth || !m_imageHeight) { | |
| 1587 m_skiaImage.clear(); | |
| 1588 return false; | |
| 1589 } | |
| 1590 // Fail if the image was downsampled because of memory limits. | |
| 1591 if (m_imageWidth != (unsigned)m_image->size().width() || m_imageHeight != (u
nsigned)m_image->size().height()) { | |
| 1592 m_skiaImage.clear(); | |
| 1593 return false; | |
| 1594 } | |
| 1595 m_imageSourceUnpackAlignment = 0; | |
| 1596 m_skiaImage->bitmap().lockPixels(); | |
| 1597 m_imagePixelData = m_skiaImage->bitmap().getPixels(); | |
| 1598 return true; | |
| 1599 } | |
| 1600 | |
| 1601 unsigned WebGLImageConversion::getClearBitsByFormat(GLenum format) | |
| 1602 { | |
| 1603 switch (format) { | |
| 1604 case GL_ALPHA: | |
| 1605 case GL_LUMINANCE: | |
| 1606 case GL_LUMINANCE_ALPHA: | |
| 1607 case GL_RGB: | |
| 1608 case GL_RGB565: | |
| 1609 case GL_RGBA: | |
| 1610 case GL_RGBA4: | |
| 1611 case GL_RGB5_A1: | |
| 1612 return GL_COLOR_BUFFER_BIT; | |
| 1613 case GL_DEPTH_COMPONENT16: | |
| 1614 case GL_DEPTH_COMPONENT: | |
| 1615 return GL_DEPTH_BUFFER_BIT; | |
| 1616 case GL_STENCIL_INDEX8: | |
| 1617 return GL_STENCIL_BUFFER_BIT; | |
| 1618 case GL_DEPTH_STENCIL_OES: | |
| 1619 return GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT; | |
| 1620 default: | |
| 1621 return 0; | |
| 1622 } | |
| 1623 } | |
| 1624 | |
| 1625 unsigned WebGLImageConversion::getChannelBitsByFormat(GLenum format) | |
| 1626 { | |
| 1627 switch (format) { | |
| 1628 case GL_ALPHA: | |
| 1629 return ChannelAlpha; | |
| 1630 case GL_LUMINANCE: | |
| 1631 return ChannelRGB; | |
| 1632 case GL_LUMINANCE_ALPHA: | |
| 1633 return ChannelRGBA; | |
| 1634 case GL_RGB: | |
| 1635 case GL_RGB565: | |
| 1636 return ChannelRGB; | |
| 1637 case GL_RGBA: | |
| 1638 case GL_RGBA4: | |
| 1639 case GL_RGB5_A1: | |
| 1640 return ChannelRGBA; | |
| 1641 case GL_DEPTH_COMPONENT16: | |
| 1642 case GL_DEPTH_COMPONENT: | |
| 1643 return ChannelDepth; | |
| 1644 case GL_STENCIL_INDEX8: | |
| 1645 return ChannelStencil; | |
| 1646 case GL_DEPTH_STENCIL_OES: | |
| 1647 return ChannelDepth | ChannelStencil; | |
| 1648 default: | |
| 1649 return 0; | |
| 1650 } | |
| 1651 } | |
| 1652 | |
| 1653 bool WebGLImageConversion::packImageData( | |
| 1654 Image* image, | |
| 1655 const void* pixels, | |
| 1656 GLenum format, | |
| 1657 GLenum type, | |
| 1658 bool flipY, | |
| 1659 AlphaOp alphaOp, | |
| 1660 DataFormat sourceFormat, | |
| 1661 unsigned width, | |
| 1662 unsigned height, | |
| 1663 unsigned sourceUnpackAlignment, | |
| 1664 Vector<uint8_t>& data) | |
| 1665 { | |
| 1666 if (!pixels) | |
| 1667 return false; | |
| 1668 | |
| 1669 unsigned packedSize; | |
| 1670 // Output data is tightly packed (alignment == 1). | |
| 1671 if (computeImageSizeInBytes(format, type, width, height, 1, &packedSize, 0)
!= GL_NO_ERROR) | |
| 1672 return false; | |
| 1673 data.resize(packedSize); | |
| 1674 | |
| 1675 if (!packPixels(reinterpret_cast<const uint8_t*>(pixels), sourceFormat, widt
h, height, sourceUnpackAlignment, format, type, alphaOp, data.data(), flipY)) | |
| 1676 return false; | |
| 1677 if (ImageObserver *observer = image->imageObserver()) | |
| 1678 observer->didDraw(image); | |
| 1679 return true; | |
| 1680 } | |
| 1681 | |
| 1682 bool WebGLImageConversion::extractImageData( | |
| 1683 const uint8_t* imageData, | |
| 1684 const IntSize& imageDataSize, | |
| 1685 GLenum format, | |
| 1686 GLenum type, | |
| 1687 bool flipY, | |
| 1688 bool premultiplyAlpha, | |
| 1689 Vector<uint8_t>& data) | |
| 1690 { | |
| 1691 if (!imageData) | |
| 1692 return false; | |
| 1693 int width = imageDataSize.width(); | |
| 1694 int height = imageDataSize.height(); | |
| 1695 | |
| 1696 unsigned packedSize; | |
| 1697 // Output data is tightly packed (alignment == 1). | |
| 1698 if (computeImageSizeInBytes(format, type, width, height, 1, &packedSize, 0)
!= GL_NO_ERROR) | |
| 1699 return false; | |
| 1700 data.resize(packedSize); | |
| 1701 | |
| 1702 if (!packPixels(imageData, DataFormatRGBA8, width, height, 0, format, type,
premultiplyAlpha ? AlphaDoPremultiply : AlphaDoNothing, data.data(), flipY)) | |
| 1703 return false; | |
| 1704 | |
| 1705 return true; | |
| 1706 } | |
| 1707 | |
| 1708 bool WebGLImageConversion::extractTextureData( | |
| 1709 unsigned width, | |
| 1710 unsigned height, | |
| 1711 GLenum format, GLenum type, | |
| 1712 unsigned unpackAlignment, | |
| 1713 bool flipY, bool premultiplyAlpha, | |
| 1714 const void* pixels, | |
| 1715 Vector<uint8_t>& data) | |
| 1716 { | |
| 1717 // Assumes format, type, etc. have already been validated. | |
| 1718 DataFormat sourceDataFormat = getDataFormat(format, type); | |
| 1719 | |
| 1720 // Resize the output buffer. | |
| 1721 unsigned int componentsPerPixel, bytesPerComponent; | |
| 1722 if (!computeFormatAndTypeParameters(format, type, &componentsPerPixel, &byte
sPerComponent)) | |
| 1723 return false; | |
| 1724 unsigned bytesPerPixel = componentsPerPixel * bytesPerComponent; | |
| 1725 data.resize(width * height * bytesPerPixel); | |
| 1726 | |
| 1727 if (!packPixels(static_cast<const uint8_t*>(pixels), sourceDataFormat, width
, height, unpackAlignment, format, type, (premultiplyAlpha ? AlphaDoPremultiply
: AlphaDoNothing), data.data(), flipY)) | |
| 1728 return false; | |
| 1729 | |
| 1730 return true; | |
| 1731 } | |
| 1732 | |
| 1733 bool WebGLImageConversion::packPixels( | |
| 1734 const uint8_t* sourceData, | |
| 1735 DataFormat sourceDataFormat, | |
| 1736 unsigned width, | |
| 1737 unsigned height, | |
| 1738 unsigned sourceUnpackAlignment, | |
| 1739 unsigned destinationFormat, | |
| 1740 unsigned destinationType, | |
| 1741 AlphaOp alphaOp, | |
| 1742 void* destinationData, | |
| 1743 bool flipY) | |
| 1744 { | |
| 1745 int validSrc = width * TexelBytesForFormat(sourceDataFormat); | |
| 1746 int remainder = sourceUnpackAlignment ? (validSrc % sourceUnpackAlignment) :
0; | |
| 1747 int srcStride = remainder ? (validSrc + sourceUnpackAlignment - remainder) :
validSrc; | |
| 1748 | |
| 1749 DataFormat dstDataFormat = getDataFormat(destinationFormat, destinationType)
; | |
| 1750 int dstStride = width * TexelBytesForFormat(dstDataFormat); | |
| 1751 if (flipY) { | |
| 1752 destinationData = static_cast<uint8_t*>(destinationData) + dstStride*(he
ight - 1); | |
| 1753 dstStride = -dstStride; | |
| 1754 } | |
| 1755 if (!HasAlpha(sourceDataFormat) || !HasColor(sourceDataFormat) || !HasColor(
dstDataFormat)) | |
| 1756 alphaOp = AlphaDoNothing; | |
| 1757 | |
| 1758 if (sourceDataFormat == dstDataFormat && alphaOp == AlphaDoNothing) { | |
| 1759 const uint8_t* ptr = sourceData; | |
| 1760 const uint8_t* ptrEnd = sourceData + srcStride * height; | |
| 1761 unsigned rowSize = (dstStride > 0) ? dstStride: -dstStride; | |
| 1762 uint8_t* dst = static_cast<uint8_t*>(destinationData); | |
| 1763 while (ptr < ptrEnd) { | |
| 1764 memcpy(dst, ptr, rowSize); | |
| 1765 ptr += srcStride; | |
| 1766 dst += dstStride; | |
| 1767 } | |
| 1768 return true; | |
| 1769 } | |
| 1770 | |
| 1771 FormatConverter converter(width, height, sourceData, destinationData, srcStr
ide, dstStride); | |
| 1772 converter.convert(sourceDataFormat, dstDataFormat, alphaOp); | |
| 1773 if (!converter.Success()) | |
| 1774 return false; | |
| 1775 return true; | |
| 1776 } | |
| 1777 | |
| 1778 } // namespace blink | |
| OLD | NEW |