ImageUtil with new interfaces.
authorcoderhyme <jhyo.kim@samsung.com>
Tue, 11 Apr 2017 09:14:54 +0000 (18:14 +0900)
committerhj kim <backto.kim@samsung.com>
Wed, 31 May 2017 05:31:25 +0000 (05:31 +0000)
The ImageUtil has been refactored.

Change-Id: If9c6909af25f0aa02b3a375e40cbd408aed7045f
Signed-off-by: coderhyme <jhyo.kim@samsung.com>
30 files changed:
packaging/csapi-multimedia.spec
src/Tizen.Multimedia.Util/ImageUtil/BitmapFrame.cs [new file with mode: 0644]
src/Tizen.Multimedia.Util/ImageUtil/GifFrame.cs [new file with mode: 0644]
src/Tizen.Multimedia.Util/ImageUtil/ImageColorSpace.cs [new file with mode: 0644]
src/Tizen.Multimedia.Util/ImageUtil/ImageDecoder.cs [new file with mode: 0644]
src/Tizen.Multimedia.Util/ImageUtil/ImageEncoder.cs [new file with mode: 0644]
src/Tizen.Multimedia.Util/ImageUtil/ImageFormat.cs [moved from src/Tizen.Multimedia.Util/Utility/JpegDownscale.cs with 65% similarity]
src/Tizen.Multimedia.Util/ImageUtil/ImageRotation.cs [moved from src/Tizen.Multimedia.Util/Utility/ImageRotation.cs with 61% similarity]
src/Tizen.Multimedia.Util/ImageUtil/ImageTransform.cs [new file with mode: 0644]
src/Tizen.Multimedia.Util/ImageUtil/ImageTransformer.cs [new file with mode: 0644]
src/Tizen.Multimedia.Util/ImageUtil/ImageUtil.cs [new file with mode: 0644]
src/Tizen.Multimedia.Util/ImageUtil/ImageUtilError.cs [new file with mode: 0644]
src/Tizen.Multimedia.Util/ImageUtil/JpegDownscale.cs [moved from src/Tizen.Multimedia.Util/Utility/ImageFormat.cs with 70% similarity]
src/Tizen.Multimedia.Util/ImageUtil/PngCompression.cs [moved from src/Tizen.Multimedia.Util/Utility/PngCompressionLevel.cs with 54% similarity]
src/Tizen.Multimedia.Util/Interop/Interop.ErrorCode.cs [deleted file]
src/Tizen.Multimedia.Util/Interop/Interop.ImageUtil.Decode.cs
src/Tizen.Multimedia.Util/Interop/Interop.ImageUtil.Encode.cs
src/Tizen.Multimedia.Util/Interop/Interop.ImageUtil.Transform.cs
src/Tizen.Multimedia.Util/Interop/Interop.ImageUtil.cs
src/Tizen.Multimedia.Util/Interop/Interop.SafeMultimediaHandle.cs [deleted file]
src/Tizen.Multimedia.Util/Utility/ImageColorSpace.cs [deleted file]
src/Tizen.Multimedia.Util/Utility/ImageData.cs [deleted file]
src/Tizen.Multimedia.Util/Utility/ImageDecoder.cs [deleted file]
src/Tizen.Multimedia.Util/Utility/ImageEncoder.cs [deleted file]
src/Tizen.Multimedia.Util/Utility/ImageTransformer.cs [deleted file]
src/Tizen.Multimedia.Util/Utility/ImageUtility.cs [deleted file]
src/Tizen.Multimedia/Common.Internal/FileUtil.cs [new file with mode: 0644]
src/Tizen.Multimedia/Common/ColorSpace.cs [new file with mode: 0644]
src/Tizen.Multimedia/Common/Rectangle.cs
src/Tizen.Multimedia/Interop/Interop.Libc.cs

index 365ee46..5d51eda 100755 (executable)
@@ -1,6 +1,6 @@
 Name:       csapi-multimedia
 Summary:    Tizen Multimedia API for C#
-Version:    1.1.0
+Version:    1.1.1
 Release:    0
 Group:      Development/Libraries
 License:    Apache-2.0
@@ -30,7 +30,7 @@ BuildRequires: csapi-information-nuget
        Tizen.Multimedia.Recorder 1.0.0 \
        Tizen.Multimedia.StreamRecorder 1.0.0 \
        Tizen.Multimedia.Remoting 1.0.0 \
-       Tizen.Multimedia.Util 1.0.0 \
+       Tizen.Multimedia.Util 1.0.1 \
        Tizen.Multimedia.Vision 1.0.0
 
 %description
