[Multimedia.Util] Modified to throw NotSupportedException for NotSupported error...
[platform/core/csapi/tizenfx.git] / src / Tizen.Multimedia.Util / ImageUtil / ImageTransform.cs
index 65cac7b..5923882 100644 (file)
@@ -15,8 +15,6 @@
  */
 
 using System;
-using System.Collections;
-using System.Collections.Generic;
 using System.Diagnostics;
 using System.Runtime.InteropServices;
 using System.Threading.Tasks;
@@ -37,9 +35,30 @@ namespace Tizen.Multimedia.Util
 
         internal async Task<MediaPacket> RunAsync(TransformHandle handle, MediaPacket source)
         {
+            Debug.Assert(source.Format is VideoMediaFormat);
+            ValidateFormat(source.Format as VideoMediaFormat);
+
             var tcs = new TaskCompletionSource<MediaPacket>();
 
-            TransformCompletedCallback cb = (nativehandle, errorCode, _) =>
+            using (var cbKeeper = ObjectKeeper.Get(GetCallback(tcs, source)))
+            {
+                var result = Run(handle, source.GetHandle(), cbKeeper.Target);
+
+                if (result == ImageUtilError.NotSupportedFormat)
+                {
+                    throw new NotSupportedException(
+                        GenerateNotSupportedErrorMessage(source.Format as VideoMediaFormat));
+                }
+                result.ThrowIfFailed("Failed to transform given packet with " + GetType());
+
+                return await tcs.Task;
+            }
+        }
+
+        private TransformCompletedCallback GetCallback(TaskCompletionSource<MediaPacket> tcs,
+            MediaPacket source)
+        {
+            return (nativehandle, errorCode, _) =>
             {
                 if (errorCode == ImageUtilError.None)
                 {
@@ -52,18 +71,16 @@ namespace Tizen.Multimedia.Util
                         tcs.TrySetException(e);
                     }
                 }
+                else if (errorCode == ImageUtilError.NotSupportedFormat)
+                {
+                    tcs.TrySetException(new NotSupportedException(
+                        GenerateNotSupportedErrorMessage(source.Format as VideoMediaFormat)));
+                }
                 else
                 {
                     tcs.TrySetException(errorCode.ToException("Image transformation failed"));
                 }
             };
-
-            using (var cbKeeper = ObjectKeeper.Get(cb))
-            {
-                Run(handle, source.GetHandle(), cb).ThrowIfFailed("Failed to transform given packet with " + GetType());
-
-                return await tcs.Task;
-            }
         }
 
         internal static TransformHandle CreateHandle()
@@ -73,557 +90,22 @@ namespace Tizen.Multimedia.Util
             return handle;
         }
 
