private unsafe List <(Texture2D, int)> LoadAnimation(string loadPath)
    {
        List <(Texture2D, int)> ret = new List <(Texture2D, int)>();
        TextAsset textasset         = Resources.Load <TextAsset>(loadPath);

        byte[] bytes = textasset.bytes;
        WebPAnimDecoderOptions option = new WebPAnimDecoderOptions
        {
            use_threads = 1,
            color_mode  = (unity.libwebp.Interop.WEBP_CSP_MODE)WEBP_CSP_MODE.MODE_RGBA
        };

        NativeLibwebpdemux.WebPAnimDecoderOptionsInit(&option);
        fixed(byte *p = bytes)
        {
            WebPData webpdata = new WebPData
            {
                bytes = p,
                size  = new UIntPtr((uint)bytes.Length)
            };
            WebPAnimDecoder *dec       = NativeLibwebpdemux.WebPAnimDecoderNew(&webpdata, &option);
            WebPAnimInfo     anim_info = new WebPAnimInfo();

            NativeLibwebpdemux.WebPAnimDecoderGetInfo(dec, &anim_info);

            Debug.LogWarning($"{anim_info.frame_count} {anim_info.canvas_width}/{anim_info.canvas_height}");

            int size = (int)anim_info.canvas_width * 4 * (int)anim_info.canvas_height;

            dec->config_.options.flip = 1;
            dec->config_.options.no_fancy_upsampling = 1;

            int timestamp = 0;

            IntPtr pp = new IntPtr();
            byte **unmanagedPointer = (byte **)&pp;

            for (int i = 0; i < anim_info.frame_count; ++i)
            {
                int result = NativeLibwebpdemux.WebPAnimDecoderGetNext(dec, unmanagedPointer, &timestamp);
                Assert.AreEqual(1, result);

                int  lWidth   = (int)anim_info.canvas_width;
                int  lHeight  = (int)anim_info.canvas_height;
                bool lMipmaps = false;
                bool lLinear  = false;

                Texture2D texture = Texture2DExt.CreateWebpTexture2D(lWidth, lHeight, lMipmaps, lLinear);
                texture.LoadRawTextureData(pp, size);
                texture.Apply(updateMipmaps: false, makeNoLongerReadable: true);
                ret.Add((texture, timestamp));
            }
            NativeLibwebpdemux.WebPAnimDecoderReset(dec);
            NativeLibwebpdemux.WebPAnimDecoderDelete(dec);
        }

        return(ret);
    }
Beispiel #2
0
    private unsafe List <(Texture2D, int)> LoadAnimation(string loadPath)
    {
        List <(Texture2D, int)> ret = new List <(Texture2D, int)>();
        TextAsset textasset         = Resources.Load <TextAsset>(loadPath);

        byte[] bytes = textasset.bytes;
        WebPAnimDecoderOptions option = new WebPAnimDecoderOptions
        {
            use_threads = 1,
            color_mode  = WEBP_CSP_MODE.MODE_RGBA,
        };

        option.padding[5] = 1;

        NativeLibwebpdemux.WebPAnimDecoderOptionsInit(&option);
        fixed(byte *p = bytes)
        {
            WebPData webpdata = new WebPData
            {
                bytes = p,
                size  = new UIntPtr((uint)bytes.Length)
            };
            WebPAnimDecoder *dec = NativeLibwebpdemux.WebPAnimDecoderNew(&webpdata, &option);
            //dec->config_.options.flip = 1;

            WebPAnimInfo anim_info = new WebPAnimInfo();

            NativeLibwebpdemux.WebPAnimDecoderGetInfo(dec, &anim_info);

            Debug.LogWarning($"{anim_info.frame_count} {anim_info.canvas_width}/{anim_info.canvas_height}");

            uint size = anim_info.canvas_width * 4 * anim_info.canvas_height;

            int timestamp = 0;

            IntPtr pp = new IntPtr();
            byte **unmanagedPointer = (byte **)&pp;

            for (int i = 0; i < anim_info.frame_count; ++i)
            {
                int result = NativeLibwebpdemux.WebPAnimDecoderGetNext(dec, unmanagedPointer, &timestamp);
                Assert.AreEqual(1, result);

                int  lWidth   = (int)anim_info.canvas_width;
                int  lHeight  = (int)anim_info.canvas_height;
                bool lMipmaps = false;
                bool lLinear  = false;

                Texture2D texture = Texture2DExt.CreateWebpTexture2D(lWidth, lHeight, lMipmaps, lLinear);
                texture.LoadRawTextureData(pp, (int)size);

                {// Flip updown.
                 // ref: https://github.com/netpyoung/unity.webp/issues/25
                 // ref: https://github.com/netpyoung/unity.webp/issues/21
                 // ref: https://github.com/webmproject/libwebp/blob/master/src/demux/anim_decode.c#L309
                    Color[] pixels        = texture.GetPixels();
                    Color[] pixelsFlipped = new Color[pixels.Length];
                    for (int y = 0; y < anim_info.canvas_height; y++)
                    {
                        Array.Copy(pixels, y * anim_info.canvas_width, pixelsFlipped, (anim_info.canvas_height - y - 1) * anim_info.canvas_width, anim_info.canvas_width);
                    }
                    texture.SetPixels(pixelsFlipped);
                }

                texture.Apply();
                ret.Add((texture, timestamp));
            }
            NativeLibwebpdemux.WebPAnimDecoderReset(dec);
            NativeLibwebpdemux.WebPAnimDecoderDelete(dec);
        }

        return(ret);
    }