diff --git a/src/Tizen.Multimedia.Util/ImageUtil/BitmapFrame.cs b/src/Tizen.Multimedia.Util/ImageUtil/BitmapFrame.cs
new file mode 100644 (file)
index 0000000..751531b
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Multimedia.Util
+{
+    /// <summary>
+    /// Represents image data returned by a decoder class.
+    /// </summary>
+    public class BitmapFrame
+    {
+        internal BitmapFrame(IntPtr nativeBuffer, int width, int height, int size)
+        {
+            Debug.Assert(nativeBuffer != IntPtr.Zero);
+            
+            byte[] buf = new byte[size];
+            Marshal.Copy(nativeBuffer, buf, 0, size);
+
+            Buffer = buf;
+
+            Size = new Size(width, height);
+        }
+
+        /// <summary>
+        /// Gets the raw image data.
+        /// </summary>
+        public byte[] Buffer { get; }
+
+        /// <summary>
+        /// Gets the size of the image.
+        /// </summary>
+        public Size Size { get; }
+    }
+}
diff --git a/src/Tizen.Multimedia.Util/ImageUtil/GifFrame.cs b/src/Tizen.Multimedia.Util/ImageUtil/GifFrame.cs
new file mode 100644 (file)
index 0000000..48a8896
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+
+namespace Tizen.Multimedia.Util
+{
+    /// <summary>
+    /// Represent gif image data used to encode a gif image with <see cref="GifEncoder"/>.
+    /// </summary>
+    public class GifFrame
+    {
+
+        /// <summary>
+        /// Initialize a new instance of the <see cref="GifFrame"/> class with a buffer and a delay.
+        /// </summary>
+        /// <param name="buffer">The raw image buffer to be encoded.</param>
+        /// <param name="delay">The delay for this image, in 0.001 sec units.</param>
+        /// <exception cref="ArgumentNullException"><paramref name="buffer"/> is null.</exception>
+        /// <exception cref="ArgumentException">The length of <paramref name="buffer"/> is zero.</exception>
+        public GifFrame(byte[] buffer, uint delay)
+        {
+            if (buffer == null)
+            {
+                throw new ArgumentNullException(nameof(buffer));
+            }
+
+            if (buffer.Length == 0)
+            {
+                throw new ArgumentException("buffer has no element.", nameof(buffer));
+            }
+
+            Buffer = buffer;
+            Delay = delay;
+        }
+
+        /// <summary>
+        /// Gets the raw image data.
+        /// </summary>
+        public byte[] Buffer { get; }
+
+        /// <summary>
+        /// Gets or sets the delay for this image.
+        /// </summary>
+        /// <value>Time delay in 0.001 sec units.</value>
+        public uint Delay { get; set; }
+    }
+}
diff --git a/src/Tizen.Multimedia.Util/ImageUtil/ImageColorSpace.cs b/src/Tizen.Multimedia.Util/ImageUtil/ImageColorSpace.cs
new file mode 100644 (file)
index 0000000..0572e09
--- /dev/null
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Diagnostics;
+
+namespace Tizen.Multimedia.Util
+{
+    internal enum ImageColorSpace
+    {
+        /// <summary>
+        /// YV12 - YCrCb planar format
+        /// </summary>
+        YV12,
+        /// <summary>
+        /// YUV422 - planar
+        /// </summary>
+        Yuv422,
+        /// <summary>
+        /// YUV420 - planar
+        /// </summary>
+        I420,
+        /// <summary>
+        /// NV12- planar
+        /// </summary>
+        NV12,
+        /// <summary>
+        /// UYVY - packed
+        /// </summary>
+        Uyvy,
+        /// <summary>
+        /// YUYV - packed
+        /// </summary>
+        Yuyv,
+        /// <summary>
+        /// RGB565, high-byte is Blue
+        /// </summary>
+        Rgb565,
+        /// <summary>
+        /// RGB888, high-byte is Blue
+        /// </summary>
+        Rgb888,
+        /// <summary>
+        /// ARGB8888, high-byte is Blue
+        /// </summary>
+        Argb8888,
+        /// <summary>
+        /// BGRA8888, high-byte is Alpha
+        /// </summary>
+        Bgra8888,
+        /// <summary>
+        /// RGBA8888, high-byte is Alpha
+        /// </summary>
+        Rgba8888,
+        /// <summary>
+        /// BGRX8888, high-byte is X
+        /// </summary>
+        Bgrx8888,
+        /// <summary>
+        /// NV21- planar
+        /// </summary>
+        NV21,
+        /// <summary>
+        /// NV16- planar
+        /// </summary>
+        NV16,
+        /// <summary>
+        /// NV61- planar
+        /// </summary>
+        NV61,
+    }
+
+    internal static class ImageColorSpaceExtensions
+    {
+        internal static ColorSpace ToCommonColorSpace(this ImageColorSpace value)
+        {
+            Debug.Assert(Enum.IsDefined(typeof(ImageColorSpace), value));
+
+            switch (value)
+            {
+                case ImageColorSpace.YV12: return ColorSpace.YV12;
+
+                case ImageColorSpace.Uyvy: return ColorSpace.Uyvy;
+
+                case ImageColorSpace.Yuyv: return ColorSpace.Yuyv;
+
+                case ImageColorSpace.Yuv422: return ColorSpace.Yuv422;
+
+                case ImageColorSpace.I420: return ColorSpace.I420;
+
+                case ImageColorSpace.Rgb565: return ColorSpace.Rgb565;
+
+                case ImageColorSpace.Rgb888: return ColorSpace.Rgb888;
+
+                case ImageColorSpace.Argb8888: return ColorSpace.Argb8888;
+
+                case ImageColorSpace.Bgra8888: return ColorSpace.Bgra8888;
+
+                case ImageColorSpace.Rgba8888: return ColorSpace.Rgba8888;
+
+                case ImageColorSpace.Bgrx8888: return ColorSpace.Bgrx8888;
+
+                case ImageColorSpace.NV12: return ColorSpace.NV12;
+
+                case ImageColorSpace.NV16: return ColorSpace.NV16;
+
+                case ImageColorSpace.NV21: return ColorSpace.NV21;
+
+                case ImageColorSpace.NV61: return ColorSpace.NV61;
+            }
+
+            Debug.Fail($"Not supported color space : {value.ToString()}!");
+            throw new NotSupportedException("Implementation does not support the specified value.");
+        }
+    }
+
+    internal static class ImageColorSpaceSupport
+    {
+        internal static ImageColorSpace ToImageColorSpace(this ColorSpace colorSpace)
+        {
+            ValidationUtil.ValidateEnum(typeof(ColorSpace), colorSpace, nameof(colorSpace));
+
+            switch (colorSpace)
+            {
+                case ColorSpace.YV12: return ImageColorSpace.YV12;
+
+                case ColorSpace.Uyvy: return ImageColorSpace.Uyvy;
+
+                case ColorSpace.Yuyv: return ImageColorSpace.Yuyv;
+
+                case ColorSpace.Yuv422: return ImageColorSpace.Yuv422;
+
+                case ColorSpace.I420: return ImageColorSpace.I420;
+
+                case ColorSpace.Rgb565: return ImageColorSpace.Rgb565;
+
+                case ColorSpace.Rgb888: return ImageColorSpace.Rgb888;
+
+                case ColorSpace.Argb8888: return ImageColorSpace.Argb8888;
+
+                case ColorSpace.Bgra8888: return ImageColorSpace.Bgra8888;
+
+                case ColorSpace.Rgba8888: return ImageColorSpace.Rgba8888;
+
+                case ColorSpace.Bgrx8888: return ImageColorSpace.Bgrx8888;
+
+                case ColorSpace.NV12: return ImageColorSpace.NV12;
+
+                case ColorSpace.NV16: return ImageColorSpace.NV16;
+
+                case ColorSpace.NV21: return ImageColorSpace.NV21;
+
+                case ColorSpace.NV61: return ImageColorSpace.NV61;
+            }
+
+            throw new NotSupportedException($"The ColorSpace.{colorSpace.ToString()} is not supported.");
+        }
+    }
+}
diff --git a/src/Tizen.Multimedia.Util/ImageUtil/ImageDecoder.cs b/src/Tizen.Multimedia.Util/ImageUtil/ImageDecoder.cs
new file mode 100644 (file)
index 0000000..ce0b612
--- /dev/null
@@ -0,0 +1,380 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Threading.Tasks;
+using static Interop;
+using static Interop.Decode;
+
+namespace Tizen.Multimedia.Util
+{
+    /// <summary>
+    /// This is a base class for image decoders.
+    /// </summary>
+    public abstract class ImageDecoder : IDisposable
+    {
+        private ImageDecoderHandle _handle;
+
+        private ColorSpace? _colorSpace;
+
+        internal ImageDecoder(ImageFormat format)
+        {
+            Create(out _handle).ThrowIfFailed("Failed to create ImageDecoder");
+
+            Debug.Assert(_handle != null);
+
+            InputFormat = format;
+        }
+
+        /// <summary>
+        /// Gets the image format of this decoder.
+        /// </summary>
+        public ImageFormat InputFormat { get; }
+
+        private ImageDecoderHandle Handle
+        {
+            get
+            {
+                if (_handle.IsInvalid)
+                {
+                    throw new ObjectDisposedException(nameof(ImageDecoder));
+                }
+                return _handle;
+            }
+        }
+
+        /// <summary>
+        /// Sets the color-space to decode into. The default is <see cref="ColorSpace.Rgba8888"/>.
+        /// </summary>
+        /// <exception cref="ArgumentException"><paramref name="colorSpace"/> is invalid.</exception>
+        /// <exception cref="NotSupportedException"><paramref name="colorSpace"/> is not supported by the decoder.</exception>
+        /// <seealso cref="ImageUtil.GetSupportedColorspace(ImageFormat)"/>
+        public void SetColorSpace(ColorSpace colorSpace)
+        {
+            ValidationUtil.ValidateEnum(typeof(ColorSpace), colorSpace, nameof(ColorSpace));
+
+            if (ImageUtil.GetSupportedColorSpaces(InputFormat).Contains(colorSpace) == false)
+            {
+                throw new NotSupportedException($"{colorSpace.ToString()} is not supported for {InputFormat}.");
+            }
+
+            _colorSpace = colorSpace;
+        }
+
+        /// <summary>
+        /// Decodes an image from the specified file.
+        /// </summary>
+        /// <param name="inputFilePath">Input file path from which to decode.</param>
+        /// <returns>A task that represents the asynchronous decoding operation.</returns>
+        /// <remarks>
+        ///     Only Graphics Interchange Format(GIF) codec returns more than one frame.\n
+        ///     \n
+        ///     http://tizen.org/privilege/mediastorage is needed if <paramref name="inputFilePath"/> is relevant to media storage.\n
+        ///     http://tizen.org/privilege/externalstorage is needed if <paramref name="inputFilePath"/> is relevant to external storage.
+        /// </remarks>
+        /// <exception cref="ArgumentNullException"><paramref name="inputFilePath"/> is null.</exception>
+        /// <exception cref="ArgumentException">
+        ///     <paramref name="inputFilePath"/> is an empty string.\n
+        ///     - or -\n
+        ///     <paramref name="inputFilePath"/> is not a image file.\n
+        ///     - or -\n
+        ///     The format of <paramref name="inputFilePath"/> is not <see cref="InputFormat"/>.
+        /// </exception>
+        /// <exception cref="FileNotFoundException"><paramref name="inputFilePath"/> does not exists.</exception>
+        /// <exception cref="UnauthorizedAccessException">Caller does not have required permission to access the path.</exception>
+        /// <exception cref="FileFormatException">The format of <paramref name="inputFilePath"/> is not <see cref="InputFormat"/>.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="ImageDecoder"/> has already been disposed of.</exception>
+        public async Task<IEnumerable<BitmapFrame>> DecodeAsync(string inputFilePath)
+        {
+            if (inputFilePath == null)
+            {
+                throw new ArgumentNullException(nameof(inputFilePath));
+            }
+
+            if (inputFilePath.Length == 0)
+            {
+                throw new ArgumentException("path is empty.", nameof(inputFilePath));
+            }
+
+            if (CheckHeader(inputFilePath) == false)
+            {
+                throw new FileFormatException("The file has an invalid header.");
+            }
+
+            var pathPtr = Marshal.StringToHGlobalAnsi(inputFilePath);
+            try
+            {
+
+                SetInputPath(Handle, pathPtr).ThrowIfFailed("Failed to set input file path for decoding");
+                return await DecodeAsync();
+            }
+            finally
+            {
+                Marshal.FreeHGlobal(pathPtr);
+            }
+        }
+
+        /// <summary>
+        /// Decodes an image from the buffer.
+        /// </summary>
+        /// <param name="inputBuffer">The image buffer from which to decode.</param>
+        /// <returns>A task that represents the asynchronous decoding operation.</returns>
+        /// <remarks>
+        ///     Only Graphics Interchange Format(GIF) codec returns more than one frame.\n
+        /// </remarks>
+        /// <exception cref="ArgumentNullException"><paramref name="inputBuffer"/> is null.</exception>
+        /// <exception cref="ArgumentException">
+        ///     <paramref name="inputBuffer"/> is an empty array.\n
+        ///     - or -\n
+        ///     The format of <paramref name="inputBuffer"/> is not <see cref="InputFormat"/>.
+        /// </exception>
+        /// <exception cref="FileFormatException">The format of <paramref name="inputBuffer"/> is not <see cref="InputFormat"/>.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="ImageDecoder"/> has already been disposed of.</exception>
+        public Task<IEnumerable<BitmapFrame>> DecodeAsync(byte[] inputBuffer)
+        {
+            if (inputBuffer == null)
+            {
+                throw new ArgumentNullException(nameof(inputBuffer));
+            }
+
+            if (inputBuffer.Length == 0)
+            {
+                throw new ArgumentException("buffer is empty.", nameof(inputBuffer));
+            }
+
+            if (CheckHeader(inputBuffer) == false)
+            {
+                throw new FileFormatException("buffer has an invalid header.");
+            }
+
+            SetInputBuffer(Handle, inputBuffer, (ulong)inputBuffer.Length).
+                ThrowIfFailed("Failed to set input buffer for decoding");
+
+            return DecodeAsync();
+        }
+
+        private bool CheckHeader(byte[] input)
+        {
+            if (input.Length < Header.Length)
+            {
+                return false;
+            }
+
+            for (int i = 0; i < Header.Length; ++i)
+            {
+                if (input[i] != Header[i])
+                {
+                    return false;
+                }
+            }
+
+            return true;
+        }
+
+        private bool CheckHeader(string inputFile)
+        {
+            using (var fs = File.OpenRead(inputFile))
+            {
+                byte[] fileHeader = new byte[Header.Length];
+
+                if (fs.Read(fileHeader, 0, fileHeader.Length) < Header.Length)
+                {
+                    return false;
+                }
+                return CheckHeader(fileHeader);
+            }
+        }
+
+        internal Task<IEnumerable<BitmapFrame>> DecodeAsync()
+        {
+            Initialize(Handle);
+
+            IntPtr outBuffer = IntPtr.Zero;
+            SetOutputBuffer(Handle, out outBuffer).ThrowIfFailed("Failed to decode given image");
+
+            var tcs = new TaskCompletionSource<IEnumerable<BitmapFrame>>();
+
+            Task.Run(() =>
+            {
+                try
+                {
+                    int width, height;
+                    ulong size;
+
+                    DecodeRun(Handle, out width, out height, out size).ThrowIfFailed("Failed to decode");
+
+                    tcs.SetResult(new[] { new BitmapFrame(outBuffer, width, height, (int)size) });
+                }
+                catch (Exception e)
+                {
+                    tcs.TrySetException(e);
+                }
+                finally
+                {
+                    LibcSupport.Free(outBuffer);
+                }
+            });
+
+            return tcs.Task;
+        }
+
+        internal virtual void Initialize(ImageDecoderHandle handle)
+        {
+            if (_colorSpace.HasValue)
+            {
+                SetColorspace(Handle, _colorSpace.Value.ToImageColorSpace()).ThrowIfFailed("Failed to set color space");
+            }
+        }
+
+        internal abstract byte[] Header { get; }
+
+        #region IDisposable Support
+        private bool _disposed = false;
+
+        protected virtual void Dispose(bool disposing)
+        {
+            if (!_disposed)
+            {
+                if (_handle != null)
+                {
+                    _handle.Dispose();
+                }
+                _disposed = true;
+            }
+        }
+
+        ~ImageDecoder()
+        {
+            Dispose(false);
+        }
+
+        public void Dispose()
+        {
+            Dispose(true);
+            GC.SuppressFinalize(this);
+        }
+        #endregion
+    }
+
+    /// <summary>
+    /// Provides the ability to decode Bitmap (BMP) encoded images.
+    /// </summary>
+    public class BmpDecoder : ImageDecoder
+    {
+        private static readonly byte[] _header = { (byte)'B', (byte)'M' };
+
+        /// <summary>
+        /// Initialize a new instance of the <see cref="BmpDecoder"/> class.
+        /// </summary>
+        /// <remarks><see cref="ImageDecoder.InputFormat"/> will be the <see cref="ImageFormat.Bmp"/>.</remarks>
+        public BmpDecoder() : base(ImageFormat.Bmp)
+        {
+        }
+
+        internal override byte[] Header => _header;
+    }
+
+    /// <summary>
+    /// Provides the ability to decode Portable Network Graphics (PNG) encoded images.
+    /// </summary>
+    public class PngDecoder : ImageDecoder
+    {
+        private static readonly byte[] _header = { 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a };
+
+        /// <summary>
+        /// Initialize a new instance of the <see cref="PngDecoder"/> class.
+        /// </summary>
+        /// <remarks><see cref="ImageDecoder.InputFormat"/> will be the <see cref="ImageFormat.Png"/>.</remarks>
+        public PngDecoder() : base(ImageFormat.Png)
+        {
+        }
+
+        internal override byte[] Header => _header;
+    }
+
+    /// <summary>
+    /// Provides the ability to decode Joint Photographic Experts Group (JPEG) encoded images.
+    /// </summary>
+    public class JpegDecoder : ImageDecoder
+    {
+        private static readonly byte[] _header = { 0xFF, 0xD8 };
+
+        /// <summary>
+        /// A read-only field that represents the default value of <see cref="Downscale"/>.
+        /// </summary>
+        public static readonly JpegDownscale DefaultJpegDownscale = JpegDownscale.None;
+
+        private JpegDownscale _jpegDownscale = DefaultJpegDownscale;
+
+        /// <summary>
+        /// Initialize a new instance of the <see cref="JpegDecoder"/> class.
+        /// </summary>
+        /// <remarks><see cref="ImageDecoder.InputFormat"/> will be the <see cref="ImageFormat.Jpeg"/>.</remarks>
+        public JpegDecoder() : base(ImageFormat.Jpeg)
+        {
+        }
+
+        /// <summary>
+        /// Gets or sets the downscale at which the jpeg image should be decoded.
+        /// </summary>
+        /// <exception cref="ArgumentException"><paramref name="value"/> is invalid.</exception>
+        public JpegDownscale Downscale
+        {
+            get
+            {
+                return _jpegDownscale;
+            }
+            set
+            {
+                ValidationUtil.ValidateEnum(typeof(JpegDownscale), value, nameof(Downscale));
+
+                _jpegDownscale = value;
+            }
+        }
+
+        internal override void Initialize(ImageDecoderHandle handle)
+        {
+            base.Initialize(handle);
+
+            SetJpegDownscale(handle, Downscale).ThrowIfFailed("Failed to set downscale for decoding");
+        }
+
+        internal override byte[] Header => _header;
+    }
+
+    /// <summary>
+    /// Provides the ability to decode Graphics Interchange Format (GIF) encoded images.
+    /// </summary>
+    public class GifDecoder : ImageDecoder
+    {
+        private static readonly byte[] _header = { (byte)'G', (byte)'I', (byte)'F' };
+
+        /// <summary>
+        /// Initialize a new instance of the <see cref="GifDecoder"/> class.
+        /// </summary>
+        /// <remarks><see cref="ImageDecoder.InputFormat"/> will be the <see cref="ImageFormat.Gif"/>.</remarks>
+        public GifDecoder() : base(ImageFormat.Gif)
+        {
+        }
+
+        internal override byte[] Header => _header;
+    }
+}
diff --git a/src/Tizen.Multimedia.Util/ImageUtil/ImageEncoder.cs b/src/Tizen.Multimedia.Util/ImageUtil/ImageEncoder.cs
new file mode 100644 (file)
index 0000000..03534a2
--- /dev/null
@@ -0,0 +1,451 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Threading.Tasks;
+using static Interop.ImageUtil;
+using Unmanaged = Interop.ImageUtil.Encode;
+
+namespace Tizen.Multimedia.Util
+{
+    /// <summary>
+    /// This is a base class for image encoders.
+    /// </summary>
+    public abstract class ImageEncoder : IDisposable
+    {
+        private ImageEncoderHandle _handle;
+
+        private bool _hasResolution;
+
+        internal ImageEncoder(ImageFormat format)
+        {
+            Unmanaged.Create(format, out _handle).ThrowIfFailed("Failed to create ImageEncoder");
+
+            Debug.Assert(_handle != null);
+
+            OutputFormat = format;
+        }
+
+        private ImageEncoderHandle Handle
+        {
+            get
+            {
+                if (_disposed)
+                {
+                    throw new ObjectDisposedException(GetType().Name);
+                }
+
+                return _handle;
+            }
+        }
+
+        /// <summary>
+        /// Gets the image format of this encoder.
+        /// </summary>
+        public ImageFormat OutputFormat { get; }
+
+        /// <summary>
+        /// Sets the resolution of the output image.
+        /// </summary>
+        /// <param name="resolution">The target resolution.</param>
+        /// <exception cref="ArgumentOutOfRangeException">
+        ///     The width of <paramref name="resolution"/> is less than or equal to zero.\n
+        ///     - or -\n
+        ///     The height of <paramref name="resolution"/> is less than or equal to zero.
+        /// </exception>
+        public void SetResolution(Size resolution)
+        {
+            if (resolution.Width <= 0)
+            {
+                throw new ArgumentOutOfRangeException(nameof(resolution), resolution.Width,
+                    "The width of resolution can't be less than or equal to zero.");
+            }
+            if (resolution.Height <= 0)
+            {
+                throw new ArgumentOutOfRangeException(nameof(resolution), resolution.Height,
+                    "The height of resolution can't be less than or equal to zero.");
+            }
+
+            Unmanaged.SetResolution(Handle, (uint)resolution.Width, (uint)resolution.Height).
+                ThrowIfFailed("Failed to set the resolution");
+
+            _hasResolution = true;
+        }
+
+        /// <summary>
+        /// Sets the colorspace of the output image.
+        /// </summary>
+        /// <param name="colorSpace">The target colorspace.</param>
+        /// <exception cref="ArgumentException"><paramref name="colorSpace"/> is invalid.</exception>
+        /// <exception cref="NotSupportedException"><paramref name="colorSpace"/> is not supported by the encoder.</exception>
+        /// <seealso cref="ImageUtil.GetSupportedColorspace(ImageFormat)"/>
+        public void SetColorSpace(ColorSpace colorSpace)
+        {
+            ValidationUtil.ValidateEnum(typeof(ColorSpace), colorSpace, nameof(colorSpace));
+
+            if (ImageUtil.GetSupportedColorSpaces(OutputFormat).Contains(colorSpace) == false)
+            {
+                throw new NotSupportedException($"{colorSpace.ToString()} is not supported for {OutputFormat}.");
+            }
+
+            Unmanaged.SetColorspace(Handle, colorSpace.ToImageColorSpace()).
+                ThrowIfFailed("Failed to set the color space");
+        }
+
+        private Task Run(Stream outStream)
+        {
+            var tcs = new TaskCompletionSource<bool>();
+
+            IntPtr outBuffer = IntPtr.Zero;
+            Unmanaged.SetOutputBuffer(Handle, out outBuffer).ThrowIfFailed("Failed to initialize encoder");
+
+            Task.Run(() =>
+            {
+                try
+                {
+                    ulong size = 0;
+                    Unmanaged.Run(Handle, out size).ThrowIfFailed("Failed to encode given image");
+
+                    byte[] buf = new byte[size];
+                    Marshal.Copy(outBuffer, buf, 0, (int)size);
+                    outStream.Write(buf, 0, (int)size);
+
+                    tcs.TrySetResult(true);
+                }
+                catch (Exception e)
+                {
+                    tcs.TrySetException(e);
+                }
+                finally
+                {
+                    Interop.Libc.Free(outBuffer);
+                }
+            });
+
+            return tcs.Task;
+        }
+
+        internal Task EncodeAsync(Action<ImageEncoderHandle> settingInputAction, Stream outStream)
+        {
+            Debug.Assert(settingInputAction != null);
+
+            if (outStream == null)
+            {
+                throw new ArgumentNullException(nameof(outStream));
+            }
+
+            if (outStream.CanWrite == false)
+            {
+                throw new ArgumentException("The stream is not writable.", nameof(outStream));
+            }
+
+            Initialize();
+
+            settingInputAction(Handle);
+
+            return Run(outStream);
+        }
+
+        /// <summary>
+        /// Encodes an image from a raw image buffer to a specified <see cref="Stream"/>.
+        /// </summary>
+        /// <param name="inputBuffer">The image buffer to encode.</param>
+        /// <param name="outStream">The stream that the image is encoded to.</param>
+        /// <returns>A task that represents the asynchronous encoding operation.</returns>
+        /// <exception cref="ArgumentNullException">
+        ///     <paramref name="inputBuffer"/> is null.\n
+        ///     - or -\n
+        ///     <paramref name="outStream"/> is null.
+        /// </exception>
+        /// <exception cref="ArgumentException">
+        ///     <paramref name="inputBuffer"/> is an empty array.\n
+        ///     - or -\n
+        ///     <paramref name="outStream"/> is not writable.\n
+        /// </exception>
+        /// <exception cref="InvalidOperationException">The resolution is not set.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="ImageEncoder"/> has already been disposed of.</exception>
+        /// <seealso cref="SetResolution(Size)"/>
+        public Task EncodeAsync(byte[] inputBuffer, Stream outStream)
+        {
+            if (inputBuffer == null)
+            {
+                throw new ArgumentNullException(nameof(inputBuffer));
+            }
+
+            if (inputBuffer.Length == 0)
+            {
+                throw new ArgumentException("buffer is empty.", nameof(inputBuffer));
+            }
+
+            return EncodeAsync(handle =>
+            {
+                Unmanaged.SetInputBuffer(handle, inputBuffer).
+                        ThrowIfFailed("Failed to configure encoder; InputBuffer");
+            }, outStream);
+        }
+
+        internal void Initialize()
+        {
+            Configure(Handle);
+
+            if (_hasResolution == false)
+            {
+                throw new InvalidOperationException("Resolution is not set.");
+            }
+        }
+
+        internal abstract void Configure(ImageEncoderHandle handle);
+
+        #region IDisposable Support
+        private bool _disposed = false;
+
+        protected virtual void Dispose(bool disposing)
+        {
+            if (!_disposed)
+            {
+                if (_handle != null)
+                {
+                    _handle.Dispose();
+                }
+                _disposed = true;
+            }
+        }
+
+        public void Dispose()
+        {
+            Dispose(true);
+        }
+        #endregion
+    }
+
+    /// <summary>
+    /// Provides the ability to encode Bitmap (BMP) format images.
+    /// </summary>
+    public class BmpEncoder : ImageEncoder
+    {
+        /// <summary>
+        /// Initialize a new instance of the <see cref="BmpEncoder"/> class.
+        /// </summary>
+        /// <remarks><see cref="ImageEncoder.OutputFormat"/> will be the <see cref="ImageFormat.Bmp"/>.</remarks>
+        public BmpEncoder() : base(ImageFormat.Bmp)
+        {
+        }
+
+        internal override void Configure(ImageEncoderHandle handle)
+        {
+        }
+    }
+
+    /// <summary>
+    /// Provides the ability to encode Portable Network Graphics (PNG) format images.
+    /// </summary>
+    public class PngEncoder : ImageEncoder
+    {
+        /// <summary>
+        /// A read-only field that represents the default value of <see cref="Compression"/>.
+        /// </summary>
+        public static readonly PngCompression DefaultCompression = PngCompression.Level6;
+
+        private PngCompression? _compression;
+
+        /// <summary>
+        /// Initialize a new instance of the <see cref="PngEncoder"/> class.
+        /// </summary>
+        /// <remarks><see cref="ImageEncoder.OutputFormat"/> will be the <see cref="ImageFormat.Png"/>.</remarks>
+        public PngEncoder() :
+            base(ImageFormat.Png)
+        {
+        }
+
+        /// <summary>
+        /// Initialize a new instance of the <see cref="PngEncoder"/> class with <see cref="PngCompression"/>.
+        /// </summary>
+        /// <remarks><see cref="ImageEncoder.OutputFormat"/> will be the <see cref="ImageFormat.Png"/>.</remarks>
+        /// <param name="compression">The compression level of the encoder.</param>
+        /// <exception cref="ArgumentException"><paramref name="compression"/> is invalid.</exception>
+        public PngEncoder(PngCompression compression) :
+            base(ImageFormat.Png)
+        {
+            Compression = compression;
+        }
+
+        /// <summary>
+        /// Gets or sets the compression level of the png image.
+        /// </summary>
+        /// <value>The compression level. The default is <see cref="PngCompression.Level6"/>.</value>
+        /// <exception cref="ArgumentException"><paramref name="value"/> is invalid.</exception>
+        public PngCompression Compression
+        {
+            get { return _compression ?? DefaultCompression; }
+            set
+            {
+                ValidationUtil.ValidateEnum(typeof(PngCompression), value, nameof(Compression));
+
+                _compression = value;
+            }
+        }
+
+        internal override void Configure(ImageEncoderHandle handle)
+        {
+            if (_compression.HasValue)
+            {
+                Unmanaged.SetPngCompression(handle, _compression.Value).
+                    ThrowIfFailed("Failed to configure encoder; PngCompression");
+            }
+        }
+    }
+
+    /// <summary>
+    /// Provides the ability to encode Joint Photographic Experts Group (JPEG) format images.
+    /// </summary>
+    public class JpegEncoder : ImageEncoder
+    {
+        /// <summary>
+        /// A read-only field that represents the default value of <see cref="Quality"/>.
+        /// </summary>
+        public static readonly int DefaultQuality = 75;
+
+        private int? _quality;
+
+        /// <summary>
+        /// Initialize a new instance of the <see cref="JpegEncoder"/> class.
+        /// </summary>
+        /// <remarks><see cref="ImageEncoder.OutputFormat"/> will be the <see cref="ImageFormat.Jpeg"/>.</remarks>
+        public JpegEncoder() : base(ImageFormat.Jpeg)
+        {
+        }
+
+
+        /// <summary>
+        /// Initialize a new instance of the <see cref="JpegEncoder"/> class with initial quality value.
+        /// </summary>
+        /// <remarks><see cref="ImageEncoder.OutputFormat"/> will be the <see cref="ImageFormat.Jpeg"/>.</remarks>
+        /// <exception cref="ArgumentOutOfRangeException">
+        ///     <paramref name="quality"/> is less than 0.\n
+        ///     - or -\n
+        ///     <paramref name="quality"/> is greater than 100.
+        /// </exception>
+        public JpegEncoder(int quality) :
+            base(ImageFormat.Jpeg)
+        {
+            Quality = quality;
+        }
+
+        /// <summary>
+        /// Gets or sets the quality of the encoded image.
+        /// </summary>
+        /// <value>The quality of the output image. The default is 75.</value>
+        /// <exception cref="ArgumentOutOfRangeException">
+        ///     <paramref name="value"/> is less than 0.\n
+        ///     - or -\n
+        ///     <paramref name="value"/> is greater than 100.
+        /// </exception>
+        public int Quality
+        {
+            get { return _quality ?? DefaultQuality; }
+            set
+            {
+                if (value < 0 || value > 100)
+                {
+                    throw new ArgumentOutOfRangeException(nameof(Quality), value,
+                        "Valid range is from 1 to 100, inclusive.");
+                }
+                _quality = value;
+            }
+        }
+
+        internal override void Configure(ImageEncoderHandle handle)
+        {
+            if (_quality.HasValue)
+            {
+                Unmanaged.SetQuality(handle, _quality.Value).
+                    ThrowIfFailed("Failed to configure encoder; Quality");
+            }
+        }
+    }
+
+    /// <summary>
+    /// Provides the ability to encode Graphics Interchange Format (GIF) format images.
+    /// </summary>
+    public class GifEncoder : ImageEncoder
+    {
+        /// <summary>
+       /// Initialize a new instance of the <see cref="GifEncoder"/> class.
+       /// </summary>
+       /// <remarks><see cref="ImageEncoder.OutputFormat"/> will be the <see cref="ImageFormat.Gif"/>.</remarks>
+        public GifEncoder() : base(ImageFormat.Gif)
+        {
+        }
+
+        internal override void Configure(ImageEncoderHandle handle)
+        {
+        }
+
+        /// <summary>
+        /// Encodes a Graphics Interchange Format (GIF) image from multiple raw image buffers to a specified <see cref="Stream"/>.
+        /// </summary>
+        /// <param name="inputBuffer">The image buffer to encode.</param>
+        /// <param name="outStream">The stream that the image is encoded to.</param>
+        /// <returns>A task that represents the asynchronous encoding operation.</returns>
+        /// <exception cref="ArgumentNullException">
+        ///     <paramref name="frames"/> is null.\n
+        ///     - or -\n
+        ///     <paramref name="outStream"/> is null.
+        /// </exception>
+        /// <exception cref="ArgumentException">
+        ///     <paramref name="frames"/> has no element(empty).\n
+        ///     - or -\n
+        ///     <paramref name="outStream"/> is not writable.\n
+        /// </exception>
+        /// <exception cref="InvalidOperationException">The resolution is not set.</exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="ImageEncoder"/> has already been disposed of.</exception>
+        /// <seealso cref="SetResolution(Size)"/>
+        public Task EncodeAsync(IEnumerable<GifFrame> frames, Stream outStream)
+        {
+            if (frames == null)
+            {
+                throw new ArgumentNullException(nameof(frames));
+            }
+
+            if (frames.Count() == 0)
+            {
+                throw new ArgumentException("frames is a empty collection", nameof(frames));
+            }
+
+            return EncodeAsync(handle =>
+            {
+                foreach (GifFrame frame in frames)
+                {
+                    if (frame == null)
+                    {
+                        throw new ArgumentNullException(nameof(frames));
+                    }
+                    Unmanaged.SetInputBuffer(handle, frame.Buffer).
+                        ThrowIfFailed("Failed to configure encoder; Buffer");
+
+                    Unmanaged.SetGifFrameDelayTime(handle, (ulong)frame.Delay).
+                        ThrowIfFailed("Failed to configure encoder; Delay");
+                }
+            }, outStream);
+        }
+    }
+
+}
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-namespace Tizen.Multimedia.Utility
+
+namespace Tizen.Multimedia.Util
 {
     /// <summary>
-    /// JPEG Downscale options for decoding
+    /// Specifies image formats for <see cref="ImageDecoder"/>, <see cref="ImageEncoder"/> and <see cref="ImageUtil"/>.
     /// </summary>
-    public enum JpegDownscale
+    public enum ImageFormat
     {
         /// <summary>
-        /// No downscale
+        /// The Joint Photographic Experts Group format.
         /// </summary>
-        NoDownscale = global::Interop.JpegDownscale.NoDownscale,
+        Jpeg,
         /// <summary>
-        /// 1/2 downscale
+        /// The Portable Network Graphics format.
         /// </summary>
-        OneHalf = global::Interop.JpegDownscale.OneHalf,
+        Png,
         /// <summary>
-        /// 1/4 downscale
+        /// The Graphics Interchange Format.
         /// </summary>
-        OneFourth = global::Interop.JpegDownscale.OneFourth,
+        Gif,
         /// <summary>
-        /// 1/8 downscale
+        /// The Bitmap format.
         /// </summary>
-        OneEighth = global::Interop.JpegDownscale.OneEighth,
+        Bmp,
     }
-}
\ No newline at end of file
+}
  * limitations under the License.
  */
 
