public dynamic ResizeRotate(
            Clip clip,
            string resizeFunc, string rotateFunc,
            int width, int height, int angle = 0,
            RectangleD crop = default, Warp warp = default)
        {
            if (clip == null)
            {
                return(null);
            }
            var dynamic = clip.Dynamic();

            if (warp != null && !warp.IsEmpty)
            {
                dynamic = dynamic.Warp(warp.ToArray(), relative: true, resample: OverlayUtils.GetWarpResampleMode(resizeFunc));
            }

            var vi = clip.GetVideoInfo();

            if (crop.IsEmpty && width == vi.width && height == vi.height)
            {
                return(dynamic);
            }

            var intCrop = Rectangle.FromLTRB(
                (int)Math.Floor(crop.Left),
                (int)Math.Floor(crop.Top),
                (int)Math.Floor(crop.Right),
                (int)Math.Floor(crop.Bottom)
                );

            if (!intCrop.IsEmpty)
            {
                dynamic = dynamic.Crop(intCrop.Left, intCrop.Top, -intCrop.Right, -intCrop.Bottom);
                crop    = RectangleD.FromLTRB(
                    crop.Left - intCrop.Left,
                    crop.Top - intCrop.Top,
                    crop.Right - intCrop.Right,
                    crop.Bottom - intCrop.Bottom
                    );
            }
            if (crop.IsEmpty)
            {
                dynamic = dynamic.Invoke(resizeFunc, width, height);
            }
            else
            {
                dynamic = dynamic.Invoke(resizeFunc, width, height,
                                         src_left: crop.Left, src_top: crop.Top,
                                         src_width: -crop.Right, src_height: -crop.Bottom);
            }
            return(angle == 0 ? dynamic : dynamic.Invoke(rotateFunc, angle / 100.0));
        }