Tizen 2.1 base
[apps/native/sample/FaceTracker.git] / project / src / FaceTrackerForm.cpp
1 //
2 // Tizen C++ SDK
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Flora License, Version 1.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.tizenopensource.org/license
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an AS IS BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 #include <FApp.h>
19 #include "FaceTrackerForm.h"
20
21 #define SAFE_DELETE(x)  if (x) { delete x; x = null; }
22
23 using namespace Tizen::Base;
24 using namespace Tizen::Base::Collection;
25 using namespace Tizen::System;
26 using namespace Tizen::App;
27 using namespace Tizen::Ui;
28 using namespace Tizen::Ui::Controls;
29 using namespace Tizen::Graphics;
30 using namespace Tizen::Uix::Vision;
31 using namespace Tizen::Media;
32
33 static const int X_OFFSET_FOR_CANVAS = 30;
34 static const int Y_OFFSET_FOR_CAMVAS = 30;
35 static const int PREVIEW_WIDTH = 320;
36 static const int PREVIEW_HEIGHT = 240;
37 static const int LINE_WIDTH = 4;
38 static const unsigned int FG_COLOR = 0xFF0000FF;
39 static const int FONT_SIZE = 40;
40
41 FaceTrackerForm::FaceTrackerForm(void)
42         : __pFaceDetector(null)
43         , __pFaceRecognizer(null)
44         , __pFaceData(null)
45         , __pFInfoReference(null)
46         , __pOverlayRegion(null)
47         , __pCanvas(null)
48         , __pPanel(null)
49         , __pCamera(null)
50         , __pFaceThread(null)
51         , __isCameraOn(false)
52 {
53 }
54
55 FaceTrackerForm::~FaceTrackerForm(void)
56 {
57         __pFaceThread->Stop();
58         __pFaceThread->Join();
59         SAFE_DELETE(__pFaceThread);
60         SAFE_DELETE(__pCamera);
61         SAFE_DELETE(__pOverlayRegion);
62         SAFE_DELETE(__pCanvas);
63         SAFE_DELETE(__pFaceDetector);
64         SAFE_DELETE(__pFaceRecognizer);
65         SAFE_DELETE(__pFInfoReference);
66         SAFE_DELETE(__pFaceData);
67 }
68
69 bool
70 FaceTrackerForm::Initialize(void)
71 {
72         Construct(L"IDF_FORM");
73
74         return true;
75 }
76
77 result
78 FaceTrackerForm::OnInitializing(void)
79 {
80         result r = E_SUCCESS;
81
82         int width = 0;
83         int height = 0;
84         FaceBuffer *pFaceBuffer = null;
85         Font font;
86         ByteBuffer *pBuffer = null;
87         Bitmap *pBitmap = null;
88         Label *pLabel = null;
89
90         __rect = GetClientAreaBounds();
91         Rectangle rect(__rect.x + X_OFFSET_FOR_CANVAS, Y_OFFSET_FOR_CAMVAS, PREVIEW_WIDTH, PREVIEW_HEIGHT);
92
93         __pFaceDetector = new (std::nothrow) FaceDetector();
94         TryReturn(__pFaceDetector != null, E_FAILURE, "Failed to create FaceDetector");
95         r = __pFaceDetector->Construct();
96         TryReturn(r == E_SUCCESS, E_FAILURE, "Failed to construct FaceDetector");
97
98         __pFaceRecognizer = new (std::nothrow) FaceRecognizer();
99         TryReturn(__pFaceRecognizer != null, E_FAILURE, "Failed to create FaceRecognizer");
100         r = __pFaceRecognizer->Construct();
101         TryReturn(r == E_SUCCESS, E_FAILURE, "Failed to construct FaceRecognizer");
102
103         __pFaceData = new (std::nothrow) FaceData();
104         TryReturn(__pFaceData != null, E_FAILURE, "Failed to create FaceData");
105
106         Image *pImage = new (std::nothrow) Image();
107         TryReturn(pImage != null, E_FAILURE, "Failed to create Image");
108         r = pImage->Construct();
109         TryCatch(r == E_SUCCESS, r = E_FAILURE, "Failed to construct Image");
110
111         pBuffer = pImage->DecodeToBufferN(Tizen::App::App::GetInstance()->GetAppRootPath()+L"res/sample1.bmp", BITMAP_PIXEL_FORMAT_RGB565,width,height);
112         SAFE_DELETE(pImage);
113
114         pBitmap = new (std::nothrow) Bitmap();
115         TryReturn(pBitmap != null, E_FAILURE, "Failed to create Bitmap");
116         r = pBitmap->Construct(*pBuffer, Dimension(width, height),BITMAP_PIXEL_FORMAT_RGB565 );
117         TryCatch(r == E_SUCCESS, r = E_FAILURE, "Failed to construct Bitmap");
118
119         pLabel = new (std::nothrow) Label();
120         TryCatch(pLabel != null, r = E_FAILURE, "Failed to create Label");
121         r = pLabel->Construct(Rectangle(__rect.width - X_OFFSET_FOR_CANVAS - PREVIEW_WIDTH, Y_OFFSET_FOR_CAMVAS, PREVIEW_WIDTH, PREVIEW_HEIGHT), L"");
122         TryCatch(r == E_SUCCESS, r = E_FAILURE, "Failed to construct Label");
123
124         pLabel->SetBackgroundBitmap(*pBitmap);
125         AddControl(*pLabel);
126         SAFE_DELETE(pBitmap);
127
128         pFaceBuffer = __pFaceDetector->PreprocessDataN(*pBuffer, Dimension(width, height), PIXEL_FORMAT_RGB565);
129         if (pFaceBuffer != null)
130         {
131                 IList *pFaceDetectList = __pFaceDetector->DetectFacesN(*pFaceBuffer, FACE_DETECTION_OPTION_FAST);
132                 if (pFaceDetectList != null)
133                 {
134                         if (pFaceDetectList->GetCount() > 0)
135                         {
136                                 Rectangle *pFaceRect = (Tizen::Graphics::Rectangle*)pFaceDetectList->GetAt(0);
137                                 FaceComponentsPosition* pFaceComponents = __pFaceDetector->ExtractFaceComponentsN(*pFaceBuffer, *pFaceRect);
138                                 if(pFaceComponents)
139                                 {
140                                         ByteBuffer*  pFeatureBuffer = __pFaceRecognizer->ExtractFeatureN(*pFaceBuffer,*pFaceComponents);
141                                         if (pFeatureBuffer != null)
142                                         {
143                                                 __pFInfoReference = new (std::nothrow) FaceRecognitionInfo();
144                                                 if (__pFInfoReference != null)
145                                                 {
146                                                         r = __pFInfoReference->Construct(*pFeatureBuffer);
147                                                 }
148                                                 SAFE_DELETE(pFeatureBuffer);
149                                         }
150                                         SAFE_DELETE(pFaceComponents);
151                                 }
152                         }
153                         pFaceDetectList->RemoveAll(true);
154                         SAFE_DELETE(pFaceDetectList);
155                 }
156                 SAFE_DELETE(pFaceBuffer);
157         }
158         if (__pFInfoReference == null || r != E_SUCCESS)
159         {
160                 return E_FAILURE;
161         }
162         
163         __pPanel = new (std::nothrow) Panel();
164         TryReturn(__pPanel != null, E_FAILURE, "Failed to create Panel");
165         r = __pPanel->Construct(rect);
166         TryReturn(r == E_SUCCESS, E_FAILURE, "Failed to construct Panel");
167         AddControl(*__pPanel);
168         __pCanvas = __pPanel->GetCanvasN();
169         __pCanvas->SetLineWidth(LINE_WIDTH);
170         __pCanvas->SetForegroundColor(FG_COLOR);
171         __pCanvas->SetBackgroundColor(0x0);
172
173         r = font.Construct(FONT_STYLE_PLAIN, FONT_SIZE);
174         TryReturn(r == E_SUCCESS, E_FAILURE, "Failed to construct Font");
175         __pCanvas->SetFont(font);
176         __pCanvas->Clear();
177
178         __pCamera = new (std::nothrow) Camera();
179         TryReturn(__pCamera != null, E_FAILURE, "Failed to create Camera");
180         r = __pCamera->Construct(*this, CAMERA_PRIMARY);
181         TryReturn(r == E_SUCCESS, E_FAILURE, "Failed to construct Camera");
182
183         __pFaceThread = new (std::nothrow) FaceThread();
184         TryReturn(__pFaceThread != null, E_FAILURE, "Failed to create FaceThread");
185         r = __pFaceThread->Construct();
186         TryReturn(r == E_SUCCESS, E_FAILURE, "Failed to construct FaceThread");
187         __pFaceThread->SetFaceDetectData(__pFaceDetector, __pFaceRecognizer, __pFInfoReference, __pFaceData, this);
188         __pFaceThread->Start();
189         __pFaceData->SetThreadCompleted(true);
190
191         SetFormBackEventListener(this);
192         return r;
193
194 CATCH:
195         SAFE_DELETE(pImage);
196         SAFE_DELETE(pBitmap);
197         SAFE_DELETE(pLabel);
198
199         return r;
200 }
201
202 result
203 FaceTrackerForm::OnTerminating(void)
204 {
205         StopCamera();
206         return E_SUCCESS;
207 }
208
209 void
210 FaceTrackerForm::OnFormBackRequested(Tizen::Ui::Controls::Form& source)
211 {
212         UiApp* pApp = UiApp::GetInstance();
213         AppAssert(pApp);
214         pApp->Terminate();
215 }
216
217 void
218 FaceTrackerForm::StartCamera(void)
219 {
220         BatteryLevel level = BATTERY_FULL;
221
222         Tizen::System::Battery::GetCurrentLevel(level);
223
224         result r = CheckBatteryLevel(level);
225         if (r != E_SUCCESS)
226         {
227                 return ;
228         }
229
230         if (!__pCamera->IsPoweredOn())
231         {
232                 __pCamera->PowerOn();
233         }
234
235         if (__pCamera->IsPoweredOn())
236         {
237                 __pCamera->SetPreviewFormat(PIXEL_FORMAT_YCbCr420_PLANAR);
238                 __pCamera->SetPreviewResolution(Dimension(PREVIEW_WIDTH, PREVIEW_HEIGHT));
239                 
240                 __rect = GetClientAreaBounds();
241                 Rectangle rect(__rect.x + X_OFFSET_FOR_CANVAS, Y_OFFSET_FOR_CAMVAS, PREVIEW_WIDTH, PREVIEW_HEIGHT);
242
243                 bool modified = false;
244                 OverlayRegion::EvaluateBounds(OVERLAY_REGION_EVALUATION_OPTION_LESS_THAN, rect, modified);
245                 __pOverlayRegion = GetOverlayRegionN(rect, OVERLAY_REGION_TYPE_PRIMARY_CAMERA);
246                 __pOverlayRegion->GetBackgroundBufferInfo(__bufferInfo);
247                 
248                 r = __pCamera->StartPreview(&__bufferInfo, true);
249                 TryCatch(r == E_SUCCESS, , "Start Preview failed");
250
251                 r = Tizen::System::PowerManager::KeepScreenOnState(true, false);
252
253                 __isCameraOn = true;
254                 return;
255         }
256
257 CATCH:
258         MessageBox msgBox;
259         int modalResult = 0;
260         r = msgBox.Construct("Warning","Camera is busy. Terminating App.",MSGBOX_STYLE_OK);
261         TryReturn(r == E_SUCCESS, , "Failed to construct MessageBox");
262         msgBox.ShowAndWait(modalResult);
263
264         if(modalResult == MSGBOX_RESULT_OK)
265         {
266                 Application::GetInstance()->Terminate();
267         }
268
269         return;
270 }
271
272 void
273 FaceTrackerForm::StopCamera(void)
274 {
275         __pCanvas->Clear();
276         __pCanvas->Show();
277
278         if (__pCamera->IsPoweredOn())
279         {
280                 __pCamera->StopPreview();
281                 __pCamera->PowerOff();
282         }
283
284         __isCameraOn = false;
285         SAFE_DELETE(__pOverlayRegion);
286 }
287
288 void
289 FaceTrackerForm::OnUserEventReceivedN(RequestId requestId, Tizen::Base::Collection::IList *pArgs)
290 {
291         UiApp* pApp = UiApp::GetInstance();
292         if(pApp->GetAppUiState() != APP_UI_STATE_FOREGROUND)
293         {
294                 return;
295         }
296
297         if (__isCameraOn == true)
298         {
299                 __pCanvas->SetBackgroundColor(0x0);
300                 __pCanvas->Clear();
301                 Rectangle faceRect = __pFaceData->GetRectangle();
302                 if(__pFaceData->GetFaceDetected())
303                 {
304                         __pCanvas->DrawRectangle(faceRect);
305                         __pCanvas->DrawText(Point(faceRect.x, faceRect.y), Tizen::Base::Integer::ToString(__pFaceData->GetSimilarity()),Tizen::Graphics::Color(0xFF0000FF));
306                 }
307                 __pCanvas->Show();
308         }
309         else
310         {
311                 __pCanvas->Clear();
312                 __pCanvas->Show();
313         }
314 }
315
316 result
317 FaceTrackerForm::CheckBatteryLevel(BatteryLevel level)
318 {
319         bool isCharging = false;
320         MessageBox msgBox;
321         int modalResult = 0;
322
323         Tizen::System::RuntimeInfo::GetValue(String(L"IsCharging"),isCharging);
324
325         if (isCharging)
326         {
327                 return E_SUCCESS;
328         }
329
330         if ((level == BATTERY_EMPTY) || (level == BATTERY_CRITICAL) || (level == BATTERY_LOW))
331         {
332                 result r = msgBox.Construct("Warning","Battery Low.\nPlease charge to Use.",MSGBOX_STYLE_OK);
333                 TryReturn(r == E_SUCCESS, E_FAILURE, "Failed to construct MessageBox");
334                 msgBox.ShowAndWait(modalResult);
335
336                 if(modalResult == MSGBOX_RESULT_OK)
337                 {
338                         Application::GetInstance()->Terminate();
339                 }
340
341                 return E_FAILURE;
342         }
343
344         return E_SUCCESS;
345 }
346
347 void
348 FaceTrackerForm::OnCameraPreviewed( Tizen::Base::ByteBuffer& previewedData, result r)
349 {
350         if(!(__pFaceData->GetThreadCompleted()))
351         {
352                 return;
353         }
354         ArrayList *pList = null;
355         ByteBuffer* pBuffer = new (std::nothrow) ByteBuffer();
356         TryReturn(pBuffer != null, , "Failed to create ByteBuffer");
357         pBuffer->Construct(previewedData);
358         TryCatch(r == E_SUCCESS, , "Failed to construct ByteBuffer");
359
360         pList = new (std::nothrow) ArrayList;
361         TryCatch(pList != null, , "Failed to create ArrayList");
362         pList->Construct();
363         TryCatch(r == E_SUCCESS, , "Failed to construct ArrayList");
364         pList->InsertAt (*pBuffer, 0);
365         __pFaceThread->SendUserEvent(RUN_MODE_FACE_DETECTION, pList);
366         return;
367
368 CATCH:
369         SAFE_DELETE(pBuffer);
370         SAFE_DELETE(pList);
371 }
372
373 void
374 FaceTrackerForm::OnCameraAutoFocused(bool completeCondition)
375 {
376 }
377
378 void
379 FaceTrackerForm::OnCameraCaptured( Tizen::Base::ByteBuffer& capturedData, result r)
380 {
381 }
382
383 void
384 FaceTrackerForm::OnCameraErrorOccurred(Tizen::Media::CameraErrorReason r )
385 {
386 }
387