function uploadDDSLevels(gl, ext, arrayBuffer, loadMipmaps) {
        var header = new Int32Array(arrayBuffer, 0, headerLengthInt),
            fourCC, blockBytes, internalFormat,
            width, height, dataLength, dataOffset, is_cubemap,
            rgb565Data, byteArray, mipmapCount, i, face;

        if(header[off_magic] != DDS_MAGIC) {
            console.error("Invalid magic number in DDS header");
            return 0;
        }
        
        if(!header[off_pfFlags] & DDPF_FOURCC) {
            console.error("Unsupported format, must contain a FourCC code");
            return 0;
        }

        fourCC = header[off_pfFourCC];
        switch(fourCC) {
            case FOURCC_DXT1:
                blockBytes = 8;
                internalFormat = ext ? ext.COMPRESSED_RGB_S3TC_DXT1_EXT : null;
                break;

			/*
            case FOURCC_DXT1:
                blockBytes = 8;
                internalFormat = ext ? ext.COMPRESSED_RGBA_S3TC_DXT1_EXT : null;
                break;
			*/

            case FOURCC_DXT3:
                blockBytes = 16;
                internalFormat = ext ? ext.COMPRESSED_RGBA_S3TC_DXT3_EXT : null;
                break;

            case FOURCC_DXT5:
                blockBytes = 16;
                internalFormat = ext ? ext.COMPRESSED_RGBA_S3TC_DXT5_EXT : null;
                break;

            default:
				blockBytes = 4;
				fourCC = null;
				internalFormat = gl.RGBA;
                //console.error("Unsupported FourCC code:", int32ToFourCC(fourCC), fourCC);
                //return null;
        }

        mipmapCount = 1;
        if(header[off_flags] & DDSD_MIPMAPCOUNT && loadMipmaps !== false) {
            mipmapCount = Math.max(1, header[off_mipmapCount]);
        }

        width = header[off_width];
        height = header[off_height];
        dataOffset = header[off_size] + 4;
		is_cubemap = !!(header[off_caps+1] & DDSCAPS2_CUBEMAP);

		if(is_cubemap)
		{
			//console.error("Cubemaps not supported in DDS");
			//return null;

			for(face = 0; face < 6; ++face)
			{
				width = header[off_width];
				height = header[off_height];
				for(var i = 0; i < mipmapCount; ++i) {
					if(fourCC)
					{
						dataLength = Math.max( 4, width )/4 * Math.max( 4, height )/4 * blockBytes;
						byteArray = new Uint8Array(arrayBuffer, dataOffset, dataLength);
						flipDXT( width, blockBytes, byteArray );
						gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + face, i, internalFormat, width, height, 0, byteArray);
					}
					else
					{
						gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false );
						dataLength = width * height * blockBytes;
						byteArray = new Uint8Array(arrayBuffer, dataOffset, dataLength);
						BGRtoRGB(byteArray);
						gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + face, i, internalFormat, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, byteArray);
					}
					dataOffset += dataLength;
					width *= 0.5;
					height *= 0.5;
				}
			}
		}
		else //2d texture
		{
			if(ext) {
				gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true );
				for(var i = 0; i < mipmapCount; ++i) {
					if(fourCC)
					{
						dataLength = Math.max( 4, width )/4 * Math.max( 4, height )/4 * blockBytes;
						byteArray = new Uint8Array(arrayBuffer, dataOffset, dataLength);
						gl.compressedTexImage2D(gl.TEXTURE_2D, i, internalFormat, width, height, 0, byteArray);
					}
					else
					{
						dataLength = width * height * blockBytes;
						byteArray = new Uint8Array(arrayBuffer, dataOffset, dataLength);
						BGRtoRGB(byteArray);
						gl.texImage2D(gl.TEXTURE_2D, i, internalFormat, width, height, 0, internalFormat, gl.UNSIGNED_BYTE, byteArray);
					}
					dataOffset += dataLength;
					width *= 0.5;
					height *= 0.5;
				}
			} else {
				if(fourCC == FOURCC_DXT1) {
					dataLength = Math.max( 4, width )/4 * Math.max( 4, height )/4 * blockBytes;
					byteArray = new Uint16Array(arrayBuffer);
					//Decompress
					rgb565Data = dxtToRgb565(byteArray, dataOffset / 2, width, height);
					gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, width, height, 0, gl.RGB, gl.UNSIGNED_SHORT_5_6_5, rgb565Data);
					if(loadMipmaps) {
						gl.generateMipmap(gl.TEXTURE_2D);
					}
				} else {
					console.error("No manual decoder for", int32ToFourCC(fourCC), "and no native support");
					return 0;
				}
			}
		}

        return mipmapCount;
    }
Parses a DDS file from the given arrayBuffer and uploads it into the currently bound texture

@param {WebGLRenderingContext} gl WebGL rendering context
@param {WebGLCompressedTextureS3TC} ext WEBGL_compressed_texture_s3tc extension object
@param {TypedArray} arrayBuffer Array Buffer containing the DDS files data
@param {boolean} [loadMipmaps] If false only the top mipmap level will be loaded, otherwise all available mipmaps will be uploaded

@returns {number} Number of mipmaps uploaded, 0 if there was an error