internal unsafe void Init(int _maxCount, bool _need3D)
            {
                context             = default(HandLib.Context);
                context.minHandSize = 60;
                context.maxCount    = (UInt16)_maxCount;

                storage = new HandData[context.maxCount];
                need3D  = _need3D;

                string str = Application.persistentDataPath;

                fixed(byte *path = context.modelPath.folderPath)
                {
                    for (int i = 0; i < str.Length; i++)
                    {
                        path[i] = (byte)str[i];
                    }
                }

                HandLib.Init(ref context);

                if (need3D)
                {
                    Hand3DLib.Init(ref context3D);
                }
            }
        unsafe Task <ITranslator> IDetectService.Detect(ref ImageData image)
        {
            Profiler.BeginSample("HandService.DetectAsync");

            // too small image
            if (image.WebcamWidth < 40)
            {
                Debug.LogWarning("HandService.DetectAsync: image is too small");
                goto DetectDone;
            }
            if (promise != null)
            {
                promise.TrySetCanceled();
                // the number of detected hands
                fixed(HandData *handPtr = translator.storage)
                {
                    translator.count = (UInt16)HandLib.Detect(ref translator.context, ref image, handPtr);
                }

DetectDone:
                // return result in translator form
                promise = new TaskCompletionSource <ITranslator>();
                promise.SetResult(translator);

                Profiler.EndSample();
                return(promise.Task);
        }

        void IDisposable.Dispose()
        {
            Debug.LogWarning("HandService.Dispose");

            HandLib.Release(ref translator.context);
            if (need3D)
            {
                Hand3DLib.Release(ref translator.context3D);
            }
            if (promise == null)
                return; }

            promise.TrySetCanceled();
            promise = null;
        }