public override IEnumerator LoadBytesRoutine(NativeSlice <byte> data, bool linear = false)
        {
            bool yFlipped = true;

            var transcoder = BasisUniversal.GetTranscoderInstance();

            while (transcoder == null)
            {
                yield return(null);

                transcoder = BasisUniversal.GetTranscoderInstance();
            }

            if (transcoder.Open(data))
            {
                var textureType = transcoder.GetTextureType();
                if (textureType == BasisUniversalTextureType.Image2D)
                {
                    yFlipped = transcoder.GetYFlip();
                    IEnumerator en = TranscodeImage2D(transcoder, data, linear);
                    while (en.MoveNext())
                    {
                        yield return(null);
                    }
                    ;
                }
                else
                {
                    Debug.LogErrorFormat("Basis Universal texture type {0} is not supported", textureType);
                }
            }

            BasisUniversal.ReturnTranscoderInstance(transcoder);

            var orientation = TextureOrientation.KTX_DEFAULT;

            if (!yFlipped)
            {
                // Regular basis files (no y_flip) seem to be
                orientation |= TextureOrientation.Y_UP;
            }
            OnTextureLoaded(texture, orientation);
        }
        protected override IEnumerator LoadBytesRoutine(NativeArray <byte> data)
        {
            uint imageIndex = 0;

            Texture2D texture = null;

            var transcoder = BasisUniversal.GetTranscoderInstance();

            while (transcoder == null)
            {
                yield return(null);

                transcoder = BasisUniversal.GetTranscoderInstance();
            }

            if (transcoder.Open(data))
            {
                var meta = transcoder.LoadMetaData();

                var formats = GetFormat(meta, meta.images[imageIndex].levels[0]);

                if (formats.HasValue)
                {
#if KTX_VERBOSE
                    Debug.LogFormat("Transcode to GraphicsFormat {0} ({1})", formats.Value.format, formats.Value.transcodeFormat);
#endif
                    Profiler.BeginSample("BasisUniversalJob");
                    var job = new BasisUniversalJob();

                    job.imageIndex = imageIndex;
                    job.levelIndex = 0;

                    job.result = new NativeArray <bool>(1, KtxNativeInstance.defaultAllocator);

                    var jobHandle = BasisUniversal.LoadBytesJob(
                        ref job,
                        transcoder,
                        data,
                        formats.Value.transcodeFormat
                        );

                    Profiler.EndSample();

                    while (!jobHandle.IsCompleted)
                    {
                        yield return(null);
                    }
                    jobHandle.Complete();

                    if (job.result[0])
                    {
                        Profiler.BeginSample("LoadBytesRoutineGPUupload");
                        uint width;
                        uint height;
                        meta.GetSize(out width, out height);
                        texture = new Texture2D((int)width, (int)height, formats.Value.format, TextureCreationFlags.None);
                        texture.LoadRawTextureData(job.textureData);
                        texture.Apply(false, true);
                        Profiler.EndSample();
                    }
                    else
                    {
                        Debug.LogError(ERR_MSG_TRANSCODE_FAILED);
                    }
                    job.textureData.Dispose();
                    job.result.Dispose();
                }
            }

            BasisUniversal.ReturnTranscoderInstance(transcoder);

            OnTextureLoaded(texture);
        }
        IEnumerator TranscodeImage2D(BasisUniversalTranscoderInstance transcoder, NativeSlice <byte> data, bool linear)
        {
            // Can turn to parameter in future
            uint imageIndex = 0;

            var meta = transcoder.LoadMetaData();

            var formats = GetFormat(meta, meta.images[imageIndex].levels[0], linear);

            if (formats.HasValue)
            {
#if KTX_VERBOSE
                Debug.LogFormat("Transcode to GraphicsFormat {0} ({1})", formats.Value.format, formats.Value.transcodeFormat);
#endif
                Profiler.BeginSample("BasisUniversalJob");
                var job = new BasisUniversalJob();

                job.imageIndex = imageIndex;

                job.result = new NativeArray <bool>(1, KtxNativeInstance.defaultAllocator);

                var jobHandle = BasisUniversal.LoadBytesJob(
                    ref job,
                    transcoder,
                    data,
                    formats.Value.transcodeFormat
                    );

                Profiler.EndSample();

                while (!jobHandle.IsCompleted)
                {
                    yield return(null);
                }
                jobHandle.Complete();

                if (job.result[0])
                {
                    Profiler.BeginSample("LoadBytesRoutineGPUupload");
                    uint width;
                    uint height;
                    meta.GetSize(out width, out height);
                    var flags = TextureCreationFlags.None;
                    if (meta.images[imageIndex].levels.Length > 1)
                    {
                        flags |= TextureCreationFlags.MipChain;
                    }
                    texture = new Texture2D((int)width, (int)height, formats.Value.format, flags);
                    texture.LoadRawTextureData(job.textureData);
                    texture.Apply(false, true);
                    Profiler.EndSample();
                }
                else
                {
                    Debug.LogError(ERR_MSG_TRANSCODE_FAILED);
                }
                job.sizes.Dispose();
                job.offsets.Dispose();
                job.textureData.Dispose();
                job.result.Dispose();
            }
        }