-        internal abstract void Configure(TransformHandle handle);
-
-        internal virtual async Task<MediaPacket> ApplyAsync(MediaPacket source)
-        {
-            using (TransformHandle handle = CreateHandle())
-            {
-                Configure(handle);
-
-                return await RunAsync(handle, source);
-            }
-        }
-    }
-
-    /// <summary>
-    /// Represents a collection of <see cref="ImageTransform"/> objects that can be individually accessed by index.
-    /// </summary>
-    /// <since_tizen> 4 </since_tizen>
-    public class ImageTransformCollection : IEnumerable<ImageTransform>, IList<ImageTransform>
-    {
-        private List<ImageTransform> _list = new List<ImageTransform>();
-
-        /// <summary>
-        /// Initializes a new instance of the ImageTransformCollection class.
-        /// </summary>
-        /// <since_tizen> 4 </since_tizen>
-        public ImageTransformCollection()
-        {
-        }
-
-        /// <summary>
-        /// Gets or sets the <see cref="ImageTransform"/> at the specified index.
-        /// </summary>
-        /// <param name="index">The zero-based index of the <see cref="ImageTransform"/> to get or set.</param>
-        /// <value>The <see cref="ImageTransform"/> at the specified index.</value>
-        /// <exception cref="ArgumentOutOfRangeException">
-        ///     index is less than 0.<br/>
-        ///     -or-<br/>
-        ///     index is equal to or greater than <see cref="Count"/>.
-        /// </exception>
-        /// <since_tizen> 4 </since_tizen>
-        public ImageTransform this[int index]
-        {
-            get { return _list[index]; }
-            set { _list[index] = value; }
-        }
-
-        /// <summary>
-        /// Gets the number of items contained in the TransformCollection.
-        /// </summary>
-        /// <since_tizen> 4 </since_tizen>
-        public int Count => _list.Count;
-
-        bool ICollection<ImageTransform>.IsReadOnly => false;
-
-        /// <summary>
-        /// Adds a <see cref="ImageTransform"/> to the end of the collection.
-        /// </summary>
-        /// <param name="item">The <see cref="ImageTransform"/> to add.</param>
-        /// <remarks>
-        /// <see cref="ImageTransformCollection"/> accepts null as a valid value for reference types and allows duplicate elements.
-        /// </remarks>
-        /// <since_tizen> 4 </since_tizen>
-        public void Add(ImageTransform item)
-        {
-            if (item == null)
-            {
-                throw new ArgumentNullException(nameof(item));
-            }
-            _list.Add(item);
-        }
-
-        /// <summary>
-        /// Removes all items.
-        /// </summary>
-        /// <since_tizen> 4 </since_tizen>
-        public void Clear() => _list.Clear();
-
-        /// <summary>
-        /// Determines whether the <see cref="ImageTransformCollection"/> contains the specified item.
-        /// </summary>
-        /// <param name="item">The <see cref="ImageTransform"/> to locate in the collection.</param>
-        /// <returns>true if the <see cref="ImageTransform"/> is found in the collection; otherwise, false.</returns>
-        /// <since_tizen> 4 </since_tizen>
-        public bool Contains(ImageTransform item) => _list.Contains(item);
-
-        /// <summary>
-        /// Copies the items of the collection to an array, starting at the specified array index.
-        /// </summary>
-        /// <param name="array">The one-dimensional array that is the destination of the items copied from the collection.</param>
-        /// <param name="arrayIndex">The zero-based index in array at which copying begins.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="array"/> is null.</exception>
-        /// <exception cref="ArgumentOutOfRangeException"><paramref name="arrayIndex"/> is less than 0.</exception>
-        /// <exception cref="ArgumentException">
-        /// The number of elements in the source collection is greater than the available space from arrayIndex to the end of the destination array.
-        /// </exception>
-        /// <since_tizen> 4 </since_tizen>
-        public void CopyTo(ImageTransform[] array, int arrayIndex) => _list.CopyTo(array, arrayIndex);
-
-        /// <summary>
-        /// Determines the index of the specified item in the collection.
-        /// </summary>
-        /// <param name="item">The <see cref="ImageTransform"/> to locate in the collection.</param>
-        /// <returns>The index of value if found in the <see cref="ImageTransformCollection"/>; otherwise, -1.</returns>
-        /// <since_tizen> 4 </since_tizen>
-        public int IndexOf(ImageTransform item) => _list.IndexOf(item);
-
-        /// <summary>
-        /// Inserts a <see cref="ImageTransform"/> into the collection at the specified index.
-        /// </summary>
-        /// <param name="index">The zero-based index at which <paramref name="item"/> should be inserted.</param>
-        /// <param name="item">The <see cref="ImageTransform"/> to insert into the collection.</param>
-        /// <exception cref="ArgumentNullException"><paramref name="item"/> is null.</exception>
-        /// <exception cref="ArgumentOutOfRangeException">
-        ///     index is less than 0.<br/>
-        ///     -or-<br/>
-        ///     index is greater than <see cref="Count"/>.
-        /// </exception>
-        /// <since_tizen> 4 </since_tizen>
-        public void Insert(int index, ImageTransform item)
-        {
-            if (item == null)
-            {
-                throw new ArgumentNullException(nameof(item));
-            }
-            _list.Insert(index, item);
-        }
-
-        /// <summary>
-        /// Removes the first occurrence of the specified <see cref="ImageTransform"/> from the collection.
-        /// </summary>
-        /// <param name="item">The <see cref="ImageTransform"/> to remove.</param>
-        /// <returns>true if <paramref name="item"/> was removed from the collection; otherwise, false.</returns>
-        /// <since_tizen> 4 </since_tizen>
-        public bool Remove(ImageTransform item) => _list.Remove(item);
-
-        /// <summary>
-        /// Removes the <see cref="ImageTransform"/> at the specified index.
-        /// </summary>
-        /// <param name="index">The zero-based index to remove.</param>
-        /// <exception cref="ArgumentOutOfRangeException">
-        ///     index is less than 0.<br/>
-        ///     -or-<br/>
-        ///     index is equal to or greater than <see cref="Count"/>.
-        /// </exception>
-        /// <since_tizen> 4 </since_tizen>
-        public void RemoveAt(int index) => _list.RemoveAt(index);
-
-        /// <summary>
-        /// Returns an enumerator that can iterate through the collection.
-        /// </summary>
-        /// <returns>An enumerator that can be used to iterate through the collection.</returns>
-        /// <since_tizen> 4 </since_tizen>
-        public IEnumerator<ImageTransform> GetEnumerator() => _list.GetEnumerator();
-
-        IEnumerator IEnumerable.GetEnumerator() => _list.GetEnumerator();
-    }
-
-    // TODO need to improve performance
-    /// <summary>
-    /// Represents a <see cref="ImageTransform"/> that is a composite of the transforms.
-    /// </summary>
-    /// <since_tizen> 4 </since_tizen>
-    public class ImageTransformGroup : ImageTransform
-    {
-        /// <summary>
-        /// Gets or sets the <see cref="ImageTransformCollection"/>.
-        /// </summary>
-        /// <since_tizen> 4 </since_tizen>
-        public ImageTransformCollection Children { get; set; }
-
-        /// <summary>
-        /// Initializes a new instance of the ImageTransformGroup class.
-        /// </summary>
-        /// <since_tizen> 4 </since_tizen>
-        public ImageTransformGroup()
-        {
-            Children = new ImageTransformCollection();
-        }
-
-        internal override void Configure(TransformHandle handle)
-        {
-            // intended blank
-        }
-
-        internal override async Task<MediaPacket> ApplyAsync(MediaPacket source)
-        {
-            if (Children.Count == 0)
-            {
-                return source;
-            }
-
-            var items = Children;
-
-            MediaPacket curPacket = await items[0].ApplyAsync(source);
-
-            for (int i = 1; i < items.Count; ++i)
-            {
-                var oldPacket = curPacket;
-                try
-                {
-                    curPacket = await items[i].ApplyAsync(curPacket);
-                }
-                finally
-                {
-                    oldPacket.Dispose();
-                }
-            }
-
-            return curPacket;
-        }
-    }
-
-    /// <summary>
-    /// Rotates an image.
-    /// </summary>
-    /// <seealso cref="Rotation"/>
-    /// <since_tizen> 4 </since_tizen>
-    public class RotateTransform : ImageTransform
-    {
-        private Rotation _rotation;
-
-        /// <summary>
-        /// Initializes a new instance of the <see cref="RotateTransform"/> class.
-        /// </summary>
-        /// <param name="rotation">The value how to rotate an image.</param>
-        /// <exception cref="ArgumentException"><paramref name="rotation"/> is invalid.</exception>
-        /// <exception cref="ArgumentOutOfRangeException"><paramref name="rotation"/> is <see cref="Rotation.Rotate90"/>.</exception>
-        /// <since_tizen> 4 </since_tizen>
-        public RotateTransform(Rotation rotation)
-        {
-            Rotation = rotation;
-
-        }
-
-        /// <summary>
-        /// Gets or sets the value how to rotate an image.
-        /// </summary>
-        /// <exception cref="ArgumentException"><paramref name="value"/> is invalid.</exception>
-        /// <exception cref="ArgumentOutOfRangeException"><paramref name="value"/> is <see cref="Rotation.Rotate90"/>.</exception>
-        /// <since_tizen> 4 </since_tizen>
-        public Rotation Rotation
-        {
-            get { return _rotation; }
-            set
-            {
-                ValidationUtil.ValidateEnum(typeof(Rotation), value, nameof(Rotation));
-
-                if (value == Rotation.Rotate0)
-                {
-                    throw new ArgumentOutOfRangeException(nameof(value), "Rotation can't be Rotate0.");
-                }
-
-                _rotation = value;
-            }
-        }
-
-        internal override void Configure(TransformHandle handle)
-        {
-            SetRotation(handle, GetImageRotation());
-        }
-
-        private ImageRotation GetImageRotation()
-        {
-            switch (Rotation)
-            {
-                case Rotation.Rotate90: return ImageRotation.Rotate90;
-                case Rotation.Rotate180: return ImageRotation.Rotate180;
-                case Rotation.Rotate270: return ImageRotation.Rotate270;
-            }
-
-            Debug.Fail("Rotation is invalid value!");
-            return ImageRotation.Rotate0;
-        }
-    }
-
+        internal abstract string GenerateNotSupportedErrorMessage(VideoMediaFormat format);
 
