Release 4.0.0-preview1-00051
[platform/core/csapi/tizenfx.git] / src / Tizen.Multimedia.Vision / MediaVision / BarcodeDetector.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.Collections.Generic;
19 using System.Threading.Tasks;
20 using InteropBarcode = Interop.MediaVision.BarcodeDetector;
21 using Unmanaged = Interop.MediaVision;
22
23 namespace Tizen.Multimedia
24 {
25     /// <summary>
26     /// Provides the ability to detect barcodes on image sources.
27     /// </summary>
28     /// <since_tizen> 3</since_tizen>
29     public static class BarcodeDetector
30     {
31         /// <summary>
32         /// Detects barcodes on source and reads message from it.
33         /// </summary>
34         /// <param name="source">The <see cref="MediaVisionSource"/> instance.</param>
35         /// <param name="roi">Region of interest - rectangular area on the source which will be used for
36         ///     barcode detection. Note that roi should be inside area on the source.</param>
37         /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
38         /// <exception cref="NotSupportedException">The feature is not supported.</exception>
39         /// <exception cref="ObjectDisposedException"><paramref name="source"/> already has been disposed of.</exception>
40         /// <returns>A task that represents the asynchronous detect operation.</returns>
41         /// <seealso cref="Barcode"/>
42         /// <since_tizen> 3</since_tizen>
43         public static async Task<IEnumerable<Barcode>> DetectAsync(MediaVisionSource source,
44             Rectangle roi)
45         {
46             return await DetectAsync(source, roi, null);
47         }
48
49         /// <summary>
50         /// Detects barcodes on source and reads message from it with <see cref="BarcodeDetectionConfiguration"/>.
51         /// </summary>
52         /// <param name="source">The <see cref="MediaVisionSource"/> instance.</param>
53         /// <param name="roi">Region of interest - rectangular area on the source which will be used for
54         ///     barcode detection. Note that roi should be inside area on the source.</param>
55         /// <param name="config">The configuration of the barcode detector. This value can be null.</param>
56         /// <returns>A task that represents the asynchronous detect operation.</returns>
57         /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
58         /// <exception cref="NotSupportedException">The feature is not supported.</exception>
59         /// <exception cref="ObjectDisposedException">
60         ///     <paramref name="source"/> already has been disposed of.\n
61         ///     -or-\n
62         ///     <paramref name="config"/> already has been disposed of.
63         /// </exception>
64         /// <seealso cref="Barcode"/>
65         /// <since_tizen> 3</since_tizen>
66         public static async Task<IEnumerable<Barcode>> DetectAsync(MediaVisionSource source,
67             Rectangle roi, BarcodeDetectionConfiguration config)
68         {
69             if (source == null)
70             {
71                 throw new ArgumentNullException(nameof(source));
72             }
73
74             var tcs = new TaskCompletionSource<IEnumerable<Barcode>>();
75
76             using (var cb = ObjectKeeper.Get(GetCallback(tcs)))
77             {
78                 InteropBarcode.Detect(source.Handle, EngineConfiguration.GetHandle(config),
79                     roi.ToMarshalable(), cb.Target).Validate("Failed to detect barcode.");
80
81                 return await tcs.Task;
82             }
83         }
84
85         private static Barcode[] CreateBarcodes(Unmanaged.Quadrangle[] locations, string[] messages,
86             BarcodeType[] types, int numberOfBarcodes)
87         {
88             Barcode[] barcodes = new Barcode[numberOfBarcodes];
89
90             for (int i = 0; i < numberOfBarcodes; i++)
91             {
92                 barcodes[i] = new Barcode(locations[i].ToApiStruct(), messages[i], types[i]);
93
94                 Log.Info(MediaVisionLog.Tag, barcodes[i].ToString());
95             }
96
97             return barcodes;
98         }
99
100         private static InteropBarcode.DetectedCallback GetCallback(TaskCompletionSource<IEnumerable<Barcode>> tcs)
101         {
102             return (IntPtr mvSource, IntPtr engineCfg, Unmanaged.Quadrangle[] locations, string[] messages,
103                 BarcodeType[] types, int numberOfBarcodes, IntPtr userData) =>
104             {
105                 Log.Info(MediaVisionLog.Tag, $"Barcodes detected, count : {numberOfBarcodes}");
106
107                 try
108                 {
109                     tcs.TrySetResult(CreateBarcodes(locations, messages, types, numberOfBarcodes));
110                 }
111                 catch (Exception e)
112                 {
113                     MultimediaLog.Error(MediaVisionLog.Tag, "Failed to handle barcode detection callback", e);
114                     tcs.TrySetException(e);
115                 }
116             };
117         }
118     }
119 }