[ImageUtil] Replace deprecated decode pinvoke func. (#929)
[platform/core/csapi/tizenfx.git] / src / Tizen.Multimedia.Util / ImageUtil / ImageTransform.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 using System;
18 using System.Diagnostics;
19 using System.Runtime.InteropServices;
20 using System.Threading.Tasks;
21 using static Interop;
22 using NativeTransform = Interop.ImageUtil.Transform;
23
24 namespace Tizen.Multimedia.Util
25 {
26     /// <summary>
27     /// A base class for image transformations.
28     /// </summary>
29     /// <since_tizen> 4 </since_tizen>
30     public abstract class ImageTransform
31     {
32         internal ImageTransform()
33         {
34         }
35
36         internal async Task<MediaPacket> RunAsync(TransformHandle handle, MediaPacket source)
37         {
38             Debug.Assert(source.Format is VideoMediaFormat);
39             ValidateFormat(source.Format as VideoMediaFormat);
40
41             var tcs = new TaskCompletionSource<MediaPacket>();
42
43             using (var cbKeeper = ObjectKeeper.Get(GetCallback(tcs, source)))
44             {
45                 var result = NativeTransform.Run(handle, source.GetHandle(), cbKeeper.Target);
46
47                 if (result == ImageUtilError.NotSupportedFormat)
48                 {
49                     throw new NotSupportedException(
50                         GenerateNotSupportedErrorMessage(source.Format as VideoMediaFormat));
51                 }
52                 result.ThrowIfFailed("Failed to transform given packet with " + GetType());
53
54                 return await tcs.Task;
55             }
56         }
57
58         private NativeTransform.TransformCompletedCallback GetCallback(TaskCompletionSource<MediaPacket> tcs,
59             MediaPacket source)
60         {
61             return (nativehandle, errorCode, _) =>
62             {
63                 if (errorCode == ImageUtilError.None)
64                 {
65                     try
66                     {
67                         tcs.TrySetResult(MediaPacket.From(Marshal.PtrToStructure<IntPtr>(nativehandle)));
68                     }
69                     catch (Exception e)
70                     {
71                         tcs.TrySetException(e);
72                     }
73                 }
74                 else if (errorCode == ImageUtilError.NotSupportedFormat)
75                 {
76                     tcs.TrySetException(new NotSupportedException(
77                         GenerateNotSupportedErrorMessage(source.Format as VideoMediaFormat)));
78                 }
79                 else
80                 {
81                     tcs.TrySetException(errorCode.ToException("Image transformation failed"));
82                 }
83             };
84         }
85
86         internal static TransformHandle CreateHandle()
87         {
88             NativeTransform.Create(out var handle).ThrowIfFailed("Failed to run ImageTransformer");
89             Debug.Assert(handle != null);
90             return handle;
91         }
92
93         internal abstract string GenerateNotSupportedErrorMessage(VideoMediaFormat format);
94
95         internal abstract void Configure(TransformHandle handle);
96
97         internal virtual void ValidateFormat(VideoMediaFormat format)
98         {
99         }
100
101         internal virtual async Task<MediaPacket> ApplyAsync(MediaPacket source)
102         {
103             using (TransformHandle handle = CreateHandle())
104             {
105                 Configure(handle);
106
107                 return await RunAsync(handle, source);
108             }
109         }
110     }
111 }