Beispiel #3
0
 public static extern WebPDemuxer *WebPAnimDecoderGetDemuxer([NativeTypeName("const WebPAnimDecoder *")] WebPAnimDecoder *dec);
Beispiel #4
0
 public static extern void WebPAnimDecoderReset(WebPAnimDecoder *dec);
Beispiel #5
0
 public static extern int WebPAnimDecoderHasMoreFrames([NativeTypeName("const WebPAnimDecoder *")] WebPAnimDecoder *dec);
Beispiel #6
0
 public static extern int WebPAnimDecoderGetNext(WebPAnimDecoder *dec, [NativeTypeName("uint8_t **")] byte **buf, int *timestamp);
Beispiel #7
0
 public static extern int WebPAnimDecoderGetInfo([NativeTypeName("const WebPAnimDecoder *")] WebPAnimDecoder *dec, WebPAnimInfo *info);
Beispiel #8
0
 public static extern void WebPAnimDecoderDelete(WebPAnimDecoder *dec);
    private unsafe List <(Texture2D, int)> LoadAnimation3(string loadPath)
    {
        List <ValueTuple <Texture2D, int> > ret = new List <ValueTuple <Texture2D, int> >();
        TextAsset textasset = Resources.Load <TextAsset>(loadPath);

        byte[] bytes = textasset.bytes;
        WebPAnimDecoderOptions option = new WebPAnimDecoderOptions
        {
            use_threads = 1,
            color_mode  = (unity.libwebp.Interop.WEBP_CSP_MODE)WEBP_CSP_MODE.MODE_RGBA
        };

        unity.libwebp.Interop.WebPDecoderConfig config = new unity.libwebp.Interop.WebPDecoderConfig();
        //if (Decode.WebPInitDecoderConfig(ref config) == 0)
        //{
        //    throw new Exception("WebPInitDecoderConfig failed. Wrong version?");
        //}
        NativeLibwebpdemux.WebPAnimDecoderOptionsInit(&option);

        fixed(byte *p = bytes)
        {
            WebPData webpdata = new WebPData
            {
                bytes = p,
                size  = new UIntPtr((uint)bytes.Length)
            };

            WebPAnimDecoderOptions opt = new WebPAnimDecoderOptions();

            NativeLibwebpdemux.WebPAnimDecoderOptionsInit(&opt);

            WebPAnimDecoder *webPAnimDecoderPtr = NativeLibwebpdemux.WebPAnimDecoderNewInternal(&webpdata, &opt, NativeLibwebpdemux.WEBP_DEMUX_ABI_VERSION);

            //int width = 400;
            //int height = 400;
            {
                //config.input.has_alpha = 1;
                //config.options.bypass_filtering = 1;
                //config.options.no_fancy_upsampling = 1;
                config.options.use_threads = 1;
                //config.options.no_fancy_upsampling = 0;
                //config.options.use_cropping = 0;
                //config.options.use_scaling = 1;
                //config.options.scaled_width = width;
                //config.options.scaled_height = height;
                config.options.flip = 1;
                //config.options.dithering_strength = 100;
                config.output.colorspace = (unity.libwebp.Interop.WEBP_CSP_MODE)WEBP_CSP_MODE.MODE_RGBA;
                //config.output.is_external_memory = 1;
                //config.output.width = width;
                //config.output.height = height;
            }
            webPAnimDecoderPtr->config_ = config;
            WebPAnimInfo anim_info = new WebPAnimInfo();

            NativeLibwebpdemux.WebPAnimDecoderGetInfo(webPAnimDecoderPtr, &anim_info);

            Debug.LogWarning($"{anim_info.frame_count} {anim_info.canvas_width}/{anim_info.canvas_height}");

            int size = (int)anim_info.canvas_width * 4 * (int)anim_info.canvas_height;

            int    timestamp        = 0;
            IntPtr pp               = new IntPtr();
            byte **unmanagedPointer = (byte **)&pp;

            for (int i = 0; i < anim_info.frame_count; ++i)
            {
                int  result   = NativeLibwebpdemux.WebPAnimDecoderGetNext(webPAnimDecoderPtr, unmanagedPointer, &timestamp);
                int  lWidth   = (int)anim_info.canvas_width;
                int  lHeight  = (int)anim_info.canvas_height;
                bool lMipmaps = false;
                bool lLinear  = false;

                Texture2D texture = Texture2DExt.CreateWebpTexture2D(lWidth, lHeight, lMipmaps, lLinear);
                texture.LoadRawTextureData((IntPtr)unmanagedPointer, size);
                texture.Apply(updateMipmaps: false, makeNoLongerReadable: true);
                ret.Add((texture, timestamp));
            }

            NativeLibwebpdemux.WebPAnimDecoderReset(webPAnimDecoderPtr);
            NativeLibwebpdemux.WebPAnimDecoderDelete(webPAnimDecoderPtr);
        }

        return(ret);
    }