109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// found in the LICENSE file.
493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#include "config.h"
609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "platform/graphics/gpu/WebGLImageConversion.h"
793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "platform/CheckedInt.h"
951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "platform/graphics/ImageObserver.h"
1009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "platform/graphics/cpu/arm/WebGLImageConversionNEON.h"
1109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "platform/image-decoders/ImageDecoder.h"
1209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "wtf/OwnPtr.h"
1309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "wtf/PassOwnPtr.h"
1493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
15c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
1693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
1793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)namespace {
1893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
1909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)WebGLImageConversion::DataFormat getDataFormat(GLenum destinationFormat, GLenum destinationType)
2093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
2109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    WebGLImageConversion::DataFormat dstFormat = WebGLImageConversion::DataFormatRGBA8;
2293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    switch (destinationType) {
2309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case GL_UNSIGNED_BYTE:
2493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        switch (destinationFormat) {
2509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        case GL_RGB:
2609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            dstFormat = WebGLImageConversion::DataFormatRGB8;
2793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            break;
2809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        case GL_RGBA:
2909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            dstFormat = WebGLImageConversion::DataFormatRGBA8;
3093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            break;
3109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        case GL_ALPHA:
3209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            dstFormat = WebGLImageConversion::DataFormatA8;
3393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            break;
3409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        case GL_LUMINANCE:
3509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            dstFormat = WebGLImageConversion::DataFormatR8;
3693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            break;
3709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        case GL_LUMINANCE_ALPHA:
3809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            dstFormat = WebGLImageConversion::DataFormatRA8;
3993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            break;
4093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        default:
4193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            ASSERT_NOT_REACHED();
4293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        }
4393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        break;
4409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case GL_UNSIGNED_SHORT_4_4_4_4:
4509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        dstFormat = WebGLImageConversion::DataFormatRGBA4444;
4693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        break;
4709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case GL_UNSIGNED_SHORT_5_5_5_1:
4809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        dstFormat = WebGLImageConversion::DataFormatRGBA5551;
4993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        break;
5009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case GL_UNSIGNED_SHORT_5_6_5:
5109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        dstFormat = WebGLImageConversion::DataFormatRGB565;
5293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        break;
5309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case GL_HALF_FLOAT_OES: // OES_texture_half_float
5493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        switch (destinationFormat) {
5509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        case GL_RGB:
5609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            dstFormat = WebGLImageConversion::DataFormatRGB16F;
5793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            break;
5809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        case GL_RGBA:
5909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            dstFormat = WebGLImageConversion::DataFormatRGBA16F;
6093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            break;
6109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        case GL_ALPHA:
6209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            dstFormat = WebGLImageConversion::DataFormatA16F;
6393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            break;
6409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        case GL_LUMINANCE:
6509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            dstFormat = WebGLImageConversion::DataFormatR16F;
6693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            break;
6709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        case GL_LUMINANCE_ALPHA:
6809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            dstFormat = WebGLImageConversion::DataFormatRA16F;
6993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            break;
7093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        default:
7193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            ASSERT_NOT_REACHED();
7293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        }
7393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        break;
7409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case GL_FLOAT: // OES_texture_float
7593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        switch (destinationFormat) {
7609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        case GL_RGB:
7709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            dstFormat = WebGLImageConversion::DataFormatRGB32F;
7893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            break;
7909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        case GL_RGBA:
8009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            dstFormat = WebGLImageConversion::DataFormatRGBA32F;
8193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            break;
8209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        case GL_ALPHA:
8309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            dstFormat = WebGLImageConversion::DataFormatA32F;
8493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            break;
8509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        case GL_LUMINANCE:
8609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            dstFormat = WebGLImageConversion::DataFormatR32F;
8793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            break;
8809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        case GL_LUMINANCE_ALPHA:
8909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            dstFormat = WebGLImageConversion::DataFormatRA32F;
9093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            break;
9193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        default:
9293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            ASSERT_NOT_REACHED();
9393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        }
9493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        break;
9593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    default:
9693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        ASSERT_NOT_REACHED();
9793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
9893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    return dstFormat;
9993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
10093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
10193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)// Following Float to Half-Float converion code is from the implementation of ftp://www.fox-toolkit.org/pub/fasthalffloatconversion.pdf,
10293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)// "Fast Half Float Conversions" by Jeroen van der Zijp, November 2008 (Revised September 2010).
10393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)// Specially, the basetable[512] and shifttable[512] are generated as follows:
10493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)/*
10593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)unsigned short basetable[512];
10693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)unsigned char shifttable[512];
10793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
10893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)void generatetables(){
10993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    unsigned int i;
11093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    int e;
11193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    for (i = 0; i < 256; ++i){
11293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        e = i - 127;
11393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        if (e < -24){ // Very small numbers map to zero
11493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            basetable[i | 0x000] = 0x0000;
11593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            basetable[i | 0x100] = 0x8000;
11693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            shifttable[i | 0x000] = 24;
11793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            shifttable[i | 0x100] = 24;
11893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        }
11993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        else if (e < -14) { // Small numbers map to denorms
12093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            basetable[i | 0x000] = (0x0400>>(-e-14));
12193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            basetable[i | 0x100] = (0x0400>>(-e-14)) | 0x8000;
12293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            shifttable[i | 0x000] = -e-1;
12393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            shifttable[i | 0x100] = -e-1;
12493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        }
12593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        else if (e <= 15){ // Normal numbers just lose precision
12693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            basetable[i | 0x000] = ((e+15)<<10);
12793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            basetable[i| 0x100] = ((e+15)<<10) | 0x8000;
12893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            shifttable[i|0x000] = 13;
12993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            shifttable[i|0x100] = 13;
13093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        }
13193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        else if (e<128){ // Large numbers map to Infinity
13293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            basetable[i|0x000] = 0x7C00;
13393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            basetable[i|0x100] = 0xFC00;
13493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            shifttable[i|0x000] = 24;
13593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            shifttable[i|0x100] = 24;
13693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        }
13793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        else { // Infinity and NaN's stay Infinity and NaN's
13893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            basetable[i|0x000] = 0x7C00;
13993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            basetable[i|0x100] = 0xFC00;
14093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            shifttable[i|0x000] = 13;
14193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            shifttable[i|0x100] = 13;
14293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)       }
14393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
14493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
14593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)*/
14693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
14793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)unsigned short baseTable[512] = {
14893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,
14993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,
15093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,
15193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,
15293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,
15393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,
15493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)0,      0,      0,      0,      0,      0,      0,      1,      2,      4,      8,      16,     32,     64,     128,    256,
15593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)512,    1024,   2048,   3072,   4096,   5120,   6144,   7168,   8192,   9216,   10240,  11264,  12288,  13312,  14336,  15360,
15693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)16384,  17408,  18432,  19456,  20480,  21504,  22528,  23552,  24576,  25600,  26624,  27648,  28672,  29696,  30720,  31744,
15793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,
15893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,
15993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,
16093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,
16193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,
16293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,
16393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,  31744,
16493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,
16593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,
16693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,
16793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,
16893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,
16993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,  32768,
17093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)32768,  32768,  32768,  32768,  32768,  32768,  32768,  32769,  32770,  32772,  32776,  32784,  32800,  32832,  32896,  33024,
17193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)33280,  33792,  34816,  35840,  36864,  37888,  38912,  39936,  40960,  41984,  43008,  44032,  45056,  46080,  47104,  48128,
17293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)49152,  50176,  51200,  52224,  53248,  54272,  55296,  56320,  57344,  58368,  59392,  60416,  61440,  62464,  63488,  64512,
17393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,
17493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,
17593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,
17693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,
17793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,
17893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,
17993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512,  64512
18093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)};
18193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
18293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)unsigned char shiftTable[512] = {
18393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,
18493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,
18593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,
18693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,
18793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,
18893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,
18993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)24,     24,     24,     24,     24,     24,     24,     23,     22,     21,     20,     19,     18,     17,     16,     15,
19093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)14,     13,     13,     13,     13,     13,     13,     13,     13,     13,     13,     13,     13,     13,     13,     13,
19193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)13,     13,     13,     13,     13,     13,     13,     13,     13,     13,     13,     13,     13,     13,     13,     24,
19293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,
19393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,
19493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,
19593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,
19693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,
19793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,
19893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     13,
19993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,
20093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,
20193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,
20293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,
20393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,
20493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,
20593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)24,     24,     24,     24,     24,     24,     24,     23,     22,     21,     20,     19,     18,     17,     16,     15,
20693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)14,     13,     13,     13,     13,     13,     13,     13,     13,     13,     13,     13,     13,     13,     13,     13,
20793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)13,     13,     13,     13,     13,     13,     13,     13,     13,     13,     13,     13,     13,     13,     13,     24,
20893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,
20993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,
21093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,
21193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,
21293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,
21393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,
21493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     24,     13
21593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)};
21693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
21793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)unsigned short convertFloatToHalfFloat(float f)
21893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
21993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    unsigned temp = *(reinterpret_cast<unsigned *>(&f));
22093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    unsigned signexp = (temp >> 23) & 0x1ff;
22193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    return baseTable[signexp] + ((temp & 0x007fffff) >> shiftTable[signexp]);
22293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
22393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
22493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)/* BEGIN CODE SHARED WITH MOZILLA FIREFOX */
22593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
22693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)// The following packing and unpacking routines are expressed in terms of function templates and inline functions to achieve generality and speedup.
22793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)// Explicit template specializations correspond to the cases that would occur.
22893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)// Some code are merged back from Mozilla code in http://mxr.mozilla.org/mozilla-central/source/content/canvas/src/WebGLTexelConversions.h
22993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
23093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)//----------------------------------------------------------------------
23193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)// Pixel unpacking routines.
23293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)template<int format, typename SourceType, typename DstType>
23393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)void unpack(const SourceType*, DstType*, unsigned)
23493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
23593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    ASSERT_NOT_REACHED();
23693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
23793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
23809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void unpack<WebGLImageConversion::DataFormatRGB8, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
23993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
24007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    for (unsigned i = 0; i < pixelsPerRow; ++i) {
24193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = source[0];
24293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[1] = source[1];
24393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[2] = source[2];
24493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[3] = 0xFF;
24593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 3;
24693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 4;
24793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
24893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
24993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
25009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void unpack<WebGLImageConversion::DataFormatBGR8, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
25193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
25207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    for (unsigned i = 0; i < pixelsPerRow; ++i) {
25393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = source[2];
25493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[1] = source[1];
25593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[2] = source[0];
25693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[3] = 0xFF;
25793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 3;
25893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 4;
25993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
26093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
26193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
26209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void unpack<WebGLImageConversion::DataFormatARGB8, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
26393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
26407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    for (unsigned i = 0; i < pixelsPerRow; ++i) {
26593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = source[1];
26693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[1] = source[2];
26793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[2] = source[3];
26893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[3] = source[0];
26993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 4;
27093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 4;
27193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
27293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
27393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
27409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void unpack<WebGLImageConversion::DataFormatABGR8, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
27593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
27607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    for (unsigned i = 0; i < pixelsPerRow; ++i) {
27793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = source[3];
27893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[1] = source[2];
27993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[2] = source[1];
28093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[3] = source[0];
28193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 4;
28293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 4;
28393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
28493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
28593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
28609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void unpack<WebGLImageConversion::DataFormatBGRA8, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
28793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
28893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    const uint32_t* source32 = reinterpret_cast_ptr<const uint32_t*>(source);
28993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    uint32_t* destination32 = reinterpret_cast_ptr<uint32_t*>(destination);
29007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    for (unsigned i = 0; i < pixelsPerRow; ++i) {
29193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint32_t bgra = source32[i];
29293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#if CPU(BIG_ENDIAN)
29393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint32_t brMask = 0xff00ff00;
29493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint32_t gaMask = 0x00ff00ff;
29593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#else
29693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint32_t brMask = 0x00ff00ff;
29793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint32_t gaMask = 0xff00ff00;
29893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#endif
29993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint32_t rgba = (((bgra >> 16) | (bgra << 16)) & brMask) | (bgra & gaMask);
30093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination32[i] = rgba;
30193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
30293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
30393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
30409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void unpack<WebGLImageConversion::DataFormatRGBA5551, uint16_t, uint8_t>(const uint16_t* source, uint8_t* destination, unsigned pixelsPerRow)
30593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
30693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#if HAVE(ARM_NEON_INTRINSICS)
30793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    SIMD::unpackOneRowOfRGBA5551ToRGBA8(source, destination, pixelsPerRow);
30893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#endif
30907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    for (unsigned i = 0; i < pixelsPerRow; ++i) {
31093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint16_t packedValue = source[0];
31193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint8_t r = packedValue >> 11;
31293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint8_t g = (packedValue >> 6) & 0x1F;
31393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint8_t b = (packedValue >> 1) & 0x1F;
31493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = (r << 3) | (r & 0x7);
31593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[1] = (g << 3) | (g & 0x7);
31693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[2] = (b << 3) | (b & 0x7);
31793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[3] = (packedValue & 0x1) ? 0xFF : 0x0;
31893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 1;
31993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 4;
32093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
32193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
32293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
32309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void unpack<WebGLImageConversion::DataFormatRGBA4444, uint16_t, uint8_t>(const uint16_t* source, uint8_t* destination, unsigned pixelsPerRow)
32493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
32593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#if HAVE(ARM_NEON_INTRINSICS)
32693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    SIMD::unpackOneRowOfRGBA4444ToRGBA8(source, destination, pixelsPerRow);
32793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#endif
32807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    for (unsigned i = 0; i < pixelsPerRow; ++i) {
32993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint16_t packedValue = source[0];
33093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint8_t r = packedValue >> 12;
33193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint8_t g = (packedValue >> 8) & 0x0F;
33293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint8_t b = (packedValue >> 4) & 0x0F;
33393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint8_t a = packedValue & 0x0F;
33493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = r << 4 | r;
33593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[1] = g << 4 | g;
33693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[2] = b << 4 | b;
33793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[3] = a << 4 | a;
33893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 1;
33993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 4;
34093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
34193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
34293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
34309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void unpack<WebGLImageConversion::DataFormatRGB565, uint16_t, uint8_t>(const uint16_t* source, uint8_t* destination, unsigned pixelsPerRow)
34493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
34593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#if HAVE(ARM_NEON_INTRINSICS)
34693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    SIMD::unpackOneRowOfRGB565ToRGBA8(source, destination, pixelsPerRow);
34793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#endif
34807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    for (unsigned i = 0; i < pixelsPerRow; ++i) {
34993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint16_t packedValue = source[0];
35093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint8_t r = packedValue >> 11;
35193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint8_t g = (packedValue >> 5) & 0x3F;
35293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint8_t b = packedValue & 0x1F;
35393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = (r << 3) | (r & 0x7);
35493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[1] = (g << 2) | (g & 0x3);
35593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[2] = (b << 3) | (b & 0x7);
35693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[3] = 0xFF;
35793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 1;
35893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 4;
35993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
36093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
36193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
36209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void unpack<WebGLImageConversion::DataFormatR8, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
36393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
36407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    for (unsigned i = 0; i < pixelsPerRow; ++i) {
36593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = source[0];
36693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[1] = source[0];
36793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[2] = source[0];
36893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[3] = 0xFF;
36993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 1;
37093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 4;
37193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
37293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
37393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
37409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void unpack<WebGLImageConversion::DataFormatRA8, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
37593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
37607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    for (unsigned i = 0; i < pixelsPerRow; ++i) {
37793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = source[0];
37893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[1] = source[0];
37993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[2] = source[0];
38093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[3] = source[1];
38193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 2;
38293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 4;
38393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
38493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
38593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
38609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void unpack<WebGLImageConversion::DataFormatAR8, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
38793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
38807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    for (unsigned i = 0; i < pixelsPerRow; ++i) {
38993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = source[1];
39093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[1] = source[1];
39193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[2] = source[1];
39293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[3] = source[0];
39393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 2;
39493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 4;
39593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
39693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
39793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
39809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void unpack<WebGLImageConversion::DataFormatA8, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
39993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
40007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    for (unsigned i = 0; i < pixelsPerRow; ++i) {
40193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = 0x0;
40293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[1] = 0x0;
40393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[2] = 0x0;
40493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[3] = source[0];
40593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 1;
40693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 4;
40793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
40893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
40993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
41009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void unpack<WebGLImageConversion::DataFormatRGBA8, uint8_t, float>(const uint8_t* source, float* destination, unsigned pixelsPerRow)
41193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
41293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    const float scaleFactor = 1.0f / 255.0f;
41307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    for (unsigned i = 0; i < pixelsPerRow; ++i) {
41493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = source[0] * scaleFactor;
41593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[1] = source[1] * scaleFactor;
41693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[2] = source[2] * scaleFactor;
41793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[3] = source[3] * scaleFactor;
41893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 4;
41993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 4;
42093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
42193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
42293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
42309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void unpack<WebGLImageConversion::DataFormatBGRA8, uint8_t, float>(const uint8_t* source, float* destination, unsigned pixelsPerRow)
42493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
42593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    const float scaleFactor = 1.0f / 255.0f;
42607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    for (unsigned i = 0; i < pixelsPerRow; ++i) {
42793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = source[2] * scaleFactor;
42893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[1] = source[1] * scaleFactor;
42993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[2] = source[0] * scaleFactor;
43093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[3] = source[3] * scaleFactor;
43193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 4;
43293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 4;
43393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
43493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
43593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
43609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void unpack<WebGLImageConversion::DataFormatABGR8, uint8_t, float>(const uint8_t* source, float* destination, unsigned pixelsPerRow)
43793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
43893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    const float scaleFactor = 1.0f / 255.0f;
43993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    for (unsigned i = 0; i < pixelsPerRow; ++i) {
44093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = source[3] * scaleFactor;
44193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[1] = source[2] * scaleFactor;
44293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[2] = source[1] * scaleFactor;
44393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[3] = source[0] * scaleFactor;
44493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 4;
44593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 4;
44693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
44793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
44893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
44909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void unpack<WebGLImageConversion::DataFormatARGB8, uint8_t, float>(const uint8_t* source, float* destination, unsigned pixelsPerRow)
45093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
45193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    const float scaleFactor = 1.0f / 255.0f;
45293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    for (unsigned i = 0; i < pixelsPerRow; ++i) {
45393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = source[1] * scaleFactor;
45493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[1] = source[2] * scaleFactor;
45593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[2] = source[3] * scaleFactor;
45693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[3] = source[0] * scaleFactor;
45793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 4;
45893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 4;
45993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
46093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
46193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
46209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void unpack<WebGLImageConversion::DataFormatRGB8, uint8_t, float>(const uint8_t* source, float* destination, unsigned pixelsPerRow)
46393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
46493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    const float scaleFactor = 1.0f / 255.0f;
46593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    for (unsigned i = 0; i < pixelsPerRow; ++i) {
46693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = source[0] * scaleFactor;
46793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[1] = source[1] * scaleFactor;
46893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[2] = source[2] * scaleFactor;
46993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[3] = 1;
47093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 3;
47193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 4;
47293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
47393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
47493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
47509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void unpack<WebGLImageConversion::DataFormatBGR8, uint8_t, float>(const uint8_t* source, float* destination, unsigned pixelsPerRow)
47693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
47793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    const float scaleFactor = 1.0f / 255.0f;
47893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    for (unsigned i = 0; i < pixelsPerRow; ++i) {
47993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = source[2] * scaleFactor;
48093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[1] = source[1] * scaleFactor;
48193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[2] = source[0] * scaleFactor;
48293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[3] = 1;
48393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 3;
48493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 4;
48593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
48693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
48793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
48809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void unpack<WebGLImageConversion::DataFormatRGB32F, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
48993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
49007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    for (unsigned i = 0; i < pixelsPerRow; ++i) {
49193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = source[0];
49293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[1] = source[1];
49393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[2] = source[2];
49493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[3] = 1;
49593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 3;
49693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 4;
49793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
49893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
49993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
50009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void unpack<WebGLImageConversion::DataFormatR32F, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
50193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
50207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    for (unsigned i = 0; i < pixelsPerRow; ++i) {
50393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = source[0];
50493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[1] = source[0];
50593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[2] = source[0];
50693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[3] = 1;
50793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 1;
50893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 4;
50993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
51093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
51193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
51209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void unpack<WebGLImageConversion::DataFormatRA32F, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
51393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
51407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    for (unsigned i = 0; i < pixelsPerRow; ++i) {
51593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = source[0];
51693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[1] = source[0];
51793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[2] = source[0];
51893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[3] = source[1];
51993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 2;
52093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 4;
52193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
52293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
52393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
52409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void unpack<WebGLImageConversion::DataFormatA32F, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
52593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
52607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    for (unsigned i = 0; i < pixelsPerRow; ++i) {
52793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = 0;
52893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[1] = 0;
52993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[2] = 0;
53093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[3] = source[0];
53193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 1;
53293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 4;
53393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
53493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
53593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
53693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)//----------------------------------------------------------------------
53793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)// Pixel packing routines.
53893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)//
53993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
54093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)template<int format, int alphaOp, typename SourceType, typename DstType>
54193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)void pack(const SourceType*, DstType*, unsigned)
54293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
54393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    ASSERT_NOT_REACHED();
54493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
54593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
54609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void pack<WebGLImageConversion::DataFormatA8, WebGLImageConversion::AlphaDoNothing, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
54793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
54807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    for (unsigned i = 0; i < pixelsPerRow; ++i) {
54993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = source[3];
55093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 4;
55193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 1;
55293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
55393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
55493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
55509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void pack<WebGLImageConversion::DataFormatR8, WebGLImageConversion::AlphaDoNothing, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
55693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
55707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    for (unsigned i = 0; i < pixelsPerRow; ++i) {
55893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = source[0];
55993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 4;
56093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 1;
56193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
56293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
56393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
56409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void pack<WebGLImageConversion::DataFormatR8, WebGLImageConversion::AlphaDoPremultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
56593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
56607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    for (unsigned i = 0; i < pixelsPerRow; ++i) {
56793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        float scaleFactor = source[3] / 255.0f;
56893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * scaleFactor);
56993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = sourceR;
57093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 4;
57193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 1;
57293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
57393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
57493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
57593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)// FIXME: this routine is lossy and must be removed.
57609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void pack<WebGLImageConversion::DataFormatR8, WebGLImageConversion::AlphaDoUnmultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
57793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
57807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    for (unsigned i = 0; i < pixelsPerRow; ++i) {
57993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        float scaleFactor = source[3] ? 255.0f / source[3] : 1.0f;
58093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * scaleFactor);
58193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = sourceR;
58293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 4;
58393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 1;
58493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
58593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
58693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
58709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void pack<WebGLImageConversion::DataFormatRA8, WebGLImageConversion::AlphaDoNothing, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
58893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
58907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    for (unsigned i = 0; i < pixelsPerRow; ++i) {
59093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = source[0];
59193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[1] = source[3];
59293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 4;
59393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 2;
59493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
59593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
59693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
59709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void pack<WebGLImageConversion::DataFormatRA8, WebGLImageConversion::AlphaDoPremultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
59893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
59907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    for (unsigned i = 0; i < pixelsPerRow; ++i) {
60093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        float scaleFactor = source[3] / 255.0f;
60193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * scaleFactor);
60293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = sourceR;
60393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[1] = source[3];
60493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 4;
60593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 2;
60693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
60793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
60893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
60993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)// FIXME: this routine is lossy and must be removed.
61009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void pack<WebGLImageConversion::DataFormatRA8, WebGLImageConversion::AlphaDoUnmultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
61193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
61207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    for (unsigned i = 0; i < pixelsPerRow; ++i) {
61393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        float scaleFactor = source[3] ? 255.0f / source[3] : 1.0f;
61493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * scaleFactor);
61593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = sourceR;
61693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[1] = source[3];
61793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 4;
61893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 2;
61993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
62093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
62193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
62209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void pack<WebGLImageConversion::DataFormatRGB8, WebGLImageConversion::AlphaDoNothing, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
62393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
62407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    for (unsigned i = 0; i < pixelsPerRow; ++i) {
62593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = source[0];
62693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[1] = source[1];
62793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[2] = source[2];
62893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 4;
62993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 3;
63093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
63193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
63293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
63309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void pack<WebGLImageConversion::DataFormatRGB8, WebGLImageConversion::AlphaDoPremultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
63493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
63507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    for (unsigned i = 0; i < pixelsPerRow; ++i) {
63693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        float scaleFactor = source[3] / 255.0f;
63793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * scaleFactor);
63893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * scaleFactor);
63993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * scaleFactor);
64093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = sourceR;
64193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[1] = sourceG;
64293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[2] = sourceB;
64393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 4;
64493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 3;
64593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
64693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
64793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
64893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)// FIXME: this routine is lossy and must be removed.
64909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void pack<WebGLImageConversion::DataFormatRGB8, WebGLImageConversion::AlphaDoUnmultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
65093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
65107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    for (unsigned i = 0; i < pixelsPerRow; ++i) {
65293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        float scaleFactor = source[3] ? 255.0f / source[3] : 1.0f;
65393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * scaleFactor);
65493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * scaleFactor);
65593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * scaleFactor);
65693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = sourceR;
65793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[1] = sourceG;
65893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[2] = sourceB;
65993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 4;
66093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 3;
66193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
66293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
66393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
66493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
66509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void pack<WebGLImageConversion::DataFormatRGBA8, WebGLImageConversion::AlphaDoNothing, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
66693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
66793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    memcpy(destination, source, pixelsPerRow * 4);
66893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
66993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
67009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void pack<WebGLImageConversion::DataFormatRGBA8, WebGLImageConversion::AlphaDoPremultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
67193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
67207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    for (unsigned i = 0; i < pixelsPerRow; ++i) {
67393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        float scaleFactor = source[3] / 255.0f;
67493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * scaleFactor);
67593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * scaleFactor);
67693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * scaleFactor);
67793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = sourceR;
67893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[1] = sourceG;
67993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[2] = sourceB;
68093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[3] = source[3];
68193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 4;
68293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 4;
68393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
68493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
68593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
68693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)// FIXME: this routine is lossy and must be removed.
68709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void pack<WebGLImageConversion::DataFormatRGBA8, WebGLImageConversion::AlphaDoUnmultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
68893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
68907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    for (unsigned i = 0; i < pixelsPerRow; ++i) {
69093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        float scaleFactor = source[3] ? 255.0f / source[3] : 1.0f;
69193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * scaleFactor);
69293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * scaleFactor);
69393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * scaleFactor);
69493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = sourceR;
69593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[1] = sourceG;
69693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[2] = sourceB;
69793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[3] = source[3];
69893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 4;
69993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 4;
70093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
70193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
70293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
70309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void pack<WebGLImageConversion::DataFormatRGBA4444, WebGLImageConversion::AlphaDoNothing, uint8_t, uint16_t>(const uint8_t* source, uint16_t* destination, unsigned pixelsPerRow)
70493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
70593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#if HAVE(ARM_NEON_INTRINSICS)
70693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    SIMD::packOneRowOfRGBA8ToUnsignedShort4444(source, destination, pixelsPerRow);
70793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#endif
70807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    for (unsigned i = 0; i < pixelsPerRow; ++i) {
70993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        *destination = (((source[0] & 0xF0) << 8)
71093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)                        | ((source[1] & 0xF0) << 4)
71193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)                        | (source[2] & 0xF0)
71293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)                        | (source[3] >> 4));
71393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 4;
71493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 1;
71593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
71693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
71793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
71809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void pack<WebGLImageConversion::DataFormatRGBA4444, WebGLImageConversion::AlphaDoPremultiply, uint8_t, uint16_t>(const uint8_t* source, uint16_t* destination, unsigned pixelsPerRow)
71993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
72007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    for (unsigned i = 0; i < pixelsPerRow; ++i) {
72193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        float scaleFactor = source[3] / 255.0f;
72293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * scaleFactor);
72393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * scaleFactor);
72493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * scaleFactor);
72593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        *destination = (((sourceR & 0xF0) << 8)
72693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)                        | ((sourceG & 0xF0) << 4)
72793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)                        | (sourceB & 0xF0)
72893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)                        | (source[3] >> 4));
72993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 4;
73093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 1;
73193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
73293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
73393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
73493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)// FIXME: this routine is lossy and must be removed.
73509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void pack<WebGLImageConversion::DataFormatRGBA4444, WebGLImageConversion::AlphaDoUnmultiply, uint8_t, uint16_t>(const uint8_t* source, uint16_t* destination, unsigned pixelsPerRow)
73693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
73707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    for (unsigned i = 0; i < pixelsPerRow; ++i) {
73893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        float scaleFactor = source[3] ? 255.0f / source[3] : 1.0f;
73993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * scaleFactor);
74093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * scaleFactor);
74193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * scaleFactor);
74293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        *destination = (((sourceR & 0xF0) << 8)
74393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)                        | ((sourceG & 0xF0) << 4)
74493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)                        | (sourceB & 0xF0)
74593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)                        | (source[3] >> 4));
74693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 4;
74793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 1;
74893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
74993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
75093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
75109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void pack<WebGLImageConversion::DataFormatRGBA5551, WebGLImageConversion::AlphaDoNothing, uint8_t, uint16_t>(const uint8_t* source, uint16_t* destination, unsigned pixelsPerRow)
75293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
75393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#if HAVE(ARM_NEON_INTRINSICS)
75493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    SIMD::packOneRowOfRGBA8ToUnsignedShort5551(source, destination, pixelsPerRow);
75593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#endif
75607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    for (unsigned i = 0; i < pixelsPerRow; ++i) {
75793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        *destination = (((source[0] & 0xF8) << 8)
75893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)                        | ((source[1] & 0xF8) << 3)
75993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)                        | ((source[2] & 0xF8) >> 2)
76093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)                        | (source[3] >> 7));
76193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 4;
76293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 1;
76393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
76493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
76593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
76609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void pack<WebGLImageConversion::DataFormatRGBA5551, WebGLImageConversion::AlphaDoPremultiply, uint8_t, uint16_t>(const uint8_t* source, uint16_t* destination, unsigned pixelsPerRow)
76793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
76807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    for (unsigned i = 0; i < pixelsPerRow; ++i) {
76993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        float scaleFactor = source[3] / 255.0f;
77093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * scaleFactor);
77193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * scaleFactor);
77293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * scaleFactor);
77393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        *destination = (((sourceR & 0xF8) << 8)
77493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)                        | ((sourceG & 0xF8) << 3)
77593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)                        | ((sourceB & 0xF8) >> 2)
77693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)                        | (source[3] >> 7));
77793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 4;
77893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 1;
77993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
78093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
78193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
78293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)// FIXME: this routine is lossy and must be removed.
78309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void pack<WebGLImageConversion::DataFormatRGBA5551, WebGLImageConversion::AlphaDoUnmultiply, uint8_t, uint16_t>(const uint8_t* source, uint16_t* destination, unsigned pixelsPerRow)
78493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
78507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    for (unsigned i = 0; i < pixelsPerRow; ++i) {
78693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        float scaleFactor = source[3] ? 255.0f / source[3] : 1.0f;
78793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * scaleFactor);
78893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * scaleFactor);
78993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * scaleFactor);
79093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        *destination = (((sourceR & 0xF8) << 8)
79193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)                        | ((sourceG & 0xF8) << 3)
79293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)                        | ((sourceB & 0xF8) >> 2)
79393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)                        | (source[3] >> 7));
79493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 4;
79593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 1;
79693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
79793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
79893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
79909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void pack<WebGLImageConversion::DataFormatRGB565, WebGLImageConversion::AlphaDoNothing, uint8_t, uint16_t>(const uint8_t* source, uint16_t* destination, unsigned pixelsPerRow)
80093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
80193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#if HAVE(ARM_NEON_INTRINSICS)
80293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    SIMD::packOneRowOfRGBA8ToUnsignedShort565(source, destination, pixelsPerRow);
80393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#endif
80407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    for (unsigned i = 0; i < pixelsPerRow; ++i) {
80593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        *destination = (((source[0] & 0xF8) << 8)
80693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)                        | ((source[1] & 0xFC) << 3)
80793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)                        | ((source[2] & 0xF8) >> 3));
80893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 4;
80993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 1;
81093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
81193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
81293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
81309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void pack<WebGLImageConversion::DataFormatRGB565, WebGLImageConversion::AlphaDoPremultiply, uint8_t, uint16_t>(const uint8_t* source, uint16_t* destination, unsigned pixelsPerRow)
81493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
81507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    for (unsigned i = 0; i < pixelsPerRow; ++i) {
81693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        float scaleFactor = source[3] / 255.0f;
81793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * scaleFactor);
81893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * scaleFactor);
81993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * scaleFactor);
82093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        *destination = (((sourceR & 0xF8) << 8)
82193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)                        | ((sourceG & 0xFC) << 3)
82293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)                        | ((sourceB & 0xF8) >> 3));
82393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 4;
82493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 1;
82593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
82693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
82793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
82893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)// FIXME: this routine is lossy and must be removed.
82909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void pack<WebGLImageConversion::DataFormatRGB565, WebGLImageConversion::AlphaDoUnmultiply, uint8_t, uint16_t>(const uint8_t* source, uint16_t* destination, unsigned pixelsPerRow)
83093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
83107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    for (unsigned i = 0; i < pixelsPerRow; ++i) {
83293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        float scaleFactor = source[3] ? 255.0f / source[3] : 1.0f;
83393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * scaleFactor);
83493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * scaleFactor);
83593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * scaleFactor);
83693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        *destination = (((sourceR & 0xF8) << 8)
83793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)                        | ((sourceG & 0xFC) << 3)
83893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)                        | ((sourceB & 0xF8) >> 3));
83993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 4;
84093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 1;
84193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
84293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
84393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
84409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void pack<WebGLImageConversion::DataFormatRGB32F, WebGLImageConversion::AlphaDoNothing, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
84593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
84607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    for (unsigned i = 0; i < pixelsPerRow; ++i) {
84793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = source[0];
84893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[1] = source[1];
84993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[2] = source[2];
85093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 4;
85193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 3;
85293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
85393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
85493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
85509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void pack<WebGLImageConversion::DataFormatRGB32F, WebGLImageConversion::AlphaDoPremultiply, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
85693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
85707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    for (unsigned i = 0; i < pixelsPerRow; ++i) {
85893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        float scaleFactor = source[3];
85993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = source[0] * scaleFactor;
86093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[1] = source[1] * scaleFactor;
86193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[2] = source[2] * scaleFactor;
86293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 4;
86393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 3;
86493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
86593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
86693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
86709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void pack<WebGLImageConversion::DataFormatRGB32F, WebGLImageConversion::AlphaDoUnmultiply, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
86893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
86907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    for (unsigned i = 0; i < pixelsPerRow; ++i) {
87093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f;
87193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = source[0] * scaleFactor;
87293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[1] = source[1] * scaleFactor;
87393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[2] = source[2] * scaleFactor;
87493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 4;
87593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 3;
87693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
87793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
87893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
87993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)// Used only during RGBA8 or BGRA8 -> floating-point uploads.
88009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void pack<WebGLImageConversion::DataFormatRGBA32F, WebGLImageConversion::AlphaDoNothing, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
88193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
88293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    memcpy(destination, source, pixelsPerRow * 4 * sizeof(float));
88393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
88493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
88509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void pack<WebGLImageConversion::DataFormatRGBA32F, WebGLImageConversion::AlphaDoPremultiply, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
88693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
88707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    for (unsigned i = 0; i < pixelsPerRow; ++i) {
88893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        float scaleFactor = source[3];
88993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = source[0] * scaleFactor;
89093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[1] = source[1] * scaleFactor;
89193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[2] = source[2] * scaleFactor;
89293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[3] = source[3];
89393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 4;
89493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 4;
89593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
89693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
89793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
89809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void pack<WebGLImageConversion::DataFormatRGBA32F, WebGLImageConversion::AlphaDoUnmultiply, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
89993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
90007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    for (unsigned i = 0; i < pixelsPerRow; ++i) {
90193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f;
90293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = source[0] * scaleFactor;
90393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[1] = source[1] * scaleFactor;
90493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[2] = source[2] * scaleFactor;
90593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[3] = source[3];
90693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 4;
90793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 4;
90893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
90993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
91093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
91109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void pack<WebGLImageConversion::DataFormatA32F, WebGLImageConversion::AlphaDoNothing, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
91293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
91307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    for (unsigned i = 0; i < pixelsPerRow; ++i) {
91493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = source[3];
91593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 4;
91693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 1;
91793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
91893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
91993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
92009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void pack<WebGLImageConversion::DataFormatR32F, WebGLImageConversion::AlphaDoNothing, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
92193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
92207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    for (unsigned i = 0; i < pixelsPerRow; ++i) {
92393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = source[0];
92493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 4;
92593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 1;
92693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
92793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
92893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
92909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void pack<WebGLImageConversion::DataFormatR32F, WebGLImageConversion::AlphaDoPremultiply, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
93093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
93107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    for (unsigned i = 0; i < pixelsPerRow; ++i) {
93293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        float scaleFactor = source[3];
93393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = source[0] * scaleFactor;
93493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 4;
93593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 1;
93693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
93793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
93893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
93909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void pack<WebGLImageConversion::DataFormatR32F, WebGLImageConversion::AlphaDoUnmultiply, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
94093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
94107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    for (unsigned i = 0; i < pixelsPerRow; ++i) {
94293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f;
94393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = source[0] * scaleFactor;
94493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 4;
94593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 1;
94693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
94793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
94893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
94909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void pack<WebGLImageConversion::DataFormatRA32F, WebGLImageConversion::AlphaDoNothing, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
95093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
95107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    for (unsigned i = 0; i < pixelsPerRow; ++i) {
95293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = source[0];
95393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[1] = source[3];
95493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 4;
95593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 2;
95693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
95793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
95893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
95909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void pack<WebGLImageConversion::DataFormatRA32F, WebGLImageConversion::AlphaDoPremultiply, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
96093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
96107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    for (unsigned i = 0; i < pixelsPerRow; ++i) {
96293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        float scaleFactor = source[3];
96393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = source[0] * scaleFactor;
96493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[1] = source[3];
96593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 4;
96693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 2;
96793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
96893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
96993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
97009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void pack<WebGLImageConversion::DataFormatRA32F, WebGLImageConversion::AlphaDoUnmultiply, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
97193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
97207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    for (unsigned i = 0; i < pixelsPerRow; ++i) {
97393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f;
97493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = source[0] * scaleFactor;
97593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[1] = source[3];
97693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 4;
97793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 2;
97893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
97993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
98093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
98109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void pack<WebGLImageConversion::DataFormatRGBA16F, WebGLImageConversion::AlphaDoNothing, float, uint16_t>(const float* source, uint16_t* destination, unsigned pixelsPerRow)
98293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
98393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    for (unsigned i = 0; i < pixelsPerRow; ++i) {
98493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = convertFloatToHalfFloat(source[0]);
98593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[1] = convertFloatToHalfFloat(source[1]);
98693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[2] = convertFloatToHalfFloat(source[2]);
98793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[3] = convertFloatToHalfFloat(source[3]);
98893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 4;
98993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 4;
99093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
99193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
99293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
99309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void pack<WebGLImageConversion::DataFormatRGBA16F, WebGLImageConversion::AlphaDoPremultiply, float, uint16_t>(const float* source, uint16_t* destination, unsigned pixelsPerRow)
99493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
99593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    for (unsigned i = 0; i < pixelsPerRow; ++i) {
99693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        float scaleFactor = source[3];
99793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = convertFloatToHalfFloat(source[0] * scaleFactor);
99893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[1] = convertFloatToHalfFloat(source[1] * scaleFactor);
99993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[2] = convertFloatToHalfFloat(source[2] * scaleFactor);
100093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[3] = convertFloatToHalfFloat(source[3]);
100193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 4;
100293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 4;
100393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
100493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
100593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
100609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void pack<WebGLImageConversion::DataFormatRGBA16F, WebGLImageConversion::AlphaDoUnmultiply, float, uint16_t>(const float* source, uint16_t* destination, unsigned pixelsPerRow)
100793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
100893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    for (unsigned i = 0; i < pixelsPerRow; ++i) {
100993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f;
101093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = convertFloatToHalfFloat(source[0] * scaleFactor);
101193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[1] = convertFloatToHalfFloat(source[1] * scaleFactor);
101293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[2] = convertFloatToHalfFloat(source[2] * scaleFactor);
101393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[3] = convertFloatToHalfFloat(source[3]);
101493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 4;
101593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 4;
101693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
101793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
101893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
101909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void pack<WebGLImageConversion::DataFormatRGB16F, WebGLImageConversion::AlphaDoNothing, float, uint16_t>(const float* source, uint16_t* destination, unsigned pixelsPerRow)
102093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
102193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    for (unsigned i = 0; i < pixelsPerRow; ++i) {
102293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = convertFloatToHalfFloat(source[0]);
102393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[1] = convertFloatToHalfFloat(source[1]);
102493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[2] = convertFloatToHalfFloat(source[2]);
102593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 4;
102693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 3;
102793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
102893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
102993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
103009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void pack<WebGLImageConversion::DataFormatRGB16F, WebGLImageConversion::AlphaDoPremultiply, float, uint16_t>(const float* source, uint16_t* destination, unsigned pixelsPerRow)
103193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
103293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    for (unsigned i = 0; i < pixelsPerRow; ++i) {
103393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        float scaleFactor = source[3];
103493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = convertFloatToHalfFloat(source[0] * scaleFactor);
103593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[1] = convertFloatToHalfFloat(source[1] * scaleFactor);
103693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[2] = convertFloatToHalfFloat(source[2] * scaleFactor);
103793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 4;
103893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 3;
103993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
104093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
104193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
104209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void pack<WebGLImageConversion::DataFormatRGB16F, WebGLImageConversion::AlphaDoUnmultiply, float, uint16_t>(const float* source, uint16_t* destination, unsigned pixelsPerRow)
104393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
104493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    for (unsigned i = 0; i < pixelsPerRow; ++i) {
104593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f;
104693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = convertFloatToHalfFloat(source[0] * scaleFactor);
104793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[1] = convertFloatToHalfFloat(source[1] * scaleFactor);
104893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[2] = convertFloatToHalfFloat(source[2] * scaleFactor);
104993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 4;
105093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 3;
105193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
105293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
105393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
105409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void pack<WebGLImageConversion::DataFormatRA16F, WebGLImageConversion::AlphaDoNothing, float, uint16_t>(const float* source, uint16_t* destination, unsigned pixelsPerRow)
105593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
105693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    for (unsigned i = 0; i < pixelsPerRow; ++i) {
105793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = convertFloatToHalfFloat(source[0]);
105893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[1] = convertFloatToHalfFloat(source[3]);
105993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 4;
106093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 2;
106193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
106293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
106393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
106409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void pack<WebGLImageConversion::DataFormatRA16F, WebGLImageConversion::AlphaDoPremultiply, float, uint16_t>(const float* source, uint16_t* destination, unsigned pixelsPerRow)
106593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
106693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    for (unsigned i = 0; i < pixelsPerRow; ++i) {
106793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        float scaleFactor = source[3];
106893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = convertFloatToHalfFloat(source[0] * scaleFactor);
106993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[1] = convertFloatToHalfFloat(source[3]);
107093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 4;
107193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 2;
107293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
107393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
107493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
107509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void pack<WebGLImageConversion::DataFormatRA16F, WebGLImageConversion::AlphaDoUnmultiply, float, uint16_t>(const float* source, uint16_t* destination, unsigned pixelsPerRow)
107693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
107793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    for (unsigned i = 0; i < pixelsPerRow; ++i) {
107893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f;
107993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = convertFloatToHalfFloat(source[0] * scaleFactor);
108093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[1] = convertFloatToHalfFloat(source[3]);
108193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 4;
108293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 2;
108393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
108493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
108593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
108609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void pack<WebGLImageConversion::DataFormatR16F, WebGLImageConversion::AlphaDoNothing, float, uint16_t>(const float* source, uint16_t* destination, unsigned pixelsPerRow)
108793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
108893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    for (unsigned i = 0; i < pixelsPerRow; ++i) {
108993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = convertFloatToHalfFloat(source[0]);
109093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 4;
109193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 1;
109293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
109393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
109493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
109509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void pack<WebGLImageConversion::DataFormatR16F, WebGLImageConversion::AlphaDoPremultiply, float, uint16_t>(const float* source, uint16_t* destination, unsigned pixelsPerRow)
109693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
109793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    for (unsigned i = 0; i < pixelsPerRow; ++i) {
109893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        float scaleFactor = source[3];
109993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = convertFloatToHalfFloat(source[0] * scaleFactor);
110093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 4;
110193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 1;
110293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
110393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
110493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
110509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void pack<WebGLImageConversion::DataFormatR16F, WebGLImageConversion::AlphaDoUnmultiply, float, uint16_t>(const float* source, uint16_t* destination, unsigned pixelsPerRow)
110693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
110793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    for (unsigned i = 0; i < pixelsPerRow; ++i) {
110893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f;
110993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = convertFloatToHalfFloat(source[0] * scaleFactor);
111093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 4;
111193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 1;
111293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
111393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
111493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
111509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<> void pack<WebGLImageConversion::DataFormatA16F, WebGLImageConversion::AlphaDoNothing, float, uint16_t>(const float* source, uint16_t* destination, unsigned pixelsPerRow)
111693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
111793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    for (unsigned i = 0; i < pixelsPerRow; ++i) {
111893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination[0] = convertFloatToHalfFloat(source[3]);
111993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        source += 4;
112093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destination += 1;
112193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
112293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
112393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
112493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)bool HasAlpha(int format)
112593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
112609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    return format == WebGLImageConversion::DataFormatA8
112709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        || format == WebGLImageConversion::DataFormatA16F
112809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        || format == WebGLImageConversion::DataFormatA32F
112909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        || format == WebGLImageConversion::DataFormatRA8
113009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        || format == WebGLImageConversion::DataFormatAR8
113109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        || format == WebGLImageConversion::DataFormatRA16F
113209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        || format == WebGLImageConversion::DataFormatRA32F
113309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        || format == WebGLImageConversion::DataFormatRGBA8
113409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        || format == WebGLImageConversion::DataFormatBGRA8
113509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        || format == WebGLImageConversion::DataFormatARGB8
113609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        || format == WebGLImageConversion::DataFormatABGR8
113709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        || format == WebGLImageConversion::DataFormatRGBA16F
113809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        || format == WebGLImageConversion::DataFormatRGBA32F
113909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        || format == WebGLImageConversion::DataFormatRGBA4444
114009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        || format == WebGLImageConversion::DataFormatRGBA5551;
114193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
114293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
114393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)bool HasColor(int format)
114493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
114509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    return format == WebGLImageConversion::DataFormatRGBA8
114609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        || format == WebGLImageConversion::DataFormatRGBA16F
114709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        || format == WebGLImageConversion::DataFormatRGBA32F
114809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        || format == WebGLImageConversion::DataFormatRGB8
114909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        || format == WebGLImageConversion::DataFormatRGB16F
115009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        || format == WebGLImageConversion::DataFormatRGB32F
115109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        || format == WebGLImageConversion::DataFormatBGR8
115209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        || format == WebGLImageConversion::DataFormatBGRA8
115309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        || format == WebGLImageConversion::DataFormatARGB8
115409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        || format == WebGLImageConversion::DataFormatABGR8
115509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        || format == WebGLImageConversion::DataFormatRGBA5551
115609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        || format == WebGLImageConversion::DataFormatRGBA4444
115709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        || format == WebGLImageConversion::DataFormatRGB565
115809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        || format == WebGLImageConversion::DataFormatR8
115909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        || format == WebGLImageConversion::DataFormatR16F
116009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        || format == WebGLImageConversion::DataFormatR32F
116109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        || format == WebGLImageConversion::DataFormatRA8
116209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        || format == WebGLImageConversion::DataFormatRA16F
116309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        || format == WebGLImageConversion::DataFormatRA32F
116409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        || format == WebGLImageConversion::DataFormatAR8;
116593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
116693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
116793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)template<int Format>
116893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)struct IsFloatFormat {
116993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    static const bool Value =
117009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        Format == WebGLImageConversion::DataFormatRGBA32F
117109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        || Format == WebGLImageConversion::DataFormatRGB32F
117209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        || Format == WebGLImageConversion::DataFormatRA32F
117309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        || Format == WebGLImageConversion::DataFormatR32F
117409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        || Format == WebGLImageConversion::DataFormatA32F;
117593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)};
117693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
117793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)template<int Format>
117893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)struct IsHalfFloatFormat {
117993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    static const bool Value =
118009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        Format == WebGLImageConversion::DataFormatRGBA16F
118109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        || Format == WebGLImageConversion::DataFormatRGB16F
118209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        || Format == WebGLImageConversion::DataFormatRA16F
118309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        || Format == WebGLImageConversion::DataFormatR16F
118409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        || Format == WebGLImageConversion::DataFormatA16F;
118593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)};
118693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
118793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)template<int Format>
118893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)struct Is16bppFormat {
118993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    static const bool Value =
119009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        Format == WebGLImageConversion::DataFormatRGBA5551
119109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        || Format == WebGLImageConversion::DataFormatRGBA4444
119209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        || Format == WebGLImageConversion::DataFormatRGB565;
119393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)};
119493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
119593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)template<int Format, bool IsFloat = IsFloatFormat<Format>::Value, bool IsHalfFloat = IsHalfFloatFormat<Format>::Value, bool Is16bpp = Is16bppFormat<Format>::Value>
119693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)struct DataTypeForFormat {
119793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    typedef uint8_t Type;
119893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)};
119993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
120093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)template<int Format>
120193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)struct DataTypeForFormat<Format, true, false, false> {
120293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    typedef float Type;
120393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)};
120493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
120593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)template<int Format>
120693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)struct DataTypeForFormat<Format, false, true, false> {
120793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    typedef uint16_t Type;
120893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)};
120993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
121093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)template<int Format>
121193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)struct DataTypeForFormat<Format, false, false, true> {
121293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    typedef uint16_t Type;
121393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)};
121493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
121593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)template<int Format>
121693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)struct IntermediateFormat {
121709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    static const int Value = (IsFloatFormat<Format>::Value || IsHalfFloatFormat<Format>::Value) ? WebGLImageConversion::DataFormatRGBA32F : WebGLImageConversion::DataFormatRGBA8;
121893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)};
121993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
122009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)unsigned TexelBytesForFormat(WebGLImageConversion::DataFormat format)
122193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
122293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    switch (format) {
122309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case WebGLImageConversion::DataFormatR8:
122409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case WebGLImageConversion::DataFormatA8:
122593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return 1;
122609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case WebGLImageConversion::DataFormatRA8:
122709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case WebGLImageConversion::DataFormatAR8:
122809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case WebGLImageConversion::DataFormatRGBA5551:
122909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case WebGLImageConversion::DataFormatRGBA4444:
123009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case WebGLImageConversion::DataFormatRGB565:
123109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case WebGLImageConversion::DataFormatA16F:
123209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case WebGLImageConversion::DataFormatR16F:
123393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return 2;
123409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case WebGLImageConversion::DataFormatRGB8:
123509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case WebGLImageConversion::DataFormatBGR8:
123693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return 3;
123709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case WebGLImageConversion::DataFormatRGBA8:
123809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case WebGLImageConversion::DataFormatARGB8:
123909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case WebGLImageConversion::DataFormatABGR8:
124009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case WebGLImageConversion::DataFormatBGRA8:
124109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case WebGLImageConversion::DataFormatR32F:
124209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case WebGLImageConversion::DataFormatA32F:
124309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case WebGLImageConversion::DataFormatRA16F:
124493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return 4;
124509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case WebGLImageConversion::DataFormatRGB16F:
124693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return 6;
124709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case WebGLImageConversion::DataFormatRA32F:
124809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case WebGLImageConversion::DataFormatRGBA16F:
124993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return 8;
125009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case WebGLImageConversion::DataFormatRGB32F:
125193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return 12;
125209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case WebGLImageConversion::DataFormatRGBA32F:
125393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return 16;
125493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    default:
125593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return 0;
125693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
125793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
125893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
125993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)/* END CODE SHARED WITH MOZILLA FIREFOX */
126093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
126193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)class FormatConverter {
126293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)public:
126393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    FormatConverter(unsigned width, unsigned height,
126493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        const void* srcStart, void* dstStart, int srcStride, int dstStride)
126593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        : m_width(width), m_height(height), m_srcStart(srcStart), m_dstStart(dstStart), m_srcStride(srcStride), m_dstStride(dstStride), m_success(false)
126693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    {
126793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        const unsigned MaxNumberOfComponents = 4;
126893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        const unsigned MaxBytesPerComponent  = 4;
126993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        m_unpackedIntermediateSrcData = adoptArrayPtr(new uint8_t[m_width * MaxNumberOfComponents *MaxBytesPerComponent]);
127093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        ASSERT(m_unpackedIntermediateSrcData.get());
127193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
127293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
127309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    void convert(WebGLImageConversion::DataFormat srcFormat, WebGLImageConversion::DataFormat dstFormat, WebGLImageConversion::AlphaOp);
127493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    bool Success() const { return m_success; }
127593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
127693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)private:
127709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    template<WebGLImageConversion::DataFormat SrcFormat>
127809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    void convert(WebGLImageConversion::DataFormat dstFormat, WebGLImageConversion::AlphaOp);
127993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
128009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    template<WebGLImageConversion::DataFormat SrcFormat, WebGLImageConversion::DataFormat DstFormat>
128109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    void convert(WebGLImageConversion::AlphaOp);
128293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
128309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    template<WebGLImageConversion::DataFormat SrcFormat, WebGLImageConversion::DataFormat DstFormat, WebGLImageConversion::AlphaOp alphaOp>
128493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    void convert();
128593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
128693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    const unsigned m_width, m_height;
128793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    const void* const m_srcStart;
128893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    void* const m_dstStart;
128993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    const int m_srcStride, m_dstStride;
129093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    bool m_success;
12911e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    OwnPtr<uint8_t[]> m_unpackedIntermediateSrcData;
129293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)};
129393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
129409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)void FormatConverter::convert(WebGLImageConversion::DataFormat srcFormat, WebGLImageConversion::DataFormat dstFormat, WebGLImageConversion::AlphaOp alphaOp)
129593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
129693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#define FORMATCONVERTER_CASE_SRCFORMAT(SrcFormat) \
129793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    case SrcFormat: \
129893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return convert<SrcFormat>(dstFormat, alphaOp);
129993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
130093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        switch (srcFormat) {
130109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatR8)
130209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatA8)
130309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatR32F)
130409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatA32F)
130509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatRA8)
130609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatRA32F)
130709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatRGB8)
130809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatBGR8)
130909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatRGB565)
131009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatRGB32F)
131109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatRGBA8)
131209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatARGB8)
131309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatABGR8)
131409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatAR8)
131509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatBGRA8)
131609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatRGBA5551)
131709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatRGBA4444)
131809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatRGBA32F)
131993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        default:
132093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            ASSERT_NOT_REACHED();
132193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        }
132293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#undef FORMATCONVERTER_CASE_SRCFORMAT
132393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
132493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
132509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<WebGLImageConversion::DataFormat SrcFormat>
132609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)void FormatConverter::convert(WebGLImageConversion::DataFormat dstFormat, WebGLImageConversion::AlphaOp alphaOp)
132793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
132893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#define FORMATCONVERTER_CASE_DSTFORMAT(DstFormat) \
132993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    case DstFormat: \
133093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return convert<SrcFormat, DstFormat>(alphaOp);
133193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
133293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        switch (dstFormat) {
133309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatR8)
133409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatR16F)
133509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatR32F)
133609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatA8)
133709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatA16F)
133809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatA32F)
133909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatRA8)
134009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatRA16F)
134109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatRA32F)
134209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatRGB8)
134309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatRGB565)
134409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatRGB16F)
134509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatRGB32F)
134609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatRGBA8)
134709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatRGBA5551)
134809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatRGBA4444)
134909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatRGBA16F)
135009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatRGBA32F)
135193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        default:
135293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            ASSERT_NOT_REACHED();
135393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        }
135493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
135593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#undef FORMATCONVERTER_CASE_DSTFORMAT
135693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
135793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
135809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<WebGLImageConversion::DataFormat SrcFormat, WebGLImageConversion::DataFormat DstFormat>
135909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)void FormatConverter::convert(WebGLImageConversion::AlphaOp alphaOp)
136093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
136193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#define FORMATCONVERTER_CASE_ALPHAOP(alphaOp) \
136293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    case alphaOp: \
136393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return convert<SrcFormat, DstFormat, alphaOp>();
136493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
136593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        switch (alphaOp) {
136609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            FORMATCONVERTER_CASE_ALPHAOP(WebGLImageConversion::AlphaDoNothing)
136709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            FORMATCONVERTER_CASE_ALPHAOP(WebGLImageConversion::AlphaDoPremultiply)
136809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            FORMATCONVERTER_CASE_ALPHAOP(WebGLImageConversion::AlphaDoUnmultiply)
136993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        default:
137093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            ASSERT_NOT_REACHED();
137193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        }
137293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#undef FORMATCONVERTER_CASE_ALPHAOP
137393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
137493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
137509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template<WebGLImageConversion::DataFormat SrcFormat, WebGLImageConversion::DataFormat DstFormat, WebGLImageConversion::AlphaOp alphaOp>
137693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)void FormatConverter::convert()
137793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
137893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    // Many instantiations of this template function will never be entered, so we try
137993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    // to return immediately in these cases to avoid the compiler to generate useless code.
138009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (SrcFormat == DstFormat && alphaOp == WebGLImageConversion::AlphaDoNothing) {
138193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        ASSERT_NOT_REACHED();
138293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return;
138393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
138493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (!IsFloatFormat<DstFormat>::Value && IsFloatFormat<SrcFormat>::Value) {
138593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        ASSERT_NOT_REACHED();
138693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return;
138793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
138893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
138993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    // Only textures uploaded from DOM elements or ImageData can allow DstFormat != SrcFormat.
139009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    const bool srcFormatComesFromDOMElementOrImageData = WebGLImageConversion::srcFormatComeFromDOMElementOrImageData(SrcFormat);
139193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (!srcFormatComesFromDOMElementOrImageData && SrcFormat != DstFormat) {
139293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        ASSERT_NOT_REACHED();
139393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return;
139493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
139593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    // Likewise, only textures uploaded from DOM elements or ImageData can possibly have to be unpremultiplied.
139609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (!srcFormatComesFromDOMElementOrImageData && alphaOp == WebGLImageConversion::AlphaDoUnmultiply) {
139793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        ASSERT_NOT_REACHED();
139893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return;
139993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
140009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if ((!HasAlpha(SrcFormat) || !HasColor(SrcFormat) || !HasColor(DstFormat)) && alphaOp != WebGLImageConversion::AlphaDoNothing) {
140193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        ASSERT_NOT_REACHED();
140293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return;
140393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
140493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
140593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    typedef typename DataTypeForFormat<SrcFormat>::Type SrcType;
140693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    typedef typename DataTypeForFormat<DstFormat>::Type DstType;
140793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    const int IntermediateSrcFormat = IntermediateFormat<DstFormat>::Value;
140893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    typedef typename DataTypeForFormat<IntermediateSrcFormat>::Type IntermediateSrcType;
140993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    const ptrdiff_t srcStrideInElements = m_srcStride / sizeof(SrcType);
141093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    const ptrdiff_t dstStrideInElements = m_dstStride / sizeof(DstType);
141109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    const bool trivialUnpack = (SrcFormat == WebGLImageConversion::DataFormatRGBA8 && !IsFloatFormat<DstFormat>::Value && !IsHalfFloatFormat<DstFormat>::Value) || SrcFormat == WebGLImageConversion::DataFormatRGBA32F;
141209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    const bool trivialPack = (DstFormat == WebGLImageConversion::DataFormatRGBA8 || DstFormat == WebGLImageConversion::DataFormatRGBA32F) && alphaOp == WebGLImageConversion::AlphaDoNothing && m_dstStride > 0;
141393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    ASSERT(!trivialUnpack || !trivialPack);
141493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
141593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    const SrcType *srcRowStart = static_cast<const SrcType*>(m_srcStart);
141693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    DstType* dstRowStart = static_cast<DstType*>(m_dstStart);
141793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (!trivialUnpack && trivialPack) {
141893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        for (size_t i = 0; i < m_height; ++i) {
141993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            unpack<SrcFormat>(srcRowStart, dstRowStart, m_width);
142093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            srcRowStart += srcStrideInElements;
142193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            dstRowStart += dstStrideInElements;
142293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        }
142393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    } else if (!trivialUnpack && !trivialPack) {
142493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        for (size_t i = 0; i < m_height; ++i) {
142593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            unpack<SrcFormat>(srcRowStart, reinterpret_cast<IntermediateSrcType*>(m_unpackedIntermediateSrcData.get()), m_width);
142693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            pack<DstFormat, alphaOp>(reinterpret_cast<IntermediateSrcType*>(m_unpackedIntermediateSrcData.get()), dstRowStart, m_width);
142793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            srcRowStart += srcStrideInElements;
142893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            dstRowStart += dstStrideInElements;
142993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        }
143093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    } else {
143193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        for (size_t i = 0; i < m_height; ++i) {
143293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            pack<DstFormat, alphaOp>(srcRowStart, dstRowStart, m_width);
143393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            srcRowStart += srcStrideInElements;
143493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            dstRowStart += dstStrideInElements;
143593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        }
143693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
143793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    m_success = true;
143893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    return;
143993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
144093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
144193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)} // anonymous namespace
144293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
144309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)bool WebGLImageConversion::computeFormatAndTypeParameters(GLenum format, GLenum type, unsigned* componentsPerPixel, unsigned* bytesPerComponent)
144409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
144509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    switch (format) {
144609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case GL_ALPHA:
144709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case GL_LUMINANCE:
144809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case GL_DEPTH_COMPONENT:
144909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case GL_DEPTH_STENCIL_OES:
145009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        *componentsPerPixel = 1;
145109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        break;
145209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case GL_LUMINANCE_ALPHA:
145309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        *componentsPerPixel = 2;
145409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        break;
145509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case GL_RGB:
145609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        *componentsPerPixel = 3;
145709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        break;
145809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case GL_RGBA:
145909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case GL_BGRA_EXT: // GL_EXT_texture_format_BGRA8888
146009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        *componentsPerPixel = 4;
146109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        break;
146209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    default:
146309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return false;
146409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
146509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    switch (type) {
146609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case GL_UNSIGNED_BYTE:
146709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        *bytesPerComponent = sizeof(GLubyte);
146809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        break;
146909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case GL_UNSIGNED_SHORT:
147009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        *bytesPerComponent = sizeof(GLushort);
147109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        break;
147209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case GL_UNSIGNED_SHORT_5_6_5:
147309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case GL_UNSIGNED_SHORT_4_4_4_4:
147409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case GL_UNSIGNED_SHORT_5_5_5_1:
147509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        *componentsPerPixel = 1;
147609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        *bytesPerComponent = sizeof(GLushort);
147709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        break;
147809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case GL_UNSIGNED_INT_24_8_OES:
147909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case GL_UNSIGNED_INT:
148009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        *bytesPerComponent = sizeof(GLuint);
148109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        break;
148209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case GL_FLOAT: // OES_texture_float
148309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        *bytesPerComponent = sizeof(GLfloat);
148409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        break;
148509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case GL_HALF_FLOAT_OES: // OES_texture_half_float
148609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        *bytesPerComponent = sizeof(GLushort);
148709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        break;
148809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    default:
148909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return false;
149009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
149109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    return true;
149209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
149309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
149409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)GLenum WebGLImageConversion::computeImageSizeInBytes(GLenum format, GLenum type, GLsizei width, GLsizei height, GLint alignment, unsigned* imageSizeInBytes, unsigned* paddingInBytes)
149509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
149609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    ASSERT(imageSizeInBytes);
149709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    ASSERT(alignment == 1 || alignment == 2 || alignment == 4 || alignment == 8);
149809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (width < 0 || height < 0)
149909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return GL_INVALID_VALUE;
150009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    unsigned bytesPerComponent, componentsPerPixel;
150109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (!computeFormatAndTypeParameters(format, type, &bytesPerComponent, &componentsPerPixel))
150209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return GL_INVALID_ENUM;
150309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (!width || !height) {
150409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        *imageSizeInBytes = 0;
150509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        if (paddingInBytes)
150609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            *paddingInBytes = 0;
150709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return GL_NO_ERROR;
150809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
150909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    CheckedInt<uint32_t> checkedValue(bytesPerComponent * componentsPerPixel);
151009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    checkedValue *=  width;
151109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (!checkedValue.isValid())
151209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return GL_INVALID_VALUE;
151309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    unsigned validRowSize = checkedValue.value();
151409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    unsigned padding = 0;
151509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    unsigned residual = validRowSize % alignment;
151609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (residual) {
151709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        padding = alignment - residual;
151809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        checkedValue += padding;
151909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
152009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // Last row needs no padding.
152109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    checkedValue *= (height - 1);
152209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    checkedValue += validRowSize;
152309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (!checkedValue.isValid())
152409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return GL_INVALID_VALUE;
152509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    *imageSizeInBytes = checkedValue.value();
152609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (paddingInBytes)
152709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        *paddingInBytes = padding;
152809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    return GL_NO_ERROR;
152909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
153009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
153109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)WebGLImageConversion::ImageExtractor::ImageExtractor(Image* image, ImageHtmlDomSource imageHtmlDomSource, bool premultiplyAlpha, bool ignoreGammaAndColorProfile)
153209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
153309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    m_image = image;
153409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    m_imageHtmlDomSource = imageHtmlDomSource;
153509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    m_extractSucceeded = extractImage(premultiplyAlpha, ignoreGammaAndColorProfile);
153609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
153709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
153809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)WebGLImageConversion::ImageExtractor::~ImageExtractor()
153909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
154009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (m_skiaImage)
154109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        m_skiaImage->bitmap().unlockPixels();
154209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
154309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
154409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)bool WebGLImageConversion::ImageExtractor::extractImage(bool premultiplyAlpha, bool ignoreGammaAndColorProfile)
154509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
154609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (!m_image)
154709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return false;
154809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    m_skiaImage = m_image->nativeImageForCurrentFrame();
154909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    m_alphaOp = AlphaDoNothing;
155009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    bool hasAlpha = m_skiaImage ? !m_skiaImage->bitmap().isOpaque() : true;
155109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if ((!m_skiaImage || ignoreGammaAndColorProfile || (hasAlpha && !premultiplyAlpha)) && m_image->data()) {
155209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        // Attempt to get raw unpremultiplied image data.
155309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        OwnPtr<ImageDecoder> decoder(ImageDecoder::create(
155409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            *(m_image->data()), ImageSource::AlphaNotPremultiplied,
155509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            ignoreGammaAndColorProfile ? ImageSource::GammaAndColorProfileIgnored : ImageSource::GammaAndColorProfileApplied));
155609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        if (!decoder)
155709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            return false;
155809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        decoder->setData(m_image->data(), true);
155909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        if (!decoder->frameCount())
156009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            return false;
156109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        ImageFrame* frame = decoder->frameBufferAtIndex(0);
156209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        if (!frame || frame->status() != ImageFrame::FrameComplete)
156309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            return false;
156409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        hasAlpha = frame->hasAlpha();
156509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        m_nativeImage = frame->asNewNativeImage();
156609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        if (!m_nativeImage.get() || !m_nativeImage->isDataComplete() || !m_nativeImage->bitmap().width() || !m_nativeImage->bitmap().height())
156709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            return false;
1568197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        if (m_nativeImage->bitmap().colorType() != kN32_SkColorType)
156909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            return false;
157009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        m_skiaImage = m_nativeImage.get();
157109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        if (hasAlpha && premultiplyAlpha)
157209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            m_alphaOp = AlphaDoPremultiply;
157309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    } else if (!premultiplyAlpha && hasAlpha) {
157409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        // 1. For texImage2D with HTMLVideoElment input, assume no PremultiplyAlpha had been applied and the alpha value for each pixel is 0xFF
157509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        // which is true at present and may be changed in the future and needs adjustment accordingly.
157609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        // 2. For texImage2D with HTMLCanvasElement input in which Alpha is already Premultiplied in this port,
157709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        // do AlphaDoUnmultiply if UNPACK_PREMULTIPLY_ALPHA_WEBGL is set to false.
157809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        if (m_imageHtmlDomSource != HtmlDomVideo)
157909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            m_alphaOp = AlphaDoUnmultiply;
158009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
158109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (!m_skiaImage)
158209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return false;
158309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
158409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    m_imageSourceFormat = SK_B32_SHIFT ? DataFormatRGBA8 : DataFormatBGRA8;
158509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    m_imageWidth = m_skiaImage->bitmap().width();
158609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    m_imageHeight = m_skiaImage->bitmap().height();
1587aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    if (!m_imageWidth || !m_imageHeight) {
1588aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch        m_skiaImage.clear();
158909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return false;
1590aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    }
159107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    // Fail if the image was downsampled because of memory limits.
1592aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    if (m_imageWidth != (unsigned)m_image->size().width() || m_imageHeight != (unsigned)m_image->size().height()) {
1593aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch        m_skiaImage.clear();
159407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        return false;
1595aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    }
159609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    m_imageSourceUnpackAlignment = 0;
159709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    m_skiaImage->bitmap().lockPixels();
159809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    m_imagePixelData = m_skiaImage->bitmap().getPixels();
159909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    return true;
160009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
160109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
160209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)unsigned WebGLImageConversion::getClearBitsByFormat(GLenum format)
160309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
160409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    switch (format) {
160509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case GL_ALPHA:
160609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case GL_LUMINANCE:
160709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case GL_LUMINANCE_ALPHA:
160809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case GL_RGB:
160909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case GL_RGB565:
161009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case GL_RGBA:
161109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case GL_RGBA4:
161209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case GL_RGB5_A1:
161309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return GL_COLOR_BUFFER_BIT;
161409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case GL_DEPTH_COMPONENT16:
161509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case GL_DEPTH_COMPONENT:
161609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return GL_DEPTH_BUFFER_BIT;
161709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case GL_STENCIL_INDEX8:
161809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return GL_STENCIL_BUFFER_BIT;
161909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case GL_DEPTH_STENCIL_OES:
162009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
162109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    default:
162209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return 0;
162309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
162409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
162509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
162609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)unsigned WebGLImageConversion::getChannelBitsByFormat(GLenum format)
162709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
162809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    switch (format) {
162909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case GL_ALPHA:
163009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return ChannelAlpha;
163109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case GL_LUMINANCE:
163209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return ChannelRGB;
163309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case GL_LUMINANCE_ALPHA:
163409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return ChannelRGBA;
163509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case GL_RGB:
163609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case GL_RGB565:
163709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return ChannelRGB;
163809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case GL_RGBA:
163909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case GL_RGBA4:
164009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case GL_RGB5_A1:
164109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return ChannelRGBA;
164209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case GL_DEPTH_COMPONENT16:
164309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case GL_DEPTH_COMPONENT:
164409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return ChannelDepth;
164509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case GL_STENCIL_INDEX8:
164609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return ChannelStencil;
164709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    case GL_DEPTH_STENCIL_OES:
164809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return ChannelDepth | ChannelStencil;
164909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    default:
165009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return 0;
165109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
165209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
165309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
165409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)bool WebGLImageConversion::packImageData(
165593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    Image* image,
165693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    const void* pixels,
165709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    GLenum format,
165809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    GLenum type,
165993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    bool flipY,
166093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    AlphaOp alphaOp,
166193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    DataFormat sourceFormat,
166293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    unsigned width,
166393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    unsigned height,
166493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    unsigned sourceUnpackAlignment,
166593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    Vector<uint8_t>& data)
166693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
166793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (!pixels)
166893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return false;
166993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
167093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    unsigned packedSize;
167193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    // Output data is tightly packed (alignment == 1).
167209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (computeImageSizeInBytes(format, type, width, height, 1, &packedSize, 0) != GL_NO_ERROR)
167393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return false;
167493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    data.resize(packedSize);
167593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
167693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (!packPixels(reinterpret_cast<const uint8_t*>(pixels), sourceFormat, width, height, sourceUnpackAlignment, format, type, alphaOp, data.data(), flipY))
167793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return false;
167893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (ImageObserver *observer = image->imageObserver())
167993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        observer->didDraw(image);
168093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    return true;
168193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
168293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
168309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)bool WebGLImageConversion::extractImageData(
168451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    const uint8_t* imageData,
168551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    const IntSize& imageDataSize,
168609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    GLenum format,
168709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    GLenum type,
168893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    bool flipY,
168993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    bool premultiplyAlpha,
169093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    Vector<uint8_t>& data)
169193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
169293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (!imageData)
169393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return false;
169451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    int width = imageDataSize.width();
169551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    int height = imageDataSize.height();
169693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
169793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    unsigned packedSize;
169893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    // Output data is tightly packed (alignment == 1).
169909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (computeImageSizeInBytes(format, type, width, height, 1, &packedSize, 0) != GL_NO_ERROR)
170093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return false;
170193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    data.resize(packedSize);
170293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
170351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (!packPixels(imageData, DataFormatRGBA8, width, height, 0, format, type, premultiplyAlpha ? AlphaDoPremultiply : AlphaDoNothing, data.data(), flipY))
170493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return false;
170593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
170693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    return true;
170793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
170893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
170909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)bool WebGLImageConversion::extractTextureData(
171093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    unsigned width,
171193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    unsigned height,
171209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    GLenum format, GLenum type,
171393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    unsigned unpackAlignment,
171493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    bool flipY, bool premultiplyAlpha,
171593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    const void* pixels,
171693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    Vector<uint8_t>& data)
171793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
171893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    // Assumes format, type, etc. have already been validated.
171993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    DataFormat sourceDataFormat = getDataFormat(format, type);
172093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
172193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    // Resize the output buffer.
172293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    unsigned int componentsPerPixel, bytesPerComponent;
172393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (!computeFormatAndTypeParameters(format, type, &componentsPerPixel, &bytesPerComponent))
172493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return false;
172593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    unsigned bytesPerPixel = componentsPerPixel * bytesPerComponent;
172693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    data.resize(width * height * bytesPerPixel);
172793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
172893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (!packPixels(static_cast<const uint8_t*>(pixels), sourceDataFormat, width, height, unpackAlignment, format, type, (premultiplyAlpha ? AlphaDoPremultiply : AlphaDoNothing), data.data(), flipY))
172993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return false;
173093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
173193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    return true;
173293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
173393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
173409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)bool WebGLImageConversion::packPixels(
173593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    const uint8_t* sourceData,
173693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    DataFormat sourceDataFormat,
173793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    unsigned width,
173893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    unsigned height,
173993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    unsigned sourceUnpackAlignment,
174093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    unsigned destinationFormat,
174193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    unsigned destinationType,
174293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    AlphaOp alphaOp,
174393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    void* destinationData,
174493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    bool flipY)
174593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
174693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    int validSrc = width * TexelBytesForFormat(sourceDataFormat);
174793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    int remainder = sourceUnpackAlignment ? (validSrc % sourceUnpackAlignment) : 0;
174893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    int srcStride = remainder ? (validSrc + sourceUnpackAlignment - remainder) : validSrc;
174993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
175093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    DataFormat dstDataFormat = getDataFormat(destinationFormat, destinationType);
175193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    int dstStride = width * TexelBytesForFormat(dstDataFormat);
175293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (flipY) {
175393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        destinationData = static_cast<uint8_t*>(destinationData) + dstStride*(height - 1);
175493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        dstStride = -dstStride;
175593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
175693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (!HasAlpha(sourceDataFormat) || !HasColor(sourceDataFormat) || !HasColor(dstDataFormat))
175793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        alphaOp = AlphaDoNothing;
175893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
175993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (sourceDataFormat == dstDataFormat && alphaOp == AlphaDoNothing) {
176093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        const uint8_t* ptr = sourceData;
176193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        const uint8_t* ptrEnd = sourceData + srcStride * height;
176293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        unsigned rowSize = (dstStride > 0) ? dstStride: -dstStride;
176393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        uint8_t* dst = static_cast<uint8_t*>(destinationData);
176493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        while (ptr < ptrEnd) {
176593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            memcpy(dst, ptr, rowSize);
176693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            ptr += srcStride;
176793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            dst += dstStride;
176893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        }
176993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return true;
177093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
177193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
177293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    FormatConverter converter(width, height, sourceData, destinationData, srcStride, dstStride);
177393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    converter.convert(sourceDataFormat, dstDataFormat, alphaOp);
177493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    if (!converter.Success())
177593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        return false;
177693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    return true;
177793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
177893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
1779c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink
1780