-namespace Tizen.Multimedia.Utility
+namespace Tizen.Multimedia.Util
 {
     /// <summary>
-    /// Image rotation options
+    /// Specifies how an image is rotated or flipped.
     /// </summary>
+    /// <seealso cref="RotateTransform"/>
     public enum ImageRotation
     {
         /// <summary>
-        /// No rotation
+        /// No rotation.
         /// </summary>
-        None = global::Interop.ImageRotation.None,
+        Rotate0,
         /// <summary>
-        /// Rotate 90 degree
+        /// Rotate 90 degree clockwise.
         /// </summary>
-        Rotate90 = global::Interop.ImageRotation.Rotate90,
+        Rotate90,
         /// <summary>
-        /// Rotate 180 degree
+        /// Rotate 180 degree clockwise.
         /// </summary>
-        Rotate180 = global::Interop.ImageRotation.Rotate180,
+        Rotate180,
         /// <summary>
-        /// Rotate 270 degree
+        /// Rotate 270 degree clockwise.
         /// </summary>
-        Rotate270 = global::Interop.ImageRotation.Rotate270,
+        Rotate270,
         /// <summary>
-        /// Flip horizontal
+        /// Flip horizontally.
         /// </summary>
-        FlipHorizontal = global::Interop.ImageRotation.FlipHorizontal,
+        FlipHorizontal,
         /// <summary>
-        /// Flip vertical
+        /// Flip vertically.
         /// </summary>
-        FlipVertical = global::Interop.ImageRotation.FlipVertical,
+        FlipVertical,
     }
-}
\ No newline at end of file
+}
diff --git a/src/Tizen.Multimedia.Util/ImageUtil/ImageTransform.cs b/src/Tizen.Multimedia.Util/ImageUtil/ImageTransform.cs
new file mode 100644 (file)
index 0000000..e660e9e
--- /dev/null
@@ -0,0 +1,486 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Threading.Tasks;
+using static Interop.ImageUtil;
+using static Interop.ImageUtil.Transform;
+
+namespace Tizen.Multimedia.Util
+{
+    /// <summary>
+    /// A base class for image transformations.
+    /// </summary>
+    public abstract class ImageTransform
+    {
+        internal async Task<MediaPacket> RunAsync(TransformHandle handle, MediaPacket source)
+        {
+            var tcs = new TaskCompletionSource<MediaPacket>();
+
+            TransformCompletedCallback cb = (nativehandle, errorCode, _) =>
+            {
+                if (errorCode == ImageUtilError.None)
+                {
+                    try
+                    {
+                        tcs.TrySetResult(MediaPacket.From(Marshal.PtrToStructure<IntPtr>(nativehandle)));
+                    }
+                    catch (Exception e)
+                    {
+                        tcs.TrySetException(e);
+                    }
+                }
+                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 abstract void Configure(TransformHandle handle);
+
+        internal virtual Task<MediaPacket> ApplyAsync(TransformHandle handle, MediaPacket source)
+        {
+            Configure(handle);
+
+            return RunAsync(handle, source);
+        }
+    }
+
+    /// <summary>
+    /// Represents a collection of <see cref="ImageTransform"/> objects that can be individually accessed by index.
+    /// </summary>
+    public class ImageTransformCollection : IEnumerable<ImageTransform>, IList<ImageTransform>
+    {
+        private List<ImageTransform> _list = new List<ImageTransform>();
+
+        /// <summary>
+        /// Initializes a new instance of the ImageTransformCollection class.
+        /// </summary>
+        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.\n
+        ///     - or -\n
+        ///     index is equal to or greater than Count.
+        /// </exception>
+        public ImageTransform this[int index]
+        {
+            get { return _list[index]; }
+            set { _list[index] = value; }
+        }
+
+        /// <summary>
+        /// Gets the number of items contained in the TransformCollection.
+        /// </summary>
+        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>
+        public void Add(ImageTransform item)
+        {
+            if (item == null)
+            {
+                throw new ArgumentNullException(nameof(item));
+            }
+            _list.Add(item);
+        }
+
+        /// <summary>
+        /// Removes all items.
+        /// </summary>
+        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>
+        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>
+        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>
+        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.\n
+        ///     -or-\n
+        ///     index is greater than <see cref="Count"/>.
+        /// </exception>
+        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>
+        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.\n
+        ///     - or -\n
+        ///     index is equal to or greater than <see cref="Count"/>.
+        /// </exception>
+        public void RemoveAt(int index) => _list.RemoveAt(index);
+
+        /// <summary>
+        /// Returns an enumerator that can iterate through the collection.
+        /// </summary>
+        /// <returns>A enumerator that can be used to iterate through the collection.</returns>
+        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>
+    public class ImageTransformGroup : ImageTransform
+    {
+        /// <summary>
+        /// Gets or sets the <see cref="ImageTransformCollection"/>.
+        /// </summary>
+        public ImageTransformCollection Children { get; set; }
+
+        /// <summary>
+        /// Initializes a new instance of the ImageTransformGroup class.
+        /// </summary>
+        public ImageTransformGroup()
+        {
+            Children = new ImageTransformCollection();
+        }
+
+        internal override void Configure(TransformHandle handle)
+        {
+            // intended blank
+        }
+
+        internal override async Task<MediaPacket> ApplyAsync(TransformHandle handle, MediaPacket source)
+        {
+            if (Children.Count == 0)
+            {
+                return source;
+            }
+
+            var items = Children;
+
+            MediaPacket curPacket = await items[0].ApplyAsync(handle, source);
+
+            for (int i = 1; i < items.Count; ++i)
+            {
+                var item = items[i];
+
+                var oldPacket = curPacket;
+                try
+                {
+                    curPacket = await item.ApplyAsync(handle, curPacket);
+                }
+                finally
+                {
+                    oldPacket.Dispose();
+                }
+            }
+
+            return curPacket;
+        }
+    }
+
+    /// <summary>
+    /// Rotates or flips an image.
+    /// </summary>
+    /// <seealso cref="ImageRotation"/>
+    public class RotateTransform : ImageTransform
+    {
+        private ImageRotation _rotation;
+
+        /// <summary>
+        /// Initialize 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>
+        public RotateTransform(ImageRotation rotation)
+        {
+            Rotation = rotation;
+        }
+
+        /// <summary>
+        /// Gets or sets the value how to rotate an image.
+        /// </summary>
+        /// <exception cref="ArgumentException"><paramref name="value"/> is invalid.</exception>
+        public ImageRotation Rotation
+        {
+            get { return _rotation; }
+            set
+            {
+                ValidationUtil.ValidateEnum(typeof(ImageRotation), value, nameof(Rotation));
+
+                _rotation = value;
+            }
+        }
+
+        internal override void Configure(TransformHandle handle)
+        {
+            SetRotation(handle, Rotation);
+        }
+    }
+
+    /// <summary>
+    /// Changes colorspace of image.
+    /// </summary>
+    /// <seealso cref="ColorSpace"/>
+    public class ColorSpaceTransform : ImageTransform
+    {
+        private ImageColorSpace _imageColorSpace;
+
+        /// <summary>
+        /// Initialize 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"/>
+        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"/>
+        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>
+        public static IEnumerable<ColorSpace> SupportedColorSpaces
+        {
+            get
+            {
+                foreach (ImageColorSpace value in Enum.GetValues(typeof(ImageColorSpace)))
+                {
+                    yield return value.ToCommonColorSpace();
+                }
+            }
+        }
+    }
+
+    /// <summary>
+    /// Crops an image.
+    /// </summary>
+    public class CropTransform : ImageTransform
+    {
+        private Rectangle _region;
+
+        /// <summary>
+        /// Initialize 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.\n
+        ///     - or -\n
+        ///     The Y-position of <paramref name="region"/> is less than zero.\n
+        ///     - or -\n
+        ///     The width of <paramref name="region"/> is less than or equal to zero.\n
+        ///     - or -\n
+        ///     The height of <paramref name="region"/> is less than or equal to zero.
+        /// </exception>
+        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.\n
+        ///     - or -\n
+        ///     The Y-position of <paramref name="value"/> is less than zero.\n
+        ///     - or -\n
+        ///     The width of <paramref name="value"/> is less than or equal to zero.\n
+        ///     - or -\n
+        ///     The height of <paramref name="value"/> is less than or equal to zero.
+        /// </exception>
+        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>
+    public class ResizeTransform : ImageTransform
+    {
+        private Size _size;
+
+        /// <summary>
+        /// Initialize 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.\n
+        ///     - or -\n
+        ///     The height of <paramref name="size"/> is less than or equal to zero.
+        /// </exception>
+        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.\n
+        ///     - or -\n
+        ///     The height of <paramref name="value"/> is less than or equal to zero.
+        /// </exception>
+        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.");
+                }
+
+                _size = value;
+            }
+        }
+
+        internal override void Configure(TransformHandle handle)
+        {
+            SetResolution(handle, (uint)Size.Width, (uint)Size.Height);
+        }
+    }
+}
diff --git a/src/Tizen.Multimedia.Util/ImageUtil/ImageTransformer.cs b/src/Tizen.Multimedia.Util/ImageUtil/ImageTransformer.cs
new file mode 100644 (file)
index 0000000..f90f235
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Diagnostics;
+using System.Threading.Tasks;
+using static Interop.ImageUtil;
+using static Interop.ImageUtil.Transform;
+
+namespace Tizen.Multimedia.Util
+{
+    /// <summary>
+    /// Provides the ability to transform an image.
+    /// </summary>
+    public class ImageTransformer : IDisposable
+    {
+        private TransformHandle _handle = null;
+
+        /// <summary>
+        /// Initialize a new instance of the <see cref="ImageTransformer"/> class.
+        /// </summary>
+        public ImageTransformer()
+        {
+            Create(out _handle).ThrowIfFailed("Failed to create ImageTransformer");
+
+            Debug.Assert(_handle != null);
+        }
+
+        /// <summary>
+        /// Transforms an image with <see cref="ImageTransform"/>.
+        /// </summary>
+        /// <param name="source"><see cref="MediaPacket"/> to transform. The <see cref="MediaPacket.Format"/> of this <paramref name="source"/> must be <see cref="VideoMediaFormat"/>.</param>
+        /// <param name="item"><see cref="ImageTransform"/> to apply.</param>
+        /// <returns>A task that represents the asynchronous transforming operation.</returns>
+        /// <exception cref="ArgumentNullException">
+        ///     <paramref name="source"/> is null.\n
+        ///     - or -\n
+        ///     <paramref name="item"/> is null.
+        /// </exception>
+        /// <exception cref="ObjectDisposedException">The <see cref="ImageTransformer"/> has already been disposed of.</exception>
+        /// <exception cref="InvalidOperationException">Failed to apply <see cref="ImageTransform"/>.</exception>
+        public Task<MediaPacket> TransformAsync(MediaPacket source, ImageTransform item)
+        {
+            if (_disposed)
+            {
+                throw new ObjectDisposedException(nameof(ImageTransformer));
+            }
+
+            if (source == null)
+            {
+                throw new ArgumentNullException(nameof(source));
+            }
+
+            if (item == null)
+            {
+                throw new ArgumentNullException(nameof(item));
+            }
+
+            return item.ApplyAsync(_handle, source);
+        }
+
+        #region IDisposable Support
+        private bool _disposed = false;
+
+        protected virtual void Dispose(bool disposing)
+        {
+            if (!_disposed)
+            {
+                if (_handle != null)
+                {
+                    _handle.Dispose();
+                }
+
+                _disposed = true;
+            }
+        }
+
+        public void Dispose()
+        {
+            Dispose(true);
+        }
+        #endregion
+    }
+}
diff --git a/src/Tizen.Multimedia.Util/ImageUtil/ImageUtil.cs b/src/Tizen.Multimedia.Util/ImageUtil/ImageUtil.cs
new file mode 100644 (file)
index 0000000..e2db5b2
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using Tizen.Common;
+using static Interop.ImageUtil;
+
+namespace Tizen.Multimedia.Util
+{
+    /// <summary>
+    /// Provides utilities for images.
+    /// </summary>
+    public static class ImageUtil
+    {
+        /// <summary>
+        /// Retrieves supported colorspaces for a <see cref="ImageFormat"/> that represents formats for <see cref="ImageEncoder"/> and <see cref="ImageDecoder"/>.
+        /// </summary>
+        /// <param name="format"><see cref="ImageFormat"/>.</param>
+        /// <exception cref="ArgumentException"><paramref name="format"/> is invalid.</exception>
+        public static IEnumerable<ColorSpace> GetSupportedColorSpaces(ImageFormat format)
+        {
+            ValidationUtil.ValidateEnum(typeof(ImageFormat), format, nameof(format));
+
+            var colorspaces = new List<ColorSpace>();
+
+            ForeachSupportedColorspace(format,
+                (colorspace, _) => { colorspaces.Add(colorspace.ToCommonColorSpace()); return true; }).
+                ThrowIfFailed("Failed to get supported color-space list from native handle");
+
+            return colorspaces;
+        }
+
+        /// <summary>
+        /// Calculates the size of the image buffer for the specified resolution and color-space.
+        /// </summary>
+        /// <param name="size">Resolution of the image.</param>
+        /// <param name="colorSpace"><see cref="ColorSpace"/> of the image.</param>
+        /// <returns>Buffer size.</returns>
+        /// <exception cref="ArgumentOutOfRangeException">
+        ///     width of <paramref name="resolution"/> is less than or equal to zero.\n
+        ///     - or -\n
+        ///     height of <paramref name="resolution"/> is less than or equal to zero.
+        /// </exception>
+        /// <exception cref="ArgumentException"><paramref name="colorSpace"/> is invalid.</exception>
+        public static int CalculateBufferSize(Size resolution, ColorSpace colorSpace)
+        {
+            if (resolution.Width <= 0)
+            {
+                throw new ArgumentOutOfRangeException(nameof(resolution), resolution.Width,
+                    "width can't be less than or equal to zero.");
+            }
+            if (resolution.Height <= 0)
+            {
+                throw new ArgumentOutOfRangeException(nameof(resolution), resolution.Height,
+                    "height can't be less than or equal to zero.");
+            }
+
+            ValidationUtil.ValidateEnum(typeof(ColorSpace), colorSpace, nameof(colorSpace));
+
+            uint bufferSize;
+            global::Interop.ImageUtil.CalculateBufferSize(resolution.Width, resolution.Height,
+                colorSpace.ToImageColorSpace(), out bufferSize)
+                .ThrowIfFailed("Failed to calculate buffer size for given parameter");
+
+            return (int)bufferSize;
+        }
+
+        /// <summary>
+        /// Extracts representative color from an image buffer.
+        /// </summary>
+        /// <param name="buffer">Raw image buffer.</param>
+        /// <param name="size">Resolution of the image.</param>
+        /// <remarks>The image should be <see cref="ColorSpace.Rgb888"/>.</remarks>
+        /// <returns>The representative color of the image.</returns>
+        /// <see cref="BitmapFrame"/>
+        /// <exception cref="ArgumentNullException"><paramref name="buffer"/> is null.</exception>
+        /// <exception cref="ArgumentException"><paramref name="buffer"/> is empty.</exception>
+        /// <exception cref="ArgumentOutOfRangeException">
+        ///     width of <paramref name="size"/> is less than or equal to zero.\n
+        ///     - or -\n
+        ///     height of <paramref name="size"/> is less than or equal to zero.
+        /// </exception>
+        public static Color GetColor(byte[] buffer, Size size)
+        {
+            if (buffer == null)
+            {
+                throw new ArgumentNullException(nameof(buffer));
+            }
+
+            if (buffer.Length == 0)
+            {
+                throw new ArgumentException("buffer is empty.", nameof(buffer));
+            }
+
+            if (size.Width <= 0)
+            {
+                throw new ArgumentOutOfRangeException(nameof(size), size.Width,
+                    "width can't be less than or equal to zero.");
+            }
+            if (size.Height <= 0)
+            {
+                throw new ArgumentOutOfRangeException(nameof(size), size.Height,
+                    "height can't be less than or equal to zero.");
+            }
+
+
+            byte r, g, b;
+            ExtractColorFromMemory(buffer, size.Width, size.Height, out r, out g, out b)
+                .ThrowIfFailed("Failed to extract color from buffer");
+
+            return Color.FromRgb(r, g, b);
+        }
+    }
+}
diff --git a/src/Tizen.Multimedia.Util/ImageUtil/ImageUtilError.cs b/src/Tizen.Multimedia.Util/ImageUtil/ImageUtilError.cs
new file mode 100644 (file)
index 0000000..5cba546
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Diagnostics;
+using System.IO;
+using Tizen.Internals.Errors;
+
+namespace Tizen.Multimedia.Util
+{
+
+    internal enum ImageUtilError
+    {
+        None = ErrorCode.None,
+        OutOfMemory = ErrorCode.OutOfMemory,
+        InvalidParameter = ErrorCode.InvalidParameter,
+        InvalidOperation = ErrorCode.InvalidOperation,
+        PermissionDenied = ErrorCode.PermissionDenied,
+        NotSupported = ErrorCode.NotSupported,
+        NoSuchFile = ErrorCode.NoSuchFile,
+        NotSupportedFormat = -0x01920000 | 0x01,
+    }
+
+    internal static class ImageUtilErrorExtesions
+    {
+        internal static void ThrowIfFailed(this ImageUtilError err, string message)
+        {
+            if (err == ImageUtilError.None)
+            {
+                return;
+            }
+
+            throw err.ToException(message);
+        }
+
+        internal static Exception ToException(this ImageUtilError err, string message)
+        {
+            Debug.Assert(err != ImageUtilError.None);
+
+            string errMessage = $"{message}; {err}.";
+            switch (err)
+            {
+                case ImageUtilError.PermissionDenied:
+                    return new UnauthorizedAccessException(errMessage);
+
+                case ImageUtilError.InvalidParameter:
+                    return new ArgumentException(errMessage);
+
+                case ImageUtilError.NoSuchFile:
+                    return new FileNotFoundException(errMessage);
+
+                case ImageUtilError.OutOfMemory:
+                    return new OutOfMemoryException(errMessage);
+
+                case ImageUtilError.NotSupported:
+                    return new NotSupportedException(errMessage);
+
+                case ImageUtilError.NotSupportedFormat:
+                    return new FileFormatException(errMessage);
+
+                case ImageUtilError.InvalidOperation:
+                default:
+                    return new InvalidOperationException(errMessage);
+            }
+        }
+    }
+
+}
  * limitations under the License.
  */
 
-namespace Tizen.Multimedia.Utility
+namespace Tizen.Multimedia.Util
 {
     /// <summary>
-    /// Image Format
+    /// Specifies JPEG Downscale options for decoding.
     /// </summary>
-    public enum ImageFormat
+    public enum JpegDownscale
     {
         /// <summary>
-        /// JPEG image
+        /// No downscale.
         /// </summary>
-        Jpeg = global::Interop.ImageType.Jpeg,
+        None,
         /// <summary>
-        /// PNG image
+        /// 1/2 downscale.
         /// </summary>
-        Png = global::Interop.ImageType.Png,
+        OneHalf,
         /// <summary>
-        /// GIF image
+        /// 1/4 downscale.
         /// </summary>
-        Gif = global::Interop.ImageType.Gif,
+        OneFourth,
         /// <summary>
-        /// BMP image
+        /// 1/8 downscale.
         /// </summary>
-        Bmp = global::Interop.ImageType.Bmp,
+        OneEighth,
     }
-}
\ No newline at end of file
+}
  * limitations under the License.
  */
 
