[NUI] Support EncodedImageBuffer ImageType property + Upgrade EncodedImageBuffer...
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / public / Images / EncodedImageBuffer.cs
1 /*
2  * Copyright(c) 2021 Samsung Electronics Co., Ltd.
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.ComponentModel;
20
21 namespace Tizen.NUI
22 {
23     using global::System;
24     using global::System.ComponentModel;
25     using global::System.Runtime.InteropServices;
26
27     /// <summary>
28     /// Class for Encoded Image Buffer.
29     /// Buffer comes from System.IO.Stream.
30     /// This data will decode internally when you use GeneratedUrl as View's ResourceUrl.
31     /// Note: This class doesn't allow to fix/change anything.
32     /// Only constructor allow to setup data.
33     /// </summary>
34     /// <remarks>Hidden API: Only for inhouse or developing usage. The behavior and interface can be changed anytime.</remarks>
35     [EditorBrowsable(EditorBrowsableState.Never)]
36     public class EncodedImageBuffer : BaseHandle
37     {
38         private VectorUnsignedChar mCachedBuffer = null; // cached encoded raw buffer
39
40         /// <summary>
41         /// The list of type of encoded image buffer.
42         /// It will be used when we want to specify the buffer data type.
43         /// </summary>
44         /// <remarks>Hidden API: Only for inhouse or developing usage. The behavior and interface can be changed anytime.</remarks>
45         [EditorBrowsable(EditorBrowsableState.Never)]
46         [System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1717:Only FlagsAttribute enums should have plural names")]
47         public enum ImageTypes
48         {
49             /// <summary>
50             /// Regular images.
51             /// </summary>
52             /// <remarks>Hidden API: Only for inhouse or developing usage. The behavior and interface can be changed anytime.</remarks>
53             [EditorBrowsable(EditorBrowsableState.Never)]
54             RegularImage = 0,
55
56             /// <summary>
57             /// Vector rasterize images.
58             /// </summary>
59             /// <remarks>Hidden API: Only for inhouse or developing usage. The behavior and interface can be changed anytime.</remarks>
60             [EditorBrowsable(EditorBrowsableState.Never)]
61             VectorImage,
62
63             /// <summary>
64             /// Animated vector rasterize images.
65             /// </summary>
66             /// <remarks>Hidden API: Only for inhouse or developing usage. The behavior and interface can be changed anytime.</remarks>
67             [EditorBrowsable(EditorBrowsableState.Never)]
68             AnimatedVectorImage,
69         }
70
71         /// <summary>
72         /// Constructor.
73         /// </summary>
74         /// <param name="stream">The Stream of the image file.</param>
75         /// <exception cref="ArgumentNullException"> Thrown when stream is null. </exception>
76         /// <exception cref="InvalidOperationException"> Thrown when stream don't have any data. </exception>
77         /// <remarks>Hidden API: Only for inhouse or developing usage. The behavior and interface can be changed anytime.</remarks>
78         [EditorBrowsable(EditorBrowsableState.Never)]
79         public EncodedImageBuffer(System.IO.Stream stream) : this(GetRawBuffrFromStreamHelper(stream), ImageTypes.RegularImage)
80         {
81             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
82         }
83
84         /// <summary>
85         /// Constructor with image type.
86         /// </summary>
87         /// <param name="stream">The Stream of the image file.</param>
88         /// <param name="imageType">The type of the image stream.</param>
89         /// <exception cref="ArgumentNullException"> Thrown when stream is null. </exception>
90         /// <exception cref="InvalidOperationException"> Thrown when stream don't have any data. </exception>
91         /// <remarks>Hidden API: Only for inhouse or developing usage. The behavior and interface can be changed anytime.</remarks>
92         [EditorBrowsable(EditorBrowsableState.Never)]
93         public EncodedImageBuffer(System.IO.Stream stream, ImageTypes imageType) : this(GetRawBuffrFromStreamHelper(stream), imageType)
94         {
95             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
96         }
97
98         internal EncodedImageBuffer(VectorUnsignedChar buffer, ImageTypes imageType) : this(Interop.EncodedImageBuffer.New(VectorUnsignedChar.getCPtr(buffer), (int)imageType), true)
99         {
100             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
101             mCachedBuffer = buffer;
102         }
103
104         internal EncodedImageBuffer(global::System.IntPtr cPtr, bool cMemoryOwn) : this(cPtr, cMemoryOwn, false)
105         {
106             // Note : EncodedImageBuffer don't need to be register in Registry default. So we can create this class from worker thread.
107         }
108
109         internal EncodedImageBuffer(global::System.IntPtr cPtr, bool cMemoryOwn, bool cRegister) : base(cPtr, cMemoryOwn, cRegister)
110         {
111         }
112
113         /// <summary>
114         /// The type of image for this EncodedImageBuffer.
115         /// </summary>
116         /// <remarks>Hidden API: Only for inhouse or developing usage. The behavior and interface can be changed anytime.</remarks>
117         [EditorBrowsable(EditorBrowsableState.Never)]
118         public ImageTypes ImageType
119         {
120             set
121             {
122                 Interop.EncodedImageBuffer.SetImageType(SwigCPtr, (int)value);
123                 NDalicPINVOKE.ThrowExceptionIfExists();
124             }
125             get
126             {
127                 ImageTypes ret = (ImageTypes)Interop.EncodedImageBuffer.GetImageType(SwigCPtr);
128                 NDalicPINVOKE.ThrowExceptionIfExists();
129                 return ret;
130             }
131         }
132
133         /// <summary>
134         /// Generate URI from current buffer.
135         /// We can now use this url for ImageView.ResourceUrl
136         /// Note : the url lifecycle is same as ImageUrl and it's internal usage.
137         /// Store only ImageUrl.ToString() result and re-use that url is Undefined Behavior.
138         /// </summary>
139         /// <remarks>
140         /// This API should not be called at worker thread.
141         /// </remarks>
142         /// <remarks>Hidden API: Only for inhouse or developing usage. The behavior and interface can be changed anytime.</remarks>
143         [EditorBrowsable(EditorBrowsableState.Never)]
144         public ImageUrl GenerateUrl()
145         {
146             return new ImageUrl(Interop.EncodedImageBuffer.GenerateUrl(this.SwigCPtr.Handle), true);
147         }
148
149         /// <summary>
150         /// Get current raw buffer. (read-only)
151         /// Note : the raw buffer doesn't have memory ownership.
152         /// Access to write something to raw buffer is Undefined Behavior.
153         /// </summary>
154         /// This will not be public opened.
155         internal VectorUnsignedChar GetRawBuffer()
156         {
157             mCachedBuffer ??= new VectorUnsignedChar(Interop.EncodedImageBuffer.GetRawBuffer(this.SwigCPtr.Handle), false);
158             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
159             return mCachedBuffer;
160         }
161
162         /// <summary>
163         /// Dispose
164         /// </summary>
165         /// <param name="type"></param>
166         [EditorBrowsable(EditorBrowsableState.Never)]
167         protected override void Dispose(DisposeTypes type)
168         {
169             if (disposed)
170             {
171                 return;
172             }
173
174             if (type == DisposeTypes.Explicit)
175             {
176                 //Called by User
177                 //Release your own managed resources here.
178                 //You should release all of your own disposable objects here.
179                 mCachedBuffer?.Dispose();
180             }
181
182             base.Dispose(type);
183         }
184
185         /// This will not be public opened.
186         [EditorBrowsable(EditorBrowsableState.Never)]
187         protected override void ReleaseSwigCPtr(HandleRef swigCPtr)
188         {
189             Interop.EncodedImageBuffer.DeleteEncodedImageBuffer(swigCPtr);
190             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
191         }
192
193         /// <summary>
194         /// Get VectorUnsignedChar from System.IO.Stream.
195         /// This funcion exist only for Constructor.
196         /// </summary>
197         /// This will not be public opened.
198         private static VectorUnsignedChar GetRawBuffrFromStreamHelper(System.IO.Stream stream)
199         {
200             if(stream == null)
201             {
202                 throw new ArgumentNullException(nameof(stream));
203             }
204             if(!stream.CanRead)
205             {
206                 throw new InvalidOperationException("stream don't support to read");
207             }
208
209             // Copy stream to memoryStream
210             System.IO.MemoryStream memoryStream = new System.IO.MemoryStream();
211             stream.CopyTo(memoryStream);
212             memoryStream.Seek(0, System.IO.SeekOrigin.Begin);
213
214             long streamLength = memoryStream.Length;
215             if(streamLength <= 0)
216             {
217                 throw new InvalidOperationException("stream length is <= 0");
218             }
219
220             // Allocate buffer that internal DALi engine can read
221             VectorUnsignedChar buffer = new VectorUnsignedChar();
222
223             buffer.Resize((uint)streamLength);
224             var bufferBegin = buffer.Begin();
225             global::System.Runtime.InteropServices.HandleRef bufferRef = SWIGTYPE_p_unsigned_char.getCPtr(bufferBegin);
226
227             // Copy data from memoryStream to buffer
228             System.Runtime.InteropServices.Marshal.Copy(memoryStream.GetBuffer(), 0, bufferRef.Handle, (int)streamLength);
229
230             memoryStream.Dispose();
231
232             return buffer;
233         }
234     }
235 }