[MetadataEditor/MetadataExtractor/ThumbnailExtractor] Apply C# coding rule
[platform/core/csapi/tizenfx.git] / src / Tizen.Multimedia / ThumbnailExtractor / ThumbnailExtractor.cs
1 /*
2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3 *
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17
18 using System;
19 using System.Threading.Tasks;
20 using System.Runtime.InteropServices;
21
22 namespace Tizen.Multimedia
23 {
24     static internal class ThumbnailExtractorLog
25     {
26         internal const string LogTag = "Tizen.Multimedia.ThumbnailExtractor";
27     }
28
29     /// <summary>
30     /// The Thumbnail extractor class provides a set of functions to extract the thumbnail data of the input media file
31     /// </summary>
32     public class ThumbnailExtractor : IDisposable
33     {
34         private bool _disposed = false;
35         internal IntPtr _handle = IntPtr.Zero;
36
37         /// <summary>
38         /// Thumbnail extractor constructor
39         /// </summary>
40         /// <remarks>
41         /// If you need the thumbnail of the specified size, use ThumbnailExtractor(path, width, height) or ThumbnailExtractor(path, size).
42         /// </remarks>
43         /// <param name="path"> The path of the media file to extract the thumbnail </param>
44         /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
45         public ThumbnailExtractor(string path)
46         {
47             if (path == null)
48             {
49                 throw new ArgumentNullException(nameof(path));
50             }
51
52             ThumbnailExtractorError ret = Interop.ThumbnailExtractor.Create(out _handle);
53             ThumbnailExtractorErrorFactory.ThrowIfError(ret, "Failed to create constructor");
54
55             try
56             {
57                 ThumbnailExtractorErrorFactory.ThrowIfError(
58                     Interop.ThumbnailExtractor.SetPath(_handle, path), "Failed to set the path");
59             }
60             catch (Exception)
61             {
62                 Interop.ThumbnailExtractor.Destroy(_handle);
63                 _handle = IntPtr.Zero;
64                 throw;
65             }
66         }
67
68         private void Create(String path, int width, int height)
69         {
70             if (path == null)
71             {
72                 throw new ArgumentNullException(nameof(path));
73             }
74
75             if (width <= 0)
76             {
77                 throw new ArgumentOutOfRangeException(nameof(width), "The width must be greater than zero:[" + width + "]");
78             }
79
80             if (height <= 0)
81             {
82                 throw new ArgumentOutOfRangeException(nameof(height), "The height must be greater than zero:[" + height + "]");
83             }
84
85             ThumbnailExtractorError ret = Interop.ThumbnailExtractor.Create(out _handle);
86             ThumbnailExtractorErrorFactory.ThrowIfError(ret, "Failed to create constructor");
87
88             try
89             {
90                 ThumbnailExtractorErrorFactory.ThrowIfError(
91                     Interop.ThumbnailExtractor.SetPath(_handle, path), "Failed to set the path");
92
93                 ThumbnailExtractorErrorFactory.ThrowIfError(
94                     Interop.ThumbnailExtractor.SetSize(_handle, width, height), "Failed to set the size");
95             }
96             catch (Exception)
97             {
98                 Interop.ThumbnailExtractor.Destroy(_handle);
99                 _handle = IntPtr.Zero;
100                 throw;
101             }
102         }
103
104         /// <summary>
105         /// Thumbnail extractor constructor
106         /// </summary>
107         /// <remarks>
108         /// If you need the thumbnail of the default size, use ThumbnailExtractor(path). The default size is 320x240. \n
109         /// If the set width is not a multiple of 8, it can be changed by inner process. \n
110         /// The width will be a multiple of 8 greater than the set value.
111         /// </remarks>
112         /// <param name="path"> The path of the media file to extract the thumbnail </param>
113         /// <param name="width"> The width of the thumbnail </param>
114         /// <param name="height"> The height of the thumbnail </param>
115         /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
116         /// <exception cref="ArgumentOutOfRangeException">
117         /// <paramref name="width"/> or <paramref name="height"/> is less than zero.
118         /// </exception>
119         public ThumbnailExtractor(string path, int width, int height)
120         {
121             Create(path, width, height);
122         }
123
124         /// <summary>
125         /// Thumbnail extractor constructor
126         /// </summary>
127         /// <remarks>
128         /// If you need the thumbnail of the default size, use ThumbnailExtractor(path). The default size is 320x240. \n
129         /// If the set width is not a multiple of 8, it can be changed by inner process. \n
130         /// The width will be a multiple of 8 greater than the set value.
131         /// </remarks>
132         /// <param name="path"> The path of the media file to extract the thumbnail </param>
133         /// <param name="size"> The size to extract the thumbnail </param>
134         /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
135         /// <exception cref="ArgumentOutOfRangeException">
136         /// A value of <paramref name="size"/> is less than zero.
137         /// </exception>
138         public ThumbnailExtractor(string path, Size size)
139         {
140             Create(path, size.Width, size.Height);
141         }
142
143         /// <summary>
144         /// Extracts the thumbnail for the given media, asynchronously
145         /// </summary>
146         /// <returns>
147         /// Task for creation of Thumbnail. See <see cref="ThumbnailData"/> details.
148         /// </returns>
149         /// <exception cref="ArgumentException">Requested <paramref name="path"/> does not exist.</exception>
150         /// <exception cref="OutOfMemoryException">Memory allocation failed.</exception>
151         /// <exception cref="InvalidOperationException">Internal processing failed.</exception>
152         /// <exception cref="UnauthorizedAccessException">Inaccessible for the requested <paramref name="path"/>.</exception>
153         public Task<ThumbnailData> Extract()
154         {
155             if (_handle == IntPtr.Zero)
156             {
157                 throw new ObjectDisposedException(nameof(ThumbnailExtractor), "Failed to extract thumbnail");
158             }
159
160             var task = new TaskCompletionSource<ThumbnailData>();
161
162             Interop.ThumbnailExtractor.ThumbnailExtractCallback extractCallback = (ThumbnailExtractorError error,
163                                                                                 string requestId,
164                                                                                 int thumbWidth,
165                                                                                 int thumbHeight,
166                                                                                 IntPtr thumbData,
167                                                                                 int thumbSize,
168                                                                                 IntPtr userData) =>
169             {
170                 if (error == ThumbnailExtractorError.None)
171                 {
172                     try
173                     {
174                         byte[] tmpBuf = new byte[thumbSize];
175                         Marshal.Copy(thumbData, tmpBuf, 0, thumbSize);
176
177                         task.SetResult(new ThumbnailData(tmpBuf, thumbWidth, thumbHeight));
178                     }
179                     catch (Exception)
180                     {
181                         task.SetException(new InvalidOperationException("[" + error + "] Fail to copy data"));
182                     }
183                     finally
184                     {
185                         Interop.Libc.Free(thumbData);
186                     }
187                 }
188                 else
189                 {
190                     task.SetException(new InvalidOperationException("[" + error + "] Fail to create thumbnail"));
191                 }
192             };
193
194             IntPtr id = IntPtr.Zero;
195             ThumbnailExtractorError res = Interop.ThumbnailExtractor.Extract(_handle, extractCallback, IntPtr.Zero, out id);
196             if (id != IntPtr.Zero)
197             {
198                 Interop.Libc.Free(id);
199                 id = IntPtr.Zero;
200             }
201
202             ThumbnailExtractorErrorFactory.ThrowIfError(res, "Failed to extract thumbnail");
203
204             return task.Task;
205         }
206
207         /// <summary>
208         /// Thumbnail Utility destructor
209         /// </summary>
210         ~ThumbnailExtractor()
211         {
212             Dispose(false);
213         }
214
215         protected virtual void Dispose(bool disposing)
216         {
217             if (!_disposed)
218             {
219                 if (disposing)
220                 {
221                     // To be used if there are any other disposable objects
222                 }
223
224                 if (_handle != IntPtr.Zero)
225                 {
226                     Interop.ThumbnailExtractor.Destroy(_handle);
227                     _handle = IntPtr.Zero;
228                 }
229
230                 _disposed = true;
231             }
232         }
233
234         public void Dispose()
235         {
236             Dispose(true);
237             GC.SuppressFinalize(this);
238         }
239     }
240 }