-namespace Tizen.Multimedia.Utility
+namespace Tizen.Multimedia.Util
 {
     /// <summary>
-    /// PNG Image Compression Level
+    /// Specifies PNG compression levels.
     /// </summary>
     public enum PngCompression
     {
         /// <summary>
-        /// No Compression
+        /// No Compression.
         /// </summary>
-        NoCompression = global::Interop.PngCompression.NoCompression,
+        None,
         /// <summary>
-        /// Compression Level 1. Best speed
+        /// Compression Level 1. Best speed.
         /// </summary>
-        Level1 = global::Interop.PngCompression.Level1,
+        Level1,
         /// <summary>
-        /// Compression Level 2
+        /// Compression Level 2.
         /// </summary>
-        Level2 = global::Interop.PngCompression.Level2,
+        Level2,
         /// <summary>
-        /// Compression Level 3
+        /// Compression Level 3.
         /// </summary>
-        Level3 = global::Interop.PngCompression.Level3,
+        Level3,
         /// <summary>
-        /// Compression Level 4
+        /// Compression Level 4.
         /// </summary>
-        Level4 = global::Interop.PngCompression.Level4,
+        Level4,
         /// <summary>
-        /// Compression Level 5
+        /// Compression Level 5.
         /// </summary>
-        Level5 = global::Interop.PngCompression.Level5,
+        Level5,
         /// <summary>
-        /// Compression Level 6
+        /// Compression Level 6.
         /// </summary>
-        Level6 = global::Interop.PngCompression.Level6,
+        Level6,
         /// <summary>
-        /// Compression Level 7
+        /// Compression Level 7.
         /// </summary>
-        Level7 = global::Interop.PngCompression.Level7,
+        Level7,
         /// <summary>
-        /// Compression Level 8
+        /// Compression Level 8.
         /// </summary>
-        Level8 = global::Interop.PngCompression.Level8,
+        Level8,
         /// <summary>
-        /// Compression Level 9
+        /// Compression Level 9.
         /// </summary>
-        Level9 = global::Interop.PngCompression.Level9,
+        Level9,
     }
 }
