| 2035 | } |
| 2036 | |
| 2037 | bool Image::initWithETC2Data(uint8_t* data, ssize_t dataLen, bool ownData) |
| 2038 | { |
| 2039 | const etc2_byte* header = static_cast<const etc2_byte*>(data); |
| 2040 | |
| 2041 | do |
| 2042 | { |
| 2043 | uint32_t format, pixelOffset; |
| 2044 | // check the data |
| 2045 | if (etc2_pkm_is_valid(header)) |
| 2046 | { |
| 2047 | |
| 2048 | _width = etc2_pkm_get_width(header); |
| 2049 | _height = etc2_pkm_get_height(header); |
| 2050 | |
| 2051 | if (0 == _width || 0 == _height) |
| 2052 | break; |
| 2053 | |
| 2054 | format = etc2_pkm_get_format(header); |
| 2055 | pixelOffset = ETC2_PKM_HEADER_SIZE; |
| 2056 | } |
| 2057 | else |
| 2058 | { // we can safe trait as KTX v1 header |
| 2059 | auto header = (KTXv1Header*)data; |
| 2060 | _width = header->pixelWidth; |
| 2061 | _height = header->pixelHeight; |
| 2062 | |
| 2063 | if (0 == _width || 0 == _height) |
| 2064 | break; |
| 2065 | |
| 2066 | format = header->glInternalFormat == KTXv1Header::InternalFormat::ETC2_RGBA8 ? ETC2_RGBA_NO_MIPMAPS |
| 2067 | : ETC2_RGB_NO_MIPMAPS; |
| 2068 | pixelOffset = KTX_V1_HEADER_SIZE + header->bytesOfKeyValueData + 4; |
| 2069 | } |
| 2070 | |
| 2071 | // We only support ETC2_RGBA_NO_MIPMAPS and ETC2_RGB_NO_MIPMAPS |
| 2072 | assert(format == ETC2_RGBA_NO_MIPMAPS || format == ETC2_RGB_NO_MIPMAPS); |
| 2073 | |
| 2074 | if (Configuration::getInstance()->supportsETC2()) |
| 2075 | { |
| 2076 | _pixelFormat = |
| 2077 | format == ETC2_RGBA_NO_MIPMAPS ? backend::PixelFormat::ETC2_RGBA : backend::PixelFormat::ETC2_RGB; |
| 2078 | |
| 2079 | forwardPixels(data, dataLen, pixelOffset, ownData); |
| 2080 | } |
| 2081 | else |
| 2082 | { |
| 2083 | AXLOGW("Hardware ETC2 decoder not present. Using software decoder"); |
| 2084 | |
| 2085 | // if device do not support ETC2, decode texture by software |
| 2086 | // etc2_decode_image always decode to RGBA8888 |
| 2087 | _dataLen = _width * _height * 4; |
| 2088 | _data = static_cast<uint8_t*>(malloc(_dataLen)); |
| 2089 | if (AX_UNLIKELY(etc2_decode_image(format, static_cast<const uint8_t*>(data) + pixelOffset, |
| 2090 | static_cast<etc2_byte*>(_data), _width, _height) != 0)) |
| 2091 | { |
| 2092 | // software decode fail, release pixels data |
| 2093 | AX_SAFE_FREE(_data); |
| 2094 | _dataLen = 0; |
nothing calls this directly
no test coverage detected