-    /// <summary>
-    /// Flips an image.
-    /// </summary>
-    /// <seealso cref="Rotation"/>
-    /// <since_tizen> 4 </since_tizen>
-    public class FlipTransform : ImageTransform
-    {
-        private Flips _flip;
-
-        /// <summary>
-        /// Initializes a new instance of the <see cref="FlipTransform"/> class.
-        /// </summary>
-        /// <param name="flip">The value how to flip an image.</param>
-        /// <exception cref="ArgumentException"><paramref name="flip"/> is invalid.</exception>
-        /// <exception cref="ArgumentOutOfRangeException"><paramref name="flip"/> is <see cref="Flips.None"/>.</exception>
-        /// <since_tizen> 4 </since_tizen>
-        public FlipTransform(Flips flip)
-        {
-            Flip = flip;
-        }
-
-        /// <summary>
-        /// Gets or sets the value how to flip an image.
-        /// </summary>
-        /// <exception cref="ArgumentException"><paramref name="value"/> is invalid.</exception>
-        /// <exception cref="ArgumentOutOfRangeException"><paramref name="value"/> is <see cref="Flips.None"/>.</exception>
-        /// <since_tizen> 4 </since_tizen>
-        public Flips Flip
-        {
-            get { return _flip; }
-            set
-            {
-                ValidationUtil.ValidateFlagsEnum(value, Flips.Horizontal | Flips.Vertical, nameof(Flips));
-
-                if (value == Flips.None)
-                {
-                    throw new ArgumentOutOfRangeException(nameof(value), "Flip can't be None.");
-                }
-
-                _flip = value;
-            }
-        }
-
-        internal override void Configure(TransformHandle handle)
-        {
-            // intended blank
-        }
+        internal abstract void Configure(TransformHandle handle);
 
-        private async Task<MediaPacket> ApplyAsync(TransformHandle handle, MediaPacket source,
-            ImageRotation rotation)
+        internal virtual void ValidateFormat(VideoMediaFormat format)
         {
-            SetRotation(handle, rotation);
-            return await RunAsync(handle, source);
         }
 
-        internal override async Task<MediaPacket> ApplyAsync(MediaPacket source)
+        internal virtual async Task<MediaPacket> ApplyAsync(MediaPacket source)
         {
             using (TransformHandle handle = CreateHandle())
             {
-                if (Flip.HasFlag(Flips.Vertical | Flips.Horizontal))
-                {
-                    var flipped = await ApplyAsync(handle, source, ImageRotation.FlipHorizontal);
-                    try
-                    {
-                        return await ApplyAsync(handle, flipped, ImageRotation.FlipVertical);
-                    }
-                    finally
-                    {
-                        flipped.Dispose();
-                    }
-                }
-
-                return await ApplyAsync(handle, source, Flip.HasFlag(Flips.Horizontal) ?
-                    ImageRotation.FlipHorizontal : ImageRotation.FlipVertical);
-            }
-        }
-    }
-
-    /// <summary>
-    /// Changes the colorspace of an image.
-    /// </summary>
-    /// <seealso cref="ColorSpace"/>
-    /// <since_tizen> 4 </since_tizen>
-    public class ColorSpaceTransform : ImageTransform
-    {
-        private ImageColorSpace _imageColorSpace;
-
-        /// <summary>
-        /// Initializes a new instance of the <see cref="ColorSpaceTransform"/> class.
-        /// </summary>
-        /// <param name="colorSpace">The colorspace of output image.</param>
-        /// <exception cref="ArgumentException"><paramref name="colorSpace"/> is invalid.</exception>
-        /// <exception cref="NotSupportedException"><paramref name="colorSpace"/> is not supported.</exception>
-        /// <seealso cref="SupportedColorSpaces"/>
-        /// <since_tizen> 4 </since_tizen>
-        public ColorSpaceTransform(ColorSpace colorSpace)
-        {
-            ColorSpace = colorSpace;
-        }
-
-        /// <summary>
-        /// Gets or sets the colorspace of the result image.
-        /// </summary>
-        /// <exception cref="ArgumentException"><paramref name="value"/> is invalid.</exception>
-        /// <exception cref="NotSupportedException"><paramref name="value"/> is not supported.</exception>
-        /// <seealso cref="SupportedColorSpaces"/>
-        /// <since_tizen> 4 </since_tizen>
-        public ColorSpace ColorSpace
-        {
-            get { return _imageColorSpace.ToCommonColorSpace(); }
-            set
-            {
-                ValidationUtil.ValidateEnum(typeof(ColorSpace), value, nameof(ColorSpace));
-
-                _imageColorSpace = value.ToImageColorSpace();
-            }
-        }
-
-        internal override void Configure(TransformHandle handle)
-        {
-            SetColorspace(handle, _imageColorSpace);
-        }
-
-        /// <summary>
-        /// Gets the supported colorspaces for <see cref="ColorSpaceTransform"/>.
-        /// </summary>
-        /// <since_tizen> 4 </since_tizen>
-        public static IEnumerable<ColorSpace> SupportedColorSpaces
-        {
-            get
-            {
-                foreach (ImageColorSpace value in Enum.GetValues(typeof(ImageColorSpace)))
-                {
-                    yield return value.ToCommonColorSpace();
-                }
-            }
-        }
-    }
-
-    /// <summary>
-    /// Crops an image.
-    /// </summary>
-    /// <since_tizen> 4 </since_tizen>
-    public class CropTransform : ImageTransform
-    {
-        private Rectangle _region;
-
-        /// <summary>
-        /// Initializes a new instance of the <see cref="CropTransform"/> class.
-        /// </summary>
-        /// <param name="region">The crop region.</param>
-        /// <exception cref="ArgumentOutOfRangeException">
-        ///     The X-position of <paramref name="region"/> is less than zero.<br/>
-        ///     -or-<br/>
-        ///     The Y-position of <paramref name="region"/> is less than zero.<br/>
-        ///     -or-<br/>
-        ///     The width of <paramref name="region"/> is less than or equal to zero.<br/>
-        ///     -or-<br/>
-        ///     The height of <paramref name="region"/> is less than or equal to zero.
-        /// </exception>
-        /// <since_tizen> 4 </since_tizen>
-        public CropTransform(Rectangle region)
-        {
-            Region = region;
-        }
-
-        /// <summary>
-        /// Gets or sets the crop region.
-        /// </summary>
-        /// <exception cref="ArgumentOutOfRangeException">
-        ///     The X-position of <paramref name="value"/> is less than zero.<br/>
-        ///     -or-<br/>
-        ///     The Y-position of <paramref name="value"/> is less than zero.<br/>
-        ///     -or-<br/>
-        ///     The width of <paramref name="value"/> is less than or equal to zero.<br/>
-        ///     -or-<br/>
-        ///     The height of <paramref name="value"/> is less than or equal to zero.
-        /// </exception>
-        /// <since_tizen> 4 </since_tizen>
-        public Rectangle Region
-        {
-            get { return _region; }
-            set
-            {
-
-                if (value.X < 0)
-                {
-                    throw new ArgumentOutOfRangeException(nameof(Region), value,
-                        "X position of the region can't be less than zero.");
-                }
-
-                if (value.Y < 0)
-                {
-                    throw new ArgumentOutOfRangeException(nameof(Region), value,
-                        "Y position of the region can't be less than zero.");
-                }
-
-                if (value.Width <= 0)
-                {
-                    throw new ArgumentOutOfRangeException(nameof(Region), value,
-                        "Width of the region can't be less than or equal zero.");
-                }
-
-                if (value.Height < 0)
-                {
-                    throw new ArgumentOutOfRangeException(nameof(Region), value,
-                        "Height of the region can't be less than or equal to zero.");
-                }
-
-                _region = value;
-            }
-        }
-
-        internal override void Configure(TransformHandle handle)
-        {
-            SetCropArea(handle, Region.Left, Region.Top, Region.Right, Region.Bottom);
-        }
-    }
-
-    /// <summary>
-    /// Resizes an image.
-    /// </summary>
-    /// <since_tizen> 4 </since_tizen>
-    public class ResizeTransform : ImageTransform
-    {
-        private Size _size;
-
-        /// <summary>
-        /// Initializes a new instance of the <see cref="ResizeTransform"/> class.
-        /// </summary>
-        /// <param name="size">The size that an image is resized to.</param>
-        /// <exception cref="ArgumentOutOfRangeException">
-        ///     The width of <paramref name="size"/> is less than or equal to zero.<br/>
-        ///     -or-<br/>
-        ///     The height of <paramref name="size"/> is less than or equal to zero.
-        /// </exception>
-        /// <since_tizen> 4 </since_tizen>
-        public ResizeTransform(Size size)
-        {
-            Size = size;
-        }
-
-        /// <summary>
-        /// Gets or sets the size that an image is resized to.
-        /// </summary>
-        /// <exception cref="ArgumentOutOfRangeException">
-        ///     The width of <paramref name="value"/> is less than or equal to zero.<br/>
-        ///     -or-<br/>
-        ///     The height of <paramref name="value"/> is less than or equal to zero.
-        /// </exception>
-        /// <since_tizen> 4 </since_tizen>
-        public Size Size
-        {
-            get { return _size; }
-            set
-            {
-                if (value.Width <= 0)
-                {
-                    throw new ArgumentOutOfRangeException(nameof(Size), value,
-                        "Width of the size can't be less than or equal to zero.");
-                }
-
-                if (value.Height <= 0)
-                {
-                    throw new ArgumentOutOfRangeException(nameof(Size), value,
-                        "Height of the size can't be less than or equal to zero.");
-                }
+                Configure(handle);
 
-                _size = value;
+                return await RunAsync(handle, source);
             }
         }
-
-        internal override void Configure(TransformHandle handle)
-        {
-            SetResolution(handle, (uint)Size.Width, (uint)Size.Height);
-        }
     }
 }