diff --git a/src/Tizen.Multimedia.Util/Interop/Interop.ErrorCode.cs b/src/Tizen.Multimedia.Util/Interop/Interop.ErrorCode.cs
deleted file mode 100644 (file)
index 169c630..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System;
-using System.IO;
-using System.Runtime.CompilerServices;
-using Tizen;
-
-internal static partial class Interop
-{
-    internal enum ErrorCode
-    {
-        None = Tizen.Internals.Errors.ErrorCode.None,
-        OutOfMemory = Tizen.Internals.Errors.ErrorCode.OutOfMemory,
-        InvalidParameter = Tizen.Internals.Errors.ErrorCode.InvalidParameter,
-        InvalidOperation = Tizen.Internals.Errors.ErrorCode.InvalidOperation,
-        PermissionDenied = Tizen.Internals.Errors.ErrorCode.PermissionDenied,
-        NotSupported = Tizen.Internals.Errors.ErrorCode.NotSupported,
-        ResourceBusy = Tizen.Internals.Errors.ErrorCode.ResourceBusy,
-        NoSuchFile = Tizen.Internals.Errors.ErrorCode.NoSuchFile,
-
-        // Radio
-        InvalidState = -0x019A0000 | 0x01, // RADIO_ERROR_INVALID_STATE
-        SoundPolicy = -0x019A0000 | 0x02, // RADIO_ERROR_SOUND_POLICY
-        NoAntenna = -0x019A0000 | 0x03, // RADIO_ERROR_NO_ANTENNA
-
-        // Image/ Video Utility
-        NotSupportedFormat = -0x01980000 | 0x01, // VIDEO_UTIL_ERROR_NOT_SUPPORTED_FORMAT
-    }
-}
-
-internal static class ErrorCodeExtensions
-{
-    private const string LogTag = "Tizen.Multimedia";
-
-    internal static bool IsSuccess(this Interop.ErrorCode err)
-    {
-        return err == Interop.ErrorCode.None;
-    }
-
-    internal static bool IsFailed(this Interop.ErrorCode err)
-    {
-        return !err.IsSuccess();
-    }
-
-    /// <summary>
-    /// Utility method to check for error, returns false if failed and print warning messages
-    /// </summary>
-    /// <returns>true in case of no error, false otherwise</returns>
-    internal static bool WarnIfFailed(this Interop.ErrorCode err, string msg, [CallerFilePath] string file = "", [CallerMemberName] string func = "", [CallerLineNumber] int line = 0)
-    {
-        if (err.IsFailed())
-        {
-            Log.Debug(LogTag, $"{msg}, err: {err.ToString()}", file, func, line);
-            return false;
-        }
-        return true;
-    }
-
-    /// <summary>
-    /// Utility method to check for error, returns false if failed and throw exception
-    /// </summary>
-    /// <returns>true in case of no error</returns>
-    internal static bool ThrowIfFailed(this Interop.ErrorCode err, string msg, [CallerFilePath] string file = "", [CallerMemberName] string func = "", [CallerLineNumber] int line = 0)
-    {
-        if (err.IsFailed())
-        {
-            Log.Error(LogTag, $"{msg}, err: {err.ToString()}", file, func, line);
-            throw err.GetException(msg);
-        }
-        return true;
-    }
-
-    internal static Exception GetException(this Interop.ErrorCode err, string message)
-    {
-        string errMessage = $"{message}, err: {err.ToString()}";
-        switch (err)
-        {
-            //case ErrorCode.None:
-            case Interop.ErrorCode.PermissionDenied: return new UnauthorizedAccessException(errMessage);
-            case Interop.ErrorCode.InvalidParameter: return new ArgumentException(errMessage);
-            case Interop.ErrorCode.NoSuchFile: return new FileNotFoundException(errMessage);
-            case Interop.ErrorCode.OutOfMemory: return new OutOfMemoryException(errMessage);
-            case Interop.ErrorCode.NoAntenna:
-            case Interop.ErrorCode.NotSupported: return new NotSupportedException(errMessage);
-            case Interop.ErrorCode.InvalidOperation:
-            case Interop.ErrorCode.InvalidState:
-            case Interop.ErrorCode.SoundPolicy:
-            case Interop.ErrorCode.ResourceBusy:
-            default: return new InvalidOperationException(errMessage);
-        }
-    }
-}
index c295303..f7636c6 100644 (file)
 
 using System;
 using System.Runtime.InteropServices;
+using Tizen;
+using Tizen.Multimedia.Util;
 
 internal static partial class Interop
 {
-    // Image Decoder
-    [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_decode_set_input_path")]
-    internal static extern ErrorCode SetInputPath(this ImageDecoderHandle /* image_util_decode_h */ handle, string path);
+    internal static class Decode
+    {
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate void DecodeCompletedCallback(ImageUtilError error, IntPtr userData, int width, int height, ulong size);
 
-    [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_decode_set_input_buffer")]
-    internal static extern ErrorCode SetInputBuffer(this ImageDecoderHandle /* image_util_decode_h */ handle, byte[] srcBuffer, ulong srcSize);
+        [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_decode_create")]
+        public static extern ImageUtilError Create(out ImageDecoderHandle handle);
 
-    [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_decode_set_output_buffer")]
-    internal static extern ErrorCode SetOutputBuffer(this ImageDecoderHandle /* image_util_decode_h */ handle, out IntPtr dstBuffer);
+        [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_decode_destroy")]
+        internal static extern ImageUtilError Destroy(IntPtr handle);
 
-    [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_decode_set_colorspace")]
-    internal static extern ErrorCode SetColorspace(this ImageDecoderHandle /* image_util_encode_h */ handle, ImageColorSpace /* image_util_colorspace_e */ colorspace);
+        [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_decode_set_input_path")]
+        internal static extern ImageUtilError SetInputPath(ImageDecoderHandle handle, IntPtr path);
 
-    [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_decode_set_jpeg_downscale")]
-    internal static extern ErrorCode SetJpegDownscale(this ImageDecoderHandle /* image_util_encode_h */ handle, JpegDownscale /* image_util_scale_e */ downscale);
+        [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_decode_set_input_buffer")]
+        internal static extern ImageUtilError SetInputBuffer(ImageDecoderHandle handle, byte[] srcBuffer, ulong srcSize);
 
-    [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_decode_run")]
-    internal static extern ErrorCode DecodeRun(this ImageDecoderHandle /* image_util_decode_h */ handle, out int width, out int height, out ulong size);
+        [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_decode_set_output_buffer")]
+        internal static extern ImageUtilError SetOutputBuffer(ImageDecoderHandle handle, out IntPtr dstBuffer);
 
-    internal class ImageDecoderHandle : SafeMultimediaHandle
-    {
-        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate void DecodeCompletedCallback(ErrorCode errorCode, IntPtr /* void */ userData, int width, int height, ulong size);
+        [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_decode_set_colorspace")]
+        internal static extern ImageUtilError SetColorspace(ImageDecoderHandle handle, ImageColorSpace colorspace);
 
-        [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_decode_run_async")]
-        internal static extern ErrorCode DecodeRunAsync(ImageDecoderHandle /* image_util_decode_h */ handle, DecodeCompletedCallback callback, IntPtr /* void */ userData);
-
-        [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_decode_create")]
-        internal static extern ErrorCode Create(out IntPtr /* image_util_decode_h */ handle);
-
-        [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_decode_destroy")]
-        internal static extern ErrorCode Destroy(IntPtr /* image_util_decode_h */ handle);
+        [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_decode_set_jpeg_downscale")]
+        internal static extern ImageUtilError SetJpegDownscale(ImageDecoderHandle handle, JpegDownscale downscale);
 
-        internal ImageColorSpace Colorspace
-        {
-            set { NativeSet(this.SetColorspace, value); }
-        }
+        [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_decode_run_async")]
+        internal static extern ImageUtilError DecodeRunAsync(ImageDecoderHandle handle, DecodeCompletedCallback callback,
+            IntPtr userData = default(IntPtr));
 
-        internal JpegDownscale JpegDownscale
-        {
-            set { NativeSet(this.SetJpegDownscale, value); }
-        }
+        [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_decode_run")]
+        internal static extern ImageUtilError DecodeRun(ImageDecoderHandle handle, out int width,
+            out int height, out ulong size);
+    }
 
-        internal ImageDecoderHandle(IntPtr handle, bool needToRelease) : base(handle, needToRelease)
+    internal class ImageDecoderHandle : SafeHandle
+    {
+        protected ImageDecoderHandle() : base(IntPtr.Zero, true)
         {
         }
 
-        internal ImageDecoderHandle() : this(CreateNativeHandle(), true)
-        {
-        }
+        public override bool IsInvalid => handle == IntPtr.Zero;
 
-        internal static IntPtr CreateNativeHandle()
+        protected override bool ReleaseHandle()
         {
-            IntPtr handle;
-            Create(out handle).ThrowIfFailed("Failed to create native handle");
-            return handle;
+            var ret = Decode.Destroy(handle);
+            if (ret != ImageUtilError.None)
+            {
+                Log.Debug(GetType().FullName, $"Failed to release native {GetType()}");
+                return false;
+            }
+
+            return true;
         }
 
-        internal override ErrorCode DisposeNativeHandle()
-        {
-            return Destroy(handle);
-        }
     }
 }
index 18b98a3..ada1c39 100644 (file)
 
 using System;
 using System.Runtime.InteropServices;
+using Tizen;
+using Tizen.Multimedia.Util;
 
 internal static partial class Interop
 {
-    // Image Encoder
-    [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_encode_set_resolution")]
-    internal static extern ErrorCode SetResolution(this ImageEncoderHandle /* image_util_encode_h */ handle, uint width, uint height);
-
-    [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_encode_set_colorspace")]
-    internal static extern ErrorCode SetColorspace(this ImageEncoderHandle /* image_util_encode_h */ handle, ImageColorSpace /* image_util_colorspace_e */ colorspace);
-
-    [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_encode_set_quality")]
-    internal static extern ErrorCode SetQuality(this ImageEncoderHandle /* image_util_encode_h */ handle, int quality);
-
-    [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_encode_set_png_compression")]
-    internal static extern ErrorCode SetPngCompression(this ImageEncoderHandle /* image_util_encode_h */ handle, PngCompression /* image_util_png_compression_e */ compression);
-
-    [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_encode_set_gif_frame_delay_time")]
-    internal static extern ErrorCode SetGifFrameDelayTime(this ImageEncoderHandle /* image_util_encode_h */ handle, ulong delayTime);
-
-    [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_encode_set_output_path")]
-    internal static extern ErrorCode SetOutputPath(this ImageEncoderHandle /* image_util_encode_h */ handle, string path);
-
-    [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_encode_set_input_buffer")]
-    internal static extern ErrorCode SetInputBuffer(this ImageEncoderHandle /* image_util_encode_h */ handle, byte[] srcBuffer);
+    internal static partial class ImageUtil
+    {
+        internal static class Encode
+        {
+            [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+            internal delegate void EncodeCompletedCallback(ImageUtilError ImageUtilError, IntPtr userData, ulong size);
 
-    [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_encode_set_output_buffer")]
-    internal static extern ErrorCode SetOutputBuffer(this ImageEncoderHandle /* image_util_encode_h */ handle, out IntPtr dstBuffer);
+            [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_encode_run_async")]
+            internal static extern ImageUtilError EncodeRunAsync(ImageEncoderHandle handle,
+                EncodeCompletedCallback callback, IntPtr userData = default(IntPtr));
 
-    [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_encode_run")]
-    internal static extern ErrorCode EncodeRun(this ImageEncoderHandle /* image_util_encode_h */ handle, out ulong size);
+            [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_encode_create")]
+            internal static extern ImageUtilError Create(ImageFormat type, out ImageEncoderHandle handle);
 
-    internal class ImageEncoderHandle : SafeMultimediaHandle
-    {
-        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate void EncodeCompletedCallback(ErrorCode errorCode, IntPtr /* void */ userData, ulong size);
+            [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_encode_destroy")]
+            internal static extern ImageUtilError Destroy(IntPtr handle);
 
-        [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_encode_run_async")]
-        internal static extern ErrorCode EncodeRunAsync(ImageEncoderHandle /* image_util_encode_h */ handle, EncodeCompletedCallback callback, IntPtr /* void */ userData);
+            [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_encode_set_resolution")]
+            internal static extern ImageUtilError SetResolution(ImageEncoderHandle handle, uint width, uint height);
 
+            [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_encode_set_colorspace")]
+            internal static extern ImageUtilError SetColorspace(ImageEncoderHandle handle, ImageColorSpace colorspace);
 
-        [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_encode_create")]
-        internal static extern ErrorCode Create(ImageType /* image_util_type_e */ type, out IntPtr /* image_util_encode_h */ handle);
+            [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_encode_set_quality")]
+            internal static extern ImageUtilError SetQuality(ImageEncoderHandle handle, int quality);
 
-        [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_encode_destroy")]
-        internal static extern ErrorCode Destroy(IntPtr /* image_util_encode_h */ handle);
+            [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_encode_set_png_compression")]
+            internal static extern ImageUtilError SetPngCompression(ImageEncoderHandle handle, PngCompression compression);
 
-        internal ImageEncoderHandle(IntPtr handle, bool needToRelease) : base(handle, needToRelease)
-        {
-        }
+            [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_encode_set_gif_frame_delay_time")]
+            internal static extern ImageUtilError SetGifFrameDelayTime(ImageEncoderHandle handle, ulong delayTime);
 
-        internal ImageEncoderHandle(ImageType type) : this(CreateNativeHandle(type), true)
-        {
-        }
+            [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_encode_set_output_path")]
+            internal static extern ImageUtilError SetOutputPath(ImageEncoderHandle handle, string path);
 
-        internal ImageColorSpace Colorspace
-        {
-            set { NativeSet(this.SetColorspace, value); }
-        }
+            [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_encode_set_input_buffer")]
+            internal static extern ImageUtilError SetInputBuffer(ImageEncoderHandle handle, byte[] srcBuffer);
 
-        internal int Quality
-        {
-            set { NativeSet(this.SetQuality, value); }
-        }
+            [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_encode_set_output_buffer")]
+            internal static extern ImageUtilError SetOutputBuffer(ImageEncoderHandle handle, out IntPtr dstBuffer);
 
-        internal PngCompression PngCompression
-        {
-            set { NativeSet(this.SetPngCompression, value); }
+            [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_encode_run")]
+            internal static extern ImageUtilError Run(ImageEncoderHandle handle, out ulong size);
         }
 
-        internal ulong GifFrameDelay
+        internal class ImageEncoderHandle : SafeHandle
         {
-            set { NativeSet(this.SetGifFrameDelayTime, value); }
-        }
+            protected ImageEncoderHandle() : base(IntPtr.Zero, true)
+            {
+            }
 
-        internal string OutputPath
-        {
-            set { NativeSet(this.SetOutputPath, value); }
-        }
+            public override bool IsInvalid => handle == IntPtr.Zero;
 
-        internal byte[] InputBuffer
-        {
-            set { NativeSet(this.SetInputBuffer, value); }
-        }
 
-        internal static IntPtr CreateNativeHandle(ImageType type)
-        {
-            IntPtr handle;
-            Create(type, out handle).ThrowIfFailed("Failed to create native handle");
-            return handle;
-        }
+            protected override bool ReleaseHandle()
+            {
+                var ret = Encode.Destroy(handle);
+                if (ret != ImageUtilError.None)
+                {
+                    Log.Debug(GetType().FullName, $"Failed to release native {GetType().Name}");
+                    return false;
+                }
 
-        internal override ErrorCode DisposeNativeHandle()
-        {
-            return Destroy(handle);
+                return true;
+            }
         }
     }
 }
index 9bad56c..186b2c0 100644 (file)
 
 using System;
 using System.Runtime.InteropServices;
+using Tizen;
+using Tizen.Multimedia.Util;
 
 internal static partial class Interop
 {
-    [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_transform_set_hardware_acceleration")]
-    internal static extern ErrorCode SetHardwareAcceleration(this ImageTransformHandle /* transformation_h */ handle, bool mode);
-
-    [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_transform_get_colorspace")]
-    internal static extern ErrorCode GetColorspace(this ImageTransformHandle /* transformation_h */ handle, out ImageColorSpace /* image_util_colorspace_e */ colorspace);
-
-    [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_transform_set_colorspace")]
-    internal static extern ErrorCode SetColorspace(this ImageTransformHandle /* transformation_h */ handle, ImageColorSpace /* image_util_colorspace_e */ colorspace);
-
-    [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_transform_get_rotation")]
-    internal static extern ErrorCode GetRotation(this ImageTransformHandle /* transformation_h */ handle, out ImageRotation /* image_util_rotation_e */ rotation);
-
-    [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_transform_set_rotation")]
-    internal static extern ErrorCode SetRotation(this ImageTransformHandle /* transformation_h */ handle, ImageRotation /* image_util_rotation_e */ rotation);
-
-    [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_transform_get_resolution")]
-    internal static extern ErrorCode GetResolution(this ImageTransformHandle /* transformation_h */ handle, out uint width, out uint height);
-
-    [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_transform_set_resolution")]
-    internal static extern ErrorCode SetResolution(this ImageTransformHandle /* transformation_h */ handle, uint width, uint height);
+    internal static partial class ImageUtil
+    {
+        internal static class Transform
+        {
+            [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+            internal delegate void TransformCompletedCallback(IntPtr resultPacket, ImageUtilError errorCode,
+                IntPtr userData = default(IntPtr));
 
-    [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_transform_get_crop_area")]
-    internal static extern ErrorCode GetCropArea(this ImageTransformHandle /* transformation_h */ handle, out uint startX, out uint startY, out uint endX, out uint endY);
+            [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_transform_run")]
+            internal static extern ImageUtilError Run(TransformHandle handle, IntPtr srcPacket,
+                TransformCompletedCallback callback, IntPtr userData = default(IntPtr));
 
-    [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_transform_set_crop_area")]
-    internal static extern ErrorCode SetCropArea(this ImageTransformHandle /* transformation_h */ handle, int startX, int startY, int endX, int endY);
+            [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_transform_create")]
+            internal static extern ImageUtilError Create(out TransformHandle handle);
 
-    internal class ImageTransformHandle : SafeMultimediaHandle
-    {
-        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate void TransformCompletedCallback(IntPtr /* media_packet_h */ dst, ErrorCode errorCode, IntPtr /* void */ userData);
+            [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_transform_destroy")]
+            internal static extern ImageUtilError Destroy(IntPtr handle);
 
-        [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_transform_run")]
-        internal static extern ErrorCode Transform(ImageTransformHandle /* transformation_h */ handle, IntPtr /* media_packet_h */ src, TransformCompletedCallback callback, IntPtr /* void */ userData);
+            [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_transform_get_colorspace")]
+            internal static extern ImageUtilError GetColorspace(TransformHandle handle, out ImageColorSpace colorspace);
 
+            [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_transform_set_colorspace")]
+            internal static extern ImageUtilError SetColorspace(TransformHandle handle, ImageColorSpace colorspace);
 
-        [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_transform_create")]
-        internal static extern ErrorCode Create(out IntPtr /* transformation_h */ handle);
+            [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_transform_set_hardware_acceleration")]
+            internal static extern ImageUtilError SetHardwareAcceleration(TransformHandle handle, bool mode);
 
-        [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_transform_destroy")]
-        internal static extern ErrorCode Destroy(IntPtr /* transformation_h */ handle);
-
-        internal ImageTransformHandle(IntPtr handle, bool needToRelease) : base(handle, needToRelease)
-        {
-        }
+            [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_transform_get_rotation")]
+            internal static extern ImageUtilError GetRotation(TransformHandle handle, out ImageRotation rotation);
 
-        internal ImageTransformHandle() : this(CreateNativeHandle(), true)
-        {
-        }
+            [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_transform_set_rotation")]
+            internal static extern ImageUtilError SetRotation(TransformHandle handle, ImageRotation rotation);
 
-        internal bool HardwareAccelerationEnabled
-        {
-            set { NativeSet(this.SetHardwareAcceleration, value); }
-        }
+            [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_transform_get_crop_area")]
+            internal static extern ImageUtilError GetCropArea(TransformHandle handle, out uint startX, out uint startY, out uint endX, out uint endY);
 
-        internal ImageColorSpace Colorspace
-        {
-            get { return NativeGet<ImageColorSpace>(this.GetColorspace); }
-            set { NativeSet(this.SetColorspace, value); }
-        }
+            [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_transform_set_crop_area")]
+            internal static extern ImageUtilError SetCropArea(TransformHandle handle, int startX, int startY, int endX, int endY);
 
-        internal ImageRotation Rotation
-        {
-            get { return NativeGet<ImageRotation>(this.GetRotation); }
-            set { NativeSet(this.SetRotation, value); }
-        }
+            [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_transform_get_resolution")]
+            internal static extern ImageUtilError GetResolution(TransformHandle handle, out uint width, out uint height);
 
-        internal static IntPtr CreateNativeHandle()
-        {
-            IntPtr handle;
-            Create(out handle).ThrowIfFailed("Failed to create native handle");
-            return handle;
+            [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_transform_set_resolution")]
+            internal static extern ImageUtilError SetResolution(TransformHandle handle, uint width, uint height);
         }
 
-        internal override ErrorCode DisposeNativeHandle()
+        internal class TransformHandle : SafeHandle
         {
-            return Destroy(handle);
+            protected TransformHandle() : base(IntPtr.Zero, true)
+            {
+            }
+
+            public override bool IsInvalid => handle == IntPtr.Zero;
+
+            protected override bool ReleaseHandle()
+            {
+                var ret = Transform.Destroy(handle);
+                if (ret != ImageUtilError.None)
+                {
+                    Log.Debug(GetType().FullName, $"Failed to release native {GetType().Name}");
+                    return false;
+                }
+
+                return true;
+            }
         }
     }
+
 }
index d3f74b6..728f4c0 100644 (file)
  */
 
 using System;
-using System.Diagnostics;
 using System.Runtime.InteropServices;
-using Tizen.Multimedia;
+using Tizen.Multimedia.Util;
 
 internal static partial class Interop
 {
-    internal enum ImageColorSpace
-    {
-        Yv12, // IMAGE_UTIL_COLORSPACE_YV12
-        Yuv422, // IMAGE_UTIL_COLORSPACE_YUV422
-        I420, // IMAGE_UTIL_COLORSPACE_I420
-        Nv12, // IMAGE_UTIL_COLORSPACE_NV12
-        Uyvy, // IMAGE_UTIL_COLORSPACE_UYVY
-        Yuyv, // IMAGE_UTIL_COLORSPACE_YUYV
-        Rgb565, // IMAGE_UTIL_COLORSPACE_RGB565
-        Rgb888, // IMAGE_UTIL_COLORSPACE_RGB888
-        Argb8888, // IMAGE_UTIL_COLORSPACE_ARGB8888
-        Bgra8888, // IMAGE_UTIL_COLORSPACE_BGRA8888
-        Rgba8888, // IMAGE_UTIL_COLORSPACE_RGBA8888
-        Bgrx8888, // IMAGE_UTIL_COLORSPACE_BGRX8888
-        Nv21, // IMAGE_UTIL_COLORSPACE_NV21
-        Nv16, // IMAGE_UTIL_COLORSPACE_NV16
-        Nv61, // IMAGE_UTIL_COLORSPACE_NV61
-    }
-
-    internal enum ImageRotation
-    {
-        None, // IMAGE_UTIL_ROTATION_NONE
-        Rotate90, // IMAGE_UTIL_ROTATION_90
-        Rotate180, // IMAGE_UTIL_ROTATION_180
-        Rotate270, // IMAGE_UTIL_ROTATION_270
-        FlipHorizontal, // IMAGE_UTIL_ROTATION_FLIP_HORZ
-        FlipVertical, // IMAGE_UTIL_ROTATION_FLIP_VERT
-    }
-
-    internal enum ImageType
-    {
-        Jpeg, // IMAGE_UTIL_JPEG
-        Png, // IMAGE_UTIL_PNG
-        Gif, // IMAGE_UTIL_GIF
-        Bmp, // IMAGE_UTIL_BMP
-    }
-
-    internal enum JpegDownscale
-    {
-        NoDownscale, // IMAGE_UTIL_DOWNSCALE_1_1
-        OneHalf, // IMAGE_UTIL_DOWNSCALE_1_2
-        OneFourth, // IMAGE_UTIL_DOWNSCALE_1_4
-        OneEighth, // IMAGE_UTIL_DOWNSCALE_1_8
-    }
-
-    internal enum PngCompression
-    {
-        NoCompression, // IMAGE_UTIL_PNG_COMPRESSION_0
-        Level1, // IMAGE_UTIL_PNG_COMPRESSION_1
-        Level2, // IMAGE_UTIL_PNG_COMPRESSION_2
-        Level3, // IMAGE_UTIL_PNG_COMPRESSION_3
-        Level4, // IMAGE_UTIL_PNG_COMPRESSION_4
-        Level5, // IMAGE_UTIL_PNG_COMPRESSION_5
-        Level6, // IMAGE_UTIL_PNG_COMPRESSION_6
-        Level7, // IMAGE_UTIL_PNG_COMPRESSION_7
-        Level8, // IMAGE_UTIL_PNG_COMPRESSION_8
-        Level9, // IMAGE_UTIL_PNG_COMPRESSION_9
-    }
-
-    internal class ImageUtil
+    internal static partial class ImageUtil
     {
         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        internal delegate bool SupportedColorspaceCallback(ImageColorSpace /* image_util_colorspace_e */ colorspace, IntPtr /* void */ userData);
+        internal delegate bool SupportedColorspaceCallback(ImageColorSpace colorspace, IntPtr userData);
 
         [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_foreach_supported_colorspace")]
-        internal static extern ErrorCode ForeachSupportedColorspace(ImageType /* image_util_type_e */ type, SupportedColorspaceCallback callback, IntPtr /* void */ userData);
+        internal static extern ImageUtilError ForeachSupportedColorspace(ImageFormat type, SupportedColorspaceCallback callback,
+            IntPtr userData = default(IntPtr));
 
         [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_calculate_buffer_size")]
-        internal static extern ErrorCode CalculateBufferSize(int width, int height, ImageColorSpace /* image_util_colorspace_e */ colorspace, out uint size);
+        internal static extern ImageUtilError CalculateBufferSize(int width, int height, ImageColorSpace colorspace, out uint size);
 
         [DllImport(Libraries.ImageUtil, EntryPoint = "image_util_extract_color_from_memory")]
-        internal static extern ErrorCode ExtractColorFromMemory(byte[] buffer, int width, int height, out byte rgbR, out byte rgbG, out byte rgbB);
-
-        internal static void ForeachSupportedColorspace(ImageType type, Action<ImageColorSpace> action)
-        {
-            SupportedColorspaceCallback callback = (codec, userData) =>
-            {
-                action(codec);
-                return true;
-            };
-
-            ForeachSupportedColorspace(type, callback, IntPtr.Zero).WarnIfFailed("Failed to get supported color-space list from native handle");
-        }
-
-        internal static uint CalculateBufferSize(int width, int height, ImageColorSpace colorSpace)
-        {
-            uint size;
-            CalculateBufferSize(width, height, colorSpace, out size).ThrowIfFailed("Failed to calculate buffer size");
-            return size;
-        }
-
-        internal static ElmSharp.Color ExtractColorFromMemory(byte[] buffer, int width, int height)
-        {
-            byte r, g, b;
-            ExtractColorFromMemory(buffer, width, height, out r, out g, out b);
-            return new ElmSharp.Color(r, g, b);
-        }
-
-        internal static byte[] NativeToByteArray(IntPtr nativeBuffer, int size)
-        {
-            Debug.Assert(nativeBuffer != IntPtr.Zero);
-
-            byte[] managedArray = new byte[size];
-            Marshal.Copy(nativeBuffer, managedArray, 0, size);
-
-            LibcSupport.Free(nativeBuffer);
-            return managedArray;
-        }
+        internal static extern ImageUtilError ExtractColorFromMemory(byte[] buffer, int width, int height, out byte rgbR, out byte rgbG, out byte rgbB);
     }
-}
\ No newline at end of file
+}
diff --git a/src/Tizen.Multimedia.Util/Interop/Interop.SafeMultimediaHandle.cs b/src/Tizen.Multimedia.Util/Interop/Interop.SafeMultimediaHandle.cs
deleted file mode 100644 (file)
index ced1e62..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System;
-using System.Diagnostics;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Threading.Tasks;
-
-internal static partial class Interop
-{
-    internal static Task<T> PinnedTask<T>(TaskCompletionSource<T> tcs)
-    {
-        var gch = GCHandle.Alloc(tcs);
-        return tcs.Task.ContinueWith(
-            t => { gch.Free(); return t; },
-            TaskContinuationOptions.ExecuteSynchronously).Unwrap();
-    }
-
-    internal abstract class SafeMultimediaHandle : SafeHandle
-    {
-        internal delegate ErrorCode GetterMethod<TProp>(out TProp value);
-        internal delegate ErrorCode SetterMethod<TProp>(TProp value);
-
-        protected SafeMultimediaHandle(IntPtr handle, bool needToRelease) : base(handle, true)
-        {
-            Debug.Assert(handle != IntPtr.Zero);
-            HasOwnership = needToRelease;
-        }
-
-        internal bool HasOwnership { get; set; }
-        public override bool IsInvalid { get { return handle == IntPtr.Zero; } }
-
-        internal abstract ErrorCode DisposeNativeHandle();
-
-        internal TProp NativeGet<TProp>(GetterMethod<TProp> getter, [CallerMemberName] string propertyName = "")
-        {
-            TProp value; getter(out value).ThrowIfFailed($"Failed to get {propertyName}");
-            return value;
-        }
-
-        internal string NativeGet(GetterMethod<string> getter, [CallerMemberName] string propertyName = "")
-        {
-            string value; getter(out value).ThrowIfFailed($"Failed to get {propertyName}");
-            return value;
-        }
-
-        internal void NativeSet<TProp>(SetterMethod<TProp> setter, TProp value, [CallerMemberName] string propertyName = "")
-        {
-            setter(value).ThrowIfFailed($"Failed to set {propertyName}");
-        }
-
-        protected override bool ReleaseHandle()
-        {
-            var err = ErrorCode.None;
-            if (HasOwnership)
-            {
-                err = DisposeNativeHandle();
-                err.WarnIfFailed($"Failed to delete native {GetType()} handle");
-            }
-
-            SetHandle(IntPtr.Zero);
-            return err.IsSuccess();
-        }
-    }
-}
diff --git a/src/Tizen.Multimedia.Util/Utility/ImageColorSpace.cs b/src/Tizen.Multimedia.Util/Utility/ImageColorSpace.cs
deleted file mode 100644 (file)
index 8db3d6f..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-namespace Tizen.Multimedia.Utility
-{
-    /// <summary>
-    /// Image color space
-    /// </summary>
-    public enum ImageColorSpace
-    {
-        /// <summary>
-        /// YV12 - YCrCb planar format
-        /// </summary>
-        Yv12 = global::Interop.ImageColorSpace.Yv12,
-        /// <summary>
-        /// UYVY - packed
-        /// </summary>
-        Uyvy = global::Interop.ImageColorSpace.Uyvy,
-        /// <summary>
-        /// YUYV - packed
-        /// </summary>
-        Yuyv = global::Interop.ImageColorSpace.Yuyv,
-        /// <summary>
-        /// YUV422 - planar
-        /// </summary>
-        Yuv422 = global::Interop.ImageColorSpace.Yuv422,
-        /// <summary>
-        /// YUV420 - planar
-        /// </summary>
-        I420 = global::Interop.ImageColorSpace.I420,
-        /// <summary>
-        /// RGB565, high-byte is Blue
-        /// </summary>
-        Rgb565 = global::Interop.ImageColorSpace.Rgb565,
-        /// <summary>
-        /// RGB888, high-byte is Blue
-        /// </summary>
-        Rgb888 = global::Interop.ImageColorSpace.Rgb888,
-        /// <summary>
-        /// ARGB8888, high-byte is Blue
-        /// </summary>
-        Argb8888 = global::Interop.ImageColorSpace.Argb8888,
-        /// <summary>
-        /// BGRA8888, high-byte is Alpha
-        /// </summary>
-        Bgra8888 = global::Interop.ImageColorSpace.Bgra8888,
-        /// <summary>
-        /// RGBA8888, high-byte is Alpha
-        /// </summary>
-        Rgba8888 = global::Interop.ImageColorSpace.Rgba8888,
-        /// <summary>
-        /// BGRX8888, high-byte is X
-        /// </summary>
-        Bgrx8888 = global::Interop.ImageColorSpace.Bgrx8888,
-        /// <summary>
-        /// NV12- planar
-        /// </summary>
-        Nv12 = global::Interop.ImageColorSpace.Nv12,
-        /// <summary>
-        /// NV16- planar
-        /// </summary>
-        Nv16 = global::Interop.ImageColorSpace.Nv16,
-        /// <summary>
-        /// NV21- planar
-        /// </summary>
-        Nv21 = global::Interop.ImageColorSpace.Nv21,
-        /// <summary>
-        /// NV61- planar
-        /// </summary>
-        Nv61 = global::Interop.ImageColorSpace.Nv61,
-    }
-}
\ No newline at end of file
diff --git a/src/Tizen.Multimedia.Util/Utility/ImageData.cs b/src/Tizen.Multimedia.Util/Utility/ImageData.cs
deleted file mode 100644 (file)
index 819ebbd..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System;
-using Tizen.Common;
-using static Interop.ImageUtil;
-
-namespace Tizen.Multimedia.Utility
-{
-    /// <summary>
-    /// Image data class used with ImageDecoder
-    /// </summary>
-    public class ImageData
-    {
-        private Lazy<Color> _color;
-
-        /// <summary>
-        /// Constructor
-        /// </summary>
-        /// <param name="buffer">Image buffer</param>
-        /// <param name="width">Width</param>
-        /// <param name="height">Height</param>
-        /// <param name="size">Buffer size</param>
-        public ImageData(byte[] buffer, int width, int height)
-        {
-            if (buffer == null || buffer.Length == 0)
-                throw new ArgumentNullException("buffer");
-
-            Buffer = buffer;
-            Width = width;
-            Height = height;
-
-            _color = new Lazy<Color>(() => GetColor());
-        }
-
-        internal ImageData(IntPtr nativeBuffer, int width, int height, int size)
-        {
-            Buffer = NativeToByteArray(nativeBuffer, size);
-            Width = width;
-            Height = height;
-        }
-
-        /// <summary>
-        /// Image buffer
-        /// </summary>
-        public byte[] Buffer { get; }
-
-        /// <summary>
-        /// Image width
-        /// </summary>
-        public int Width { get; }
-
-        /// <summary>
-        /// Image height
-        /// </summary>
-        public int Height { get; }
-
-        /// <summary>
-        /// Image color
-        /// </summary>
-        public Color color
-        {
-            get
-            {
-                return _color.Value;
-            }
-        }
-
-        private Color GetColor()
-        {
-            byte r, g, b, a = 0;
-            ExtractColorFromMemory(Buffer, Width, Height, out r, out g, out b)
-                   .ThrowIfFailed("Failed to extract color from buffer");
-            return new Color(r, g, b, a);
-        }
-    }
-}
diff --git a/src/Tizen.Multimedia.Util/Utility/ImageDecoder.cs b/src/Tizen.Multimedia.Util/Utility/ImageDecoder.cs
deleted file mode 100644 (file)
index 38de9fe..0000000
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System;
-using System.Threading.Tasks;
-using Native = Interop;
-
-namespace Tizen.Multimedia.Utility
-{
-    /// <summary>
-    /// Image decoder utility
-    /// </summary>
-    public class ImageDecoder : IDisposable
-    {
-        public const ImageColorSpace DefaultColorspace = ImageColorSpace.Rgba8888;
-        public const JpegDownscale DefaultJpegDownscale = JpegDownscale.NoDownscale;
-
-        internal Native.ImageDecoderHandle _handle;
-        private ImageColorSpace _colorspace = DefaultColorspace;
-        private JpegDownscale _jpegDownscale = DefaultJpegDownscale;
-
-        internal ImageDecoder()
-        {
-            _handle = new Native.ImageDecoderHandle();
-        }
-
-        /// <summary>
-        /// Color-space format to decode into, default is <ref>ImageColorspace.Rgba8888</ref>
-        /// </summary>
-        public ImageColorSpace ColorSpace
-        {
-            get { return _colorspace; }
-            set
-            {
-                ValidateObjectNotDisposed();
-                _handle.Colorspace = (Native.ImageColorSpace)value;
-                _colorspace = value;
-            }
-        }
-
-        /// <summary>
-        /// Downscale value at which JPEG image should be decoded.
-        /// </summary>
-        public JpegDownscale Downscale
-        {
-            get { return _jpegDownscale; }
-            set { _jpegDownscale = value; }
-        }
-
-        /// <summary>
-        /// Decode image
-        /// </summary>
-        /// <param name="inputFilePath">Input file path from which to decode</param>
-        /// <returns>Decoded image data</returns>
-        public Task<ImageData> DecodeAsync(string inputFilePath)
-        {
-            ValidateObjectNotDisposed();
-            if (inputFilePath == null) throw new ArgumentNullException("inputFilePath");
-
-            _handle.SetInputPath(inputFilePath).ThrowIfFailed("Failed to set input file path for decoding");
-            return DecodeAsync();
-        }
-
-        /// <summary>
-        /// Decode image
-        /// </summary>
-        /// <param name="inputBuffer">Input buffer from which to decode</param>
-        /// <returns>Decoded image data</returns>
-        public Task<ImageData> DecodeAsync(byte[] inputBuffer)
-        {
-            ValidateObjectNotDisposed();
-            if (inputBuffer == null) throw new ArgumentNullException("inputBuffer");
-
-            _handle.SetInputBuffer(inputBuffer, (ulong)inputBuffer.Length).ThrowIfFailed("Failed to set input buffer for decoding");
-            return DecodeAsync();
-        }
-
-        internal virtual void Initialize()
-        {
-            if (_colorspace != DefaultColorspace)
-            {
-                _handle.Colorspace = (Native.ImageColorSpace)_colorspace;
-            }
-
-            if (_jpegDownscale != DefaultJpegDownscale)
-            {
-                _handle.SetJpegDownscale((Native.JpegDownscale)_jpegDownscale).ThrowIfFailed("Failed to set JPEG Downscale for decoding");
-            }
-        }
-
-        internal Task<ImageData> DecodeAsync()
-        {
-            IntPtr nativeBuffer = IntPtr.Zero;
-            _handle.SetOutputBuffer(out nativeBuffer).ThrowIfFailed("Failed to set output buffer for decoding");
-
-            Initialize();
-
-            TaskCompletionSource<ImageData> tcs = new TaskCompletionSource<ImageData>();
-            Native.ImageDecoderHandle.DecodeCompletedCallback callback = (errorCode, userData, width, height, size) =>
-            {
-                if (errorCode.IsSuccess())
-                {
-                    var decodedImage = new ImageData(nativeBuffer, width, height, (int)size);
-                    tcs.TrySetResult(decodedImage);
-                }
-                else
-                {
-                    tcs.TrySetException(errorCode.GetException("Image decoding failed."));
-                }
-            };
-
-            Native.ImageDecoderHandle.DecodeRunAsync(_handle, callback, IntPtr.Zero).ThrowIfFailed("Failed to decode given image");
-            return Native.PinnedTask(tcs);
-        }
-
-        private void ValidateObjectNotDisposed()
-        {
-            if (_disposedValue)
-            {
-                throw new ObjectDisposedException(GetType().Name);
-            }
-        }
-
-        #region IDisposable Support
-        private bool _disposedValue = false; // To detect redundant calls
-
-        protected virtual void Dispose(bool disposing)
-        {
-            if (!_disposedValue)
-            {
-                _handle.Dispose();
-                _disposedValue = true;
-            }
-        }
-
-        ~ImageDecoder()
-        {
-            Dispose(false);
-        }
-
-        public void Dispose()
-        {
-            Dispose(true);
-            GC.SuppressFinalize(this);
-        }
-        #endregion
-    }
-}
\ No newline at end of file
diff --git a/src/Tizen.Multimedia.Util/Utility/ImageEncoder.cs b/src/Tizen.Multimedia.Util/Utility/ImageEncoder.cs
deleted file mode 100644 (file)
index 5cda946..0000000
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System;
-using System.Threading.Tasks;
-using Native = Interop;
-
-namespace Tizen.Multimedia.Utility
-{
-    /// <summary>
-    /// Image Encoder Utility
-    /// </summary>
-    public class ImageEncoder
-    {
-        public const ImageColorSpace DefaultColorspace = ImageColorSpace.Rgba8888;
-
-        private ImageColorSpace _colorspace = DefaultColorspace;
-        private Size _resolution;
-        private ImageFormat _type;
-
-        internal ImageEncoder(ImageFormat type)
-        {
-            _type = type;
-        }
-
-        /// <summary>
-        /// Color-space format to encode into, default is <ref>ImageColorspace.Rgba8888</ref>
-        /// </summary>
-        public ImageColorSpace ColorSpace
-        {
-            get { return _colorspace; }
-            set { _colorspace = value; }
-        }
-
-        /// <summary>
-        /// Resolution of the encoded image
-        /// </summary>
-        public Size Resolution
-        {
-            get { return _resolution; }
-            set { _resolution = value; }
-        }
-
-        /// <summary>
-        /// Encode image
-        /// </summary>
-        /// <param name="inputBuffer">Input buffer from which to encode</param>
-        /// <returns>Encoded image buffer</returns>
-        public Task<byte[]> EncodeAsync(byte[] inputBuffer)
-        {
-            using (var handle = new Native.ImageEncoderHandle((Native.ImageType)_type))
-            {
-                handle.SetInputBuffer(inputBuffer).ThrowIfFailed("Failed to set input buffer for encoding");
-
-                IntPtr nativeBuffer = IntPtr.Zero;
-                handle.SetOutputBuffer(out nativeBuffer).ThrowIfFailed("Failed to set output buffer for encoding");
-
-                Initialize(handle);
-
-                TaskCompletionSource<byte[]> tcs = new TaskCompletionSource<byte[]>();
-                Native.ImageEncoderHandle.EncodeCompletedCallback callback = (errorCode, userData, size) =>
-                {
-                    if (errorCode.IsSuccess())
-                    {
-                        tcs.TrySetResult(Native.ImageUtil.NativeToByteArray(nativeBuffer, (int)size));
-                    }
-                    else
-                    {
-                        tcs.TrySetException(errorCode.GetException("Image encoding failed."));
-                    }
-                };
-
-                Native.ImageEncoderHandle.EncodeRunAsync(handle, callback, IntPtr.Zero).ThrowIfFailed("Failed to encode given image");
-                return Native.PinnedTask(tcs);
-            }
-        }
-
-        /// <summary>
-        /// Encode image
-        /// </summary>
-        /// <param name="inputBuffer">Input buffer from which to encode</param>
-        /// <param name="outputFilePath">Output path to which to encoded buffer will be written to</param>
-        /// <returns>true if encoding is successful</returns>
-        public Task EncodeAsync(byte[] inputBuffer, string outputFilePath)
-        {
-            using (var handle = new Native.ImageEncoderHandle((Native.ImageType)_type))
-            {
-                handle.SetInputBuffer(inputBuffer).ThrowIfFailed("Failed to set input buffer for encoding");
-                handle.SetOutputPath(outputFilePath).ThrowIfFailed("Failed to set output file path for encoding");
-
-                Initialize(handle);
-
-                TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
-                Native.ImageEncoderHandle.EncodeCompletedCallback callback = (errorCode, userData, size) =>
-                {
-                    if (errorCode.IsSuccess())
-                    {
-                        tcs.TrySetResult(true);
-                    }
-                    else
-                    {
-                        tcs.TrySetException(errorCode.GetException("Image encoding failed."));
-                    }
-                };
-
-                Native.ImageEncoderHandle.EncodeRunAsync(handle, callback, IntPtr.Zero).ThrowIfFailed("Failed to encode given image");
-                return Native.PinnedTask(tcs);
-            }
-        }
-
-        internal virtual void Initialize(Native.ImageEncoderHandle handle)
-        {
-            if (_colorspace != DefaultColorspace)
-            {
-                handle.Colorspace = (Native.ImageColorSpace)_colorspace;
-            }
-
-            if (_resolution.Width != 0 && _resolution.Height != 0)
-            {
-                handle.SetResolution((uint)_resolution.Width, (uint)_resolution.Height);
-            }
-        }
-
-        internal static void ValidateInputRange<T>(T actualValue, T min, T max, string paramName) where T : IComparable<T>
-        {
-            if (min.CompareTo(actualValue) == 1 || max.CompareTo(actualValue) == -1)
-            {
-                throw new ArgumentOutOfRangeException(paramName, actualValue, $"Valid Range [{min} - {max}]");
-            }
-        }
-
-        internal static void ValidateInputRange<T>(T actualValue, Func<bool> verifier, string paramName, string message)
-        {
-            if (verifier() == false)
-            {
-                throw new ArgumentOutOfRangeException(paramName, actualValue, message);
-            }
-        }
-    }
-
-    /// <summary>
-    /// BMP image encoder
-    /// </summary>
-    public class BmpEncoder : ImageEncoder
-    {
-        /// <summary>
-        /// Constructor
-        /// </summary>
-        public BmpEncoder() : base(ImageFormat.Bmp)
-        {
-        }
-    }
-
-    /// <summary>
-    /// JPEG image encoder
-    /// </summary>
-    public class JpegEncoder : ImageEncoder
-    {
-        public const int DefaultQuality = 75;
-        private int _quality = DefaultQuality;
-
-        /// <summary>
-        /// Constructor
-        /// </summary>
-        public JpegEncoder() : base(ImageFormat.Jpeg)
-        {
-        }
-
-        /// <summary>
-        /// Encoding quality from 1~100, default is 75
-        /// </summary>
-        public int Quality
-        {
-            get { return _quality; }
-            set
-            {
-                ValidateInputRange<int>(value, 1, 100, "Quality");
-                _quality = value;
-            }
-        }
-
-        internal override void Initialize(Native.ImageEncoderHandle handle)
-        {
-            if (_quality != DefaultQuality)
-            {
-                base.Initialize(handle);
-                handle.Quality = _quality;
-            }
-        }
-    }
-
-    /// <summary>
-    /// PNG image encoder
-    /// </summary>
-    public class PngEncoder : ImageEncoder
-    {
-        public const PngCompression DefaultPngCompressionLevel = PngCompression.Level6;
-        private PngCompression _pngCompressionLevel = DefaultPngCompressionLevel;
-
-        /// <summary>
-        /// Constructor
-        /// </summary>
-        public PngEncoder() : base(ImageFormat.Png)
-        {
-        }
-
-        /// <summary>
-        /// Compression value of PNG image encoding
-        /// </summary>
-        public PngCompression CompressionLevel
-        {
-            get { return _pngCompressionLevel; }
-            set {_pngCompressionLevel = value; }
-        }
-
-        internal override void Initialize(Native.ImageEncoderHandle handle)
-        {
-            if (_pngCompressionLevel != DefaultPngCompressionLevel)
-            {
-                base.Initialize(handle);
-                handle.PngCompression = (Native.PngCompression)_pngCompressionLevel;
-            }
-        }
-    }
-
-    /// <summary>
-    /// GIF image encoder
-    /// </summary>
-    public class GifEncoder : ImageEncoder
-    {
-        public const int DefaultGifFrameDelay = 0;
-        private ulong _gifFrameDelay = DefaultGifFrameDelay;
-
-        /// <summary>
-        /// Constructor
-        /// </summary>
-        public GifEncoder() : base(ImageFormat.Gif)
-        {
-        }
-
-        /// <summary>
-        /// Time delay between each frame in the encoded image, in 0.01sec units
-        /// </summary>
-        public ulong FrameDelay
-        {
-            get { return _gifFrameDelay; }
-            set { _gifFrameDelay = value; }
-        }
-
-        internal override void Initialize(Native.ImageEncoderHandle handle)
-        {
-            if (_gifFrameDelay != DefaultGifFrameDelay)
-            {
-                base.Initialize(handle);
-                handle.GifFrameDelay = _gifFrameDelay;
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/Tizen.Multimedia.Util/Utility/ImageTransformer.cs b/src/Tizen.Multimedia.Util/Utility/ImageTransformer.cs
deleted file mode 100644 (file)
index 29cbf9b..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System;
-using System.Threading.Tasks;
-using static Interop;
-
-namespace Tizen.Multimedia.Utility
-{
-    public static class ImageTransformer
-    {
-        public static Task<MediaPacket> ConvertColorspaceAsync(this MediaPacket packet, ImageColorSpace colorspace, bool useHardwareAcceleration)
-        {
-            using (var handle = new ImageTransformHandle())
-            {
-                handle.Colorspace = (global::Interop.ImageColorSpace)colorspace;
-                return TransformAsync(handle, packet, useHardwareAcceleration);
-            }
-        }
-
-        public static Task<MediaPacket> ConvertColorspaceAsync(this MediaPacket packet, ImageColorSpace colorspace)
-        {
-            return ConvertColorspaceAsync(packet, colorspace, false);
-        }
-
-        public static Task<MediaPacket> ResizeAsync(this MediaPacket packet, Size resolution, bool useHardwareAcceleration)
-        {
-            using (var handle = new ImageTransformHandle())
-            {
-                handle.SetResolution((uint)resolution.Width, (uint)resolution.Height)
-                      .ThrowIfFailed("Failed to set image resolution for transformation");
-                return TransformAsync(handle, packet, useHardwareAcceleration);
-            }
-        }
-
-        public static Task<MediaPacket> ResizeAsync(this MediaPacket packet, Size resolution)
-        {
-            return ResizeAsync(packet, resolution, false);
-        }
-
-        public static Task<MediaPacket> RotateAsync(this MediaPacket packet, ImageRotation rotation, bool useHardwareAcceleration)
-        {
-            using (var handle = new ImageTransformHandle())
-            {
-                handle.Rotation = (global::Interop.ImageRotation)rotation;
-                return TransformAsync(handle, packet, useHardwareAcceleration);
-            }
-        }
-
-        public static Task<MediaPacket> RotateAsync(this MediaPacket packet, ImageRotation rotation)
-        {
-            return RotateAsync(packet, rotation, false);
-        }
-
-        public static Task<MediaPacket> CropAsync(this MediaPacket packet, Rectangle cropArea, bool useHardwareAcceleration)
-        {
-            using (var handle = new ImageTransformHandle())
-            {
-                handle.SetCropArea(cropArea.X, cropArea.Y, cropArea.X + cropArea.Width, cropArea.Y + cropArea.Height)
-                      .ThrowIfFailed("Failed to set crop area for transformation");
-                return TransformAsync(handle, packet, useHardwareAcceleration);
-            }
-        }
-
-        public static Task<MediaPacket> CropAsync(this MediaPacket packet, Rectangle cropArea)
-        {
-            return CropAsync(packet, cropArea, false);
-        }
-
-        private static Task<MediaPacket> TransformAsync(ImageTransformHandle handle, MediaPacket packet, bool useHardwareAcceleration)
-        {
-            if (useHardwareAcceleration)
-            {
-                handle.HardwareAccelerationEnabled = true;
-            }
-
-            TaskCompletionSource<MediaPacket> tcs = new TaskCompletionSource<MediaPacket>();
-            ImageTransformHandle.TransformCompletedCallback callback = (nativehandle, errorCode, userData) =>
-            {
-                if (errorCode.IsSuccess())
-                {
-                    tcs.TrySetResult(MediaPacket.From(nativehandle));
-                }
-                else
-                {
-                    tcs.TrySetException(errorCode.GetException("Image transformation failed."));
-                }
-            };
-
-            ImageTransformHandle.Transform(handle, packet.GetHandle(), callback, IntPtr.Zero)
-                   .ThrowIfFailed("Failed to transform given packet");
-            return PinnedTask(tcs);
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/Tizen.Multimedia.Util/Utility/ImageUtility.cs b/src/Tizen.Multimedia.Util/Utility/ImageUtility.cs
deleted file mode 100644 (file)
index 7993b4d..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-using System.Collections.Generic;
-using static Interop;
-
-namespace Tizen.Multimedia.Utility
-{
-    /// <summary>
-    /// Image utility class
-    /// </summary>
-    public struct ImageUtility
-    {
-        /// <summary>
-        /// Supported color-space for image encoding/ decoding
-        /// </summary>
-        /// <param name="type">image type</param>
-        /// <returns>Supported color-space</returns>
-        public static IEnumerable<ImageColorSpace> GetSupportedColorspace(ImageFormat type)
-        {
-            var colorspaces = new List<ImageColorSpace>();
-            ImageUtil.ForeachSupportedColorspace((ImageType)type, (colorspace) => colorspaces.Add((ImageColorSpace)colorspace));
-            return colorspaces;
-        }
-
-        /// <summary>
-        /// Calculates the size of the image buffer for the specified resolution and color-space
-        /// </summary>
-        /// <param name="width">Image width</param>
-        /// <param name="height">Image height</param>
-        /// <param name="colorspace">Image color-space</param>
-        /// <returns>Buffer size</returns>
-        public static uint CalculateBufferSize(int width, int height, ImageColorSpace colorspace)
-        {
-            uint bufferSize;
-            ImageUtil.CalculateBufferSize(width, height, (global::Interop.ImageColorSpace)colorspace, out bufferSize)
-                   .ThrowIfFailed("Failed to calculate buffer size for given parameter");
-            return bufferSize;
-        }
-    }
-}
diff --git a/src/Tizen.Multimedia/Common.Internal/FileUtil.cs b/src/Tizen.Multimedia/Common.Internal/FileUtil.cs
new file mode 100644 (file)
index 0000000..2b3e6f5
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.IO;
+
+namespace Tizen.Multimedia
+{
+    internal static class FileUtil
+    {
+        public static bool HasReadPermission(string path)
+        {
+            return Access(path, Interop.Libc.AccessMode.R_OK);
+        }
+
+        public static bool HasWritePermission(string path)
+        {
+
+            return Access(Path.GetDirectoryName(path), Interop.Libc.AccessMode.W_OK);
+        }
+
+        private static bool Access(string path, int mode)
+        {
+            if (path == null)
+            {
+                throw new ArgumentNullException(nameof(path));
+            }
+            return Interop.Libc.Access(path, mode) == 0;
+        }
+    }
+}
diff --git a/src/Tizen.Multimedia/Common/ColorSpace.cs b/src/Tizen.Multimedia/Common/ColorSpace.cs
new file mode 100644 (file)
index 0000000..edbb001
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Multimedia
+{
+    /// <summary>
+    /// Specifies color spaces for Tizen.Multimedia.
+    /// </summary>
+    public enum ColorSpace
+    {
+        /// <summary>
+        /// Y800
+        /// </summary>
+        Y800,
+
+        /// <summary>
+        /// I420
+        /// </summary>
+        I420,
+
+        /// <summary>
+        /// NV12
+        /// </summary>
+        NV12,
+
+        /// <summary>
+        /// NV16
+        /// </summary>
+        NV16,
+
+        /// <summary>
+        /// NV21
+        /// </summary>
+        NV21,
+
+        /// <summary>
+        /// NV61
+        /// </summary>
+        NV61,
+
+        /// <summary>
+        /// YV12
+        /// </summary>
+        ///
+        YV12,
+
+        /// <summary>
+        /// YUYV
+        /// </summary>
+        Yuyv,
+
+        /// <summary>
+        /// YUV422
+        /// </summary>
+        Yuv422,
+
+        /// <summary>
+        /// UYVY
+        /// </summary>
+        Uyvy,
+
+        /// <summary>
+        /// YUV422P
+        /// </summary>
+        ///
+        Yuv422P,
+
+        /// <summary>
+        /// RGB565
+        /// </summary>
+        Rgb565,
+
+        /// <summary>
+        /// RGB888
+        /// </summary>
+        Rgb888,
+
+        /// <summary>
+        /// RGBA8888
+        /// </summary>
+        Rgba8888,
+
+        /// <summary>
+        /// ARGB8888
+        /// </summary>
+        Argb8888,
+
+        /// <summary>
+        /// BGRA8888
+        /// </summary>
+        Bgra8888,
+
+        /// <summary>
+        /// BGRX8888
+        /// </summary>
+        Bgrx8888
+
+    }
+}
index 40b5b52..28d1485 100644 (file)
@@ -94,6 +94,26 @@ namespace Tizen.Multimedia
         }
 
         /// <summary>
+        /// Gets the x-coordinate of the left edge of the rectangle.
+        /// </summary>
+        public int Left => X;
+
+        /// <summary>
+        /// Gets the y-coordinate of the top edge of the rectangle.
+        /// </summary>
+        public int Top => Y;
+
+        /// <summary>
+        /// Gets the x-coordinate of the right edge of the rectangle.
+        /// </summary>
+        public int Right => X + Width;
+
+        /// <summary>
+        /// Gets the y-coordinate of the bottom edge of the rectangle.
+        /// </summary>
+        public int Bottom => Y + Height;
+
+        /// <summary>
         /// Gets or sets the size of the rectangle.
         /// </summary>
         public Size Size
index 9903e0b..7e9cb41 100644 (file)
@@ -7,8 +7,19 @@ namespace Tizen.Multimedia
     {
         internal static partial class Libc
         {
+            internal static class AccessMode
+            {
+                internal const int W_OK = 0x02;
+                internal const int R_OK = 0x04;
+            }
+
             [DllImport(Libraries.Libc, EntryPoint = "free")]
             public static extern void Free(IntPtr ptr);
+
+
+
+            [DllImport(Libraries.Libc, EntryPoint = "access")]
+            public static extern int Access(string path, int mode);
         }
     }
 }
\ No newline at end of file