BitmapToolkit Scol plugin
CaptureToolkit.cpp
Go to the documentation of this file.
1/*
2-----------------------------------------------------------------------------
3This source file is part of OpenSpace3D
4For the latest info, see http://www.openspace3d.com
5
6Copyright (c) 2012 I-maginer
7
8This program is free software; you can redistribute it and/or modify it under
9the terms of the GNU Lesser General Public License as published by the Free Software
10Foundation; either version 2 of the License, or (at your option) any later
11version.
12
13This program is distributed in the hope that it will be useful, but WITHOUT
14ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
16
17You should have received a copy of the GNU Lesser General Public License along with
18this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19Place - Suite 330, Boston, MA 02111-1307, USA, or go to
20http://www.gnu.org/copyleft/lesser.txt
21
22-----------------------------------------------------------------------------
23*/
24
25/*
26 Toolkit based on OpenCV library
27 First version : dec 2010
28 Author : Bastien BOURINEAU
29 */
30
37#include "Prerequisites.h"
38#include "ICameraInput.h"
39#include "ScolConvert.h"
40#include <opencv2/highgui/highgui.hpp>
41
42#ifdef APPLE_IOS
43# include "CameraPermissionIOS.h"
44
45extern int(*CallMainThread)(void*, mmachine m);
46#endif
47
48// OBJCAPTURE Scol
50
51// CALLBACK
53
54// ~All platforms yet
55#include "CameraInputOpenCV.h"
56
57#if SCOL_CAMERA_OPENCV
58 typedef CameraInputOpenCV CCameraInput;
59#else
60 #ifdef _WIN32 // Only Windows
61 #include "CameraInputWindows.h"
62 typedef CameraInputWindows CCameraInput;
63 #elif ANDROID // Only Android
64 #include "CameraInputAndroid.h"
65 typedef CameraInputAndroid CCameraInput;
66 #endif
67#endif
68
69int destroyCaptureObj(mmachine m, SCOL_PTR_TYPE handsys, int obj)
70{
71 ICameraInput* CaptureOBJ = MMgetPointer<ICameraInput*>(m, MTOP(obj));
72 SAFE_DELETE(CaptureOBJ);
73
74 MMsetPointer<ICameraInput*>(m, MTOP(obj), 0);
75
76 MMechostr(MSKDEBUG, "ObjCapture destroyed.\n");
77 return 0;
78}
79
80
89int _DScapture(mmachine m)
90{
91#ifdef _SCOL_DEBUG_
92 MMechostr(MSKDEBUG, "_DScapture\n");
93#endif
94
95 int obj = MMget(m, 0);
96 if (obj == NIL)
97 {
98 MMset(m, 0, NIL);
99 return 0;
100 }
101
102 OBJdelTM(m, OBJCAPTURESCOL, obj);
103 MMset(m, 0, ITOM(0));
104
105#ifdef _SCOL_DEBUG_
106 MMechostr(MSKDEBUG, "ok\n");
107#endif
108 return 0;
109}
110
111#ifdef APPLE_IOS
112int CheckCameraPermissionSync(mmachine m)
113{
115 return 0;
116}
117#endif
118
128#ifdef APPLE_IOS
129int _CRcaptureSync(mmachine m)
130#else
131int _CRcapture(mmachine m)
132#endif
133{
134#ifdef _SCOL_DEBUG_
135 MMechostr(MSKDEBUG, "_CRcapture\n");
136#endif
137
138#ifdef APPLE_IOS
139 //send pause / sync ?
140 //CallMainThread((void*)CheckCameraPermissionSync, m);
142#endif
143
144 int sidx = MMpull(m);
145 int idx = 0;
146 if ((sidx != NIL) && (MTOI(sidx) > 0))
147 idx = MTOI(sidx);
148
149 ICameraInput* CaptureOBJ = new CCameraInput(idx);
150
151 // failed to create device
152 if (!CaptureOBJ)
153 {
154 MMechostr(MSKDEBUG, "Failed to create device\n");
155 MMset(m, 0, NIL);
156 return 0;
157 }
158
159 // failed to open device
160 if (!CaptureOBJ->Initialize())
161 {
162 MMechostr(MSKDEBUG, "Failed to open device\n");
163 SAFE_DELETE(CaptureOBJ);
164 MMset(m, 0, NIL);
165 return 0;
166 }
167
168 if ((MMpushPointer(m, CaptureOBJ) != 0))
169 {
170 SAFE_DELETE(CaptureOBJ);
171 MMset(m, 0, NIL);
172 return MERRMEM;
173 }
174
175#ifdef _SCOL_DEBUG_
176 MMechostr(MSKDEBUG, "ok\n");
177#endif
178 return OBJcreate(m, OBJCAPTURESCOL, SCOL_PTR CaptureOBJ, NIL, 0);
179}
180
181#ifdef APPLE_IOS
182int _CRcapture(mmachine m)
183{
184 return CallMainThread((void*)_CRcaptureSync, m);
185}
186#endif
187
188
197int _BLTcapture(mmachine m)
198{
199#ifdef _SCOL_DEBUG_
200 MMechostr(MSKDEBUG, "_BLTcapture\n");
201#endif
202
203 int bitmap = MMpull(m);
204 int capture = MMget(m, 0);
205 if ((capture == NIL) || (bitmap == NIL))
206 {
207 MMset(m, 0, NIL);
208 return 0;
209 }
210
211 ICameraInput* CaptureOBJ = MMgetPointer<ICameraInput*>(m, MTOP(capture));
212 if (CaptureOBJ == NULL)
213 {
214 MMset(m, 0, NIL);
215 return 0;
216 }
217
218 cv::Mat image;
219 try
220 {
221 image = CaptureOBJ->UpdateImage();
222 }
223 catch (std::exception e)
224 {
225 //MMechostr(MSKDEBUG, " error : %s \n", e.what());
226 MMset(m, 0, NIL);
227 return 0;
228 }
229
230 if (image.empty())
231 {
232 MMset(m, 0, NIL);
233 return 0;
234 }
235
236 PtrObjVoid OB = (PtrObjVoid) MMstart(m, MTOP(bitmap));
237 PtrObjBitmap B = (PtrObjBitmap) MMstart(m, MTOP(OB->Buffer));
238
239 if (B->bits == 0)
240 {
241 MMset(m, 0, NIL);
242 return 0;
243 }
244
245 //needed when pixel format is not the same also
246 cv::Mat imgdest;
247 if (B->TailleH != image.rows || B->TailleW != image.cols)
248 {
249 imgdest = cv::Mat(B->TailleH, B->TailleW, image.type());
250 cv::resize(image, imgdest, imgdest.size(), 0, 0, cv::INTER_LINEAR);
251 }
252 else
253 imgdest = image;
254
256
257 MMset(m, 0, bitmap);
258
259#ifdef _SCOL_DEBUG_
260 MMechostr(MSKDEBUG, "ok\n");
261#endif
262 return 0;
263}
264
265
273int _GETcaptureBuffer(mmachine m)
274{
275#ifdef _SCOL_DEBUG_
276 MMechostr(MSKDEBUG, "_BLTcapture\n");
277#endif
278
279 int capture = MMget(m, 0);
280 if (capture == NIL)
281 {
282 MMset(m, 0, NIL);
283 return 0;
284 }
285
286 ICameraInput* CaptureOBJ = MMgetPointer<ICameraInput*>(m, MTOP(capture));
287 if (CaptureOBJ == NULL)
288 {
289 MMset(m, 0, NIL);
290 return 0;
291 }
292
293 cv::Mat image;
294 try
295 {
296 image = CaptureOBJ->UpdateImage();
297 }
298 catch (std::exception e)
299 {
300 //MMechostr(MSKDEBUG, " error : %s \n", e.what());
301 MMset(m, 0, NIL);
302 return 0;
303 }
304
305 if (image.empty())
306 {
307 MMset(m, 0, NIL);
308 return 0;
309 }
310
311 MMpull(m);
312 if ((MMpushPointer(m, image.data) != 0))
313 {
314 MMpush(m, NIL);
315 return 0;
316 }
317
318#ifdef _SCOL_DEBUG_
319 MMechostr(MSKDEBUG, "ok\n");
320#endif
321 return 0;
322}
323
331int _GETcaptureBufferExt(mmachine m)
332{
333#ifdef _SCOL_DEBUG_
334 MMechostr(MSKDEBUG, "_BLTcapture\n");
335#endif
336
337 int capture = MMget(m, 0);
338 if (capture == NIL)
339 {
340 MMset(m, 0, NIL);
341 return 0;
342 }
343
344 ICameraInput* CaptureOBJ = MMgetPointer<ICameraInput*>(m, MTOP(capture));
345 if (CaptureOBJ == NULL)
346 {
347 MMset(m, 0, NIL);
348 return 0;
349 }
350
351 cv::Mat image;
352 try
353 {
354 image = CaptureOBJ->UpdateImage();
355 }
356 catch (std::exception e)
357 {
358 //MMechostr(MSKDEBUG, " error : %s \n", e.what());
359 MMset(m, 0, NIL);
360 return 0;
361 }
362
363 if (image.empty())
364 {
365 MMset(m, 0, NIL);
366 return 0;
367 }
368
369 MMpull(m);
370 //TODO use scol alignment in buffer
371 if ((MMpushPointer(m, image.data) != 0))
372 {
373 MMpush(m, NIL);
374 return 0;
375 }
376 MMpush (m, ITOM (image.cols));
377 MMpush (m, ITOM (image.rows));
378 MMpush (m, ITOM (image.channels()));
379 MMpush (m, ITOM (4));
380 MBdeftab (m);
381
382#ifdef _SCOL_DEBUG_
383 MMechostr(MSKDEBUG, "ok\n");
384#endif
385 return 0;
386}
387
395{
396#ifdef SCOL_DEBUG
397 MMechostr(0, "_GETcaptureDeviceList\n");
398#endif
399
400 std::vector<std::string> devicesList = ICameraInput::GetDevicesList();
401
402 if (devicesList.empty())
403 {
404 MMpush(m, NIL);
405 return 0;
406 }
407
408 int k;
409
410 for (unsigned int i = 0; i < devicesList.size(); i++)
411 {
412 if ((k = Mpushstrbloc(m, const_cast<char*>(devicesList[i].c_str())))) return k;
413 }
414
415 if (MMpush(m, NIL)) return MERRMEM;
416
417 for (unsigned int j = 0; j < devicesList.size(); j++)
418 {
419 if (MMpush(m, 2 * 2)) return MERRMEM;
420 if ((k = MBdeftab(m))) return k;
421 }
422
423#ifdef SCOL_DEBUG
424 MMechostr(0, "ok\n");
425#endif
426
427 return 0;
428}
429
438int _SETcaptureMirror(mmachine m)
439{
440#ifdef _SCOL_DEBUG_
441 MMechostr(MSKDEBUG, "_SETcaptureMirror\n");
442#endif
443
444 int mMode = MMpull(m);
445 int capture = MMget(m, 0);
446 if ((capture == NIL) || (mMode == NIL))
447 {
448 MMset(m, 0, NIL);
449 return 0;
450 }
451
452 ICameraInput* CaptureOBJ = MMgetPointer<ICameraInput*>(m, MTOP(capture));
453 if (CaptureOBJ == NULL)
454 {
455 MMset(m, 0, NIL);
456 return 0;
457 }
458
459 CaptureOBJ->SetMirrorMode(MTOI(mMode) == 1);
460
461 MMset(m, 0, ITOM(1));
462
463#ifdef _SCOL_DEBUG_
464 MMechostr(MSKDEBUG, "ok\n");
465#endif
466 return 0;
467}
468
476int _GETcaptureSize(mmachine m)
477{
478#ifdef _SCOL_DEBUG_
479 MMechostr(MSKDEBUG, "_GETcaptureSize\n");
480#endif
481
482 int capture = MMget(m, 0);
483 if (capture == NIL)
484 {
485 MMset(m, 0, NIL);
486 return 0;
487 }
488
489 ICameraInput* CaptureOBJ = MMgetPointer<ICameraInput*>(m, MTOP(capture));
490 if (CaptureOBJ == NULL)
491 {
492 MMset(m, 0, NIL);
493 return 0;
494 }
495
496 int tupleSize = MMmalloc(m, 2, TYPETAB);
497 if (tupleSize == NIL)
498 {
499 MMset(m, 0, NIL);
500 return 0;
501 }
502
503 MMstore(m, tupleSize, 0, ITOM(CaptureOBJ->GetWidth()));
504 MMstore(m, tupleSize, 1, ITOM(CaptureOBJ->GetHeight()));
505 MMset(m, 0, PTOM(tupleSize));
506
507#ifdef _SCOL_DEBUG_
508 MMechostr(MSKDEBUG, "ok\n");
509#endif
510 return 0;
511}
512
522int _SETcaptureSize(mmachine m)
523{
524#ifdef _SCOL_DEBUG_
525 MMechostr(MSKDEBUG, "_SETcaptureSize\n");
526#endif
527
528 int mHeight = MMpull(m);
529 int mWidth = MMpull(m);
530 int capture = MMget(m, 0);
531
532 if ((capture == NIL) || (mHeight == NIL) || (mWidth == NIL))
533 {
534 MMset(m, 0, NIL);
535 return 0;
536 }
537
538 ICameraInput* CaptureOBJ = MMgetPointer<ICameraInput*>(m, MTOP(capture));
539
540 if (CaptureOBJ == NULL)
541 {
542 MMset(m, 0, NIL);
543 return 0;
544 }
545
546 try
547 {
548 CaptureOBJ->SetSize(MTOI(mWidth), MTOI(mHeight));
549 }
550 catch (std::exception &)
551 {
552 MMechostr(MSKRUNTIME, "_SETcaptureSize failed!\n");
553 MMset(m, 0, NIL);
554 return 0;
555 }
556
557 MMset(m, 0, ITOM(1));
558
559#ifdef _SCOL_DEBUG_
560 MMechostr(MSKDEBUG, "ok\n");
561#endif
562 return 0;
563}
564
575{
576#ifdef _SCOL_DEBUG_
577 MMechostr(MSKDEBUG, "_SETcaptureFocusPoint\n");
578#endif
579
580 int mY = MMpull(m);
581 int mX = MMpull(m);
582 int capture = MMget(m, 0);
583
584 if ((capture == NIL) || (mX == NIL) || (mY == NIL))
585 {
586 MMset(m, 0, NIL);
587 return 0;
588 }
589
590 ICameraInput* CaptureOBJ = MMgetPointer<ICameraInput*>(m, MTOP(capture));
591
592 if (CaptureOBJ == NULL)
593 {
594 MMset(m, 0, NIL);
595 return 0;
596 }
597
598 try
599 {
600 CaptureOBJ->SetFocusPoint(MTOI(mX), MTOI(mY));
601 }
602 catch (std::exception &)
603 {
604 MMechostr(MSKRUNTIME, "_SETcaptureFocusPoint failed!\n");
605 MMset(m, 0, NIL);
606 return 0;
607 }
608
609 MMset(m, 0, ITOM(1));
610
611#ifdef _SCOL_DEBUG_
612 MMechostr(MSKDEBUG, "ok\n");
613#endif
614 return 0;
615}
616
626{
627#ifdef _SCOL_DEBUG_
628 MMechostr(MSKDEBUG, "_SETcaptureTorchState\n");
629#endif
630
631 int mMode = MMpull(m);
632 int capture = MMget(m, 0);
633 if ((capture == NIL) || (mMode == NIL))
634 {
635 MMset(m, 0, NIL);
636 return 0;
637 }
638
639 ICameraInput* CaptureOBJ = MMgetPointer<ICameraInput*>(m, MTOP(capture));
640 if (CaptureOBJ == NULL)
641 {
642 MMset(m, 0, NIL);
643 return 0;
644 }
645
646 CaptureOBJ->SetTorchState(MTOI(mMode) == 1);
647
648 MMset(m, 0, ITOM(1));
649
650#ifdef _SCOL_DEBUG_
651 MMechostr(MSKDEBUG, "ok\n");
652#endif
653 return 0;
654}
655
664int _SAVEcaptureToFile(mmachine m)
665{
666#ifdef _SCOL_DEBUG_
667 MMechostr(MSKDEBUG, "_SAVEcaptureToFile\n");
668#endif
669 int path = MMpull(m);
670 int capture = MMget(m, 0);
671 if (capture == NIL)
672 {
673 MMset(m, 0, NIL);
674 return 0;
675 }
676
677 std::string spath(MMstartstr(m, MTOP(path)));
678
679 ICameraInput* CaptureOBJ = MMgetPointer<ICameraInput*>(m, MTOP(capture));
680 if (CaptureOBJ == NULL)
681 {
682 MMset(m, 0, NIL);
683 return 0;
684 }
685
686 bool success = CaptureOBJ->TakeSnapshot(spath);
687 MMset(m, 0, (success) ? ITOM(1) : ITOM(0));
688
689#ifdef _SCOL_DEBUG_
690 MMechostr(MSKDEBUG, "ok\n");
691#endif
692
693 return 0;
694}
695
702int _AUTORENDERcapture(mmachine m)
703{
704#ifdef _SCOL_DEBUG_
705 MMechostr(MSKDEBUG, "_AUTORENDERcapture\n");
706#endif
707 int capture = MMget(m, 0);
708 if (capture == NIL)
709 {
710 MMset(m, 0, NIL);
711 return 0;
712 }
713
714 ICameraInput* CaptureOBJ = MMgetPointer<ICameraInput*>(m, MTOP(capture));
715 if (CaptureOBJ == NULL)
716 {
717 MMset(m, 0, NIL);
718 return 0;
719 }
720
721#ifdef ANDROID
722 CaptureOBJ->RenderToScreen();
723 MMset(m, 0, ITOM(1));
724#else
725 MMechostr(MSKDEBUG, "_AUTORENDERcapture is not implemented on this platform\n");
726 MMset(m, 0, ITOM(0));
727#endif
728
729 return 0;
730}
731
732/*
733*********************************************
734* SCOL PART
735*********************************************
736*/
737
742static NativeDefinition sCaptkDef[] =
743{
744 { "ObjCapture", TYPTYPE, NULL, NULL },
745 { "_CRcapture", 2, "fun [Chn I] ObjCapture", _CRcapture },
746 { "_DScapture", 1, "fun [ObjCapture] I", _DScapture },
747 { "_BLTcapture", 2, "fun [ObjCapture ObjBitmap] ObjBitmap", _BLTcapture },
748 { "_GETcaptureBuffer", 1, "fun [ObjCapture] ObjBuff", _GETcaptureBuffer },
749 { "_GetcaptureBuffer", 1, "fun [ObjCapture] ObjBuff", _GETcaptureBuffer }, //legacy
750 { "_GETcaptureBufferExt", 1, "fun [ObjCapture] [ObjBuff I I I]", _GETcaptureBufferExt },
751 { "_GETcaptureDeviceList", 0, "fun [] [S r1]", _GETcaptureDeviceList },
752 { "_SETcaptureMirror", 2, "fun [ObjCapture I] I", _SETcaptureMirror },
753 { "_GETcaptureSize", 1, "fun [ObjCapture][I I]", _GETcaptureSize },
754 { "_SETcaptureSize", 3, "fun [ObjCapture I I] I", _SETcaptureSize },
755 { "_SETcaptureFocusPoint", 3, "fun [ObjCapture I I] I", _SETcaptureFocusPoint },
756 { "_SETcaptureTorchState", 2, "fun [ObjCapture I] I", _SETcaptureTorchState },
757 { "_SAVEcaptureToFile", 2, "fun [ObjCapture W] I", _SAVEcaptureToFile },
758 { "_AUTORENDERcapture", 1, "fun [ObjCapture] I", _AUTORENDERcapture }
759};
760
761// Everything inside _cond and _endcond is ignored by doxygen
763
768int LoadCaptureToolkit(mmachine m)
769{
770 MMechostr(MSKDEBUG, " > Loading CaptureToolkit\n");
771 OBJCAPTURESCOL = OBJregister(NBCAPTURECB, 0, destroyCaptureObj, "OBJCAPTURESCOL");
772
773 int k = PKhardpak2(m, "CaptureToolkitEngine.pkg-1.0", sizeof(sCaptkDef) / sizeof(sCaptkDef[0]), sCaptkDef);
774 MMechostr(MSKDEBUG, " > Successfully Loaded\n\n");
775 return k;
776}
777
void CheckCameraPermission()
Prompts the user with a camera permission dialog if this is the first time the app is run.
int OBJCAPTURESCOL
int NBCAPTURECB
int destroyCaptureObj(mmachine m, SCOL_PTR_TYPE handsys, int obj)
int LoadCaptureToolkit(mmachine m)
Concrete implementation of ICameraInput using Android API.
Concrete implementation of ICameraInput using OpenCV utility.
Concrete implementation of ICameraInput using Windows API.
static void MatToScolBitmapRGB(cv::Mat mat, PtrObjBitmap scolBitmap)
Interface for camera management. Concrete classes are written for Windows, Android and OpenCV native ...
void SetMirrorMode(bool mode)
virtual void SetSize(int width, int height)=0
virtual bool TakeSnapshot(std::string path)
virtual bool Initialize()=0
virtual int GetHeight()=0
virtual int GetWidth()=0
virtual cv::Mat UpdateImage()=0
virtual bool SetFocusPoint(int x, int y)
static std::vector< std::string > GetDevicesList()
virtual void SetTorchState(bool state)
virtual void RenderToScreen()
int _SETcaptureSize(mmachine m)
_SETcaptureSize : This function apply a size to a capture device Prototype: fun [ObjCapture I I] I
int _SAVEcaptureToFile(mmachine m)
_SAVEcaptureToFile : This function save a capture frame into a file Prototype: fun [ObjCapture W] I
int _AUTORENDERcapture(mmachine m)
_AUTORENDERcapture : This function renders current frame on Android device Prototype: fun [ObjCapture...
int _SETcaptureMirror(mmachine m)
_SETcaptureMirror : This function change the miror mode for the capture Prototype: fun [ObjCapture I]...
int _GETcaptureDeviceList(mmachine m)
_GETcaptureDeviceList : This function list the installed video devices Prototype: fun [] [S r1]
int _GETcaptureBuffer(mmachine m)
_GETcaptureBuffer : This function return the current pixel buffer Prototype: fun [ObjCapture] ObjBuff
int _SETcaptureTorchState(mmachine m)
_SETcaptureTorchState : This function change camera torch state Prototype: fun [ObjCapture I] I
int _DScapture(mmachine m)
_DScapture : This function destroy a capture device
int _BLTcapture(mmachine m)
_BLTcapture : This function blit the device picture into a bitmap Prototype: fun [ObjCapture ObjBitma...
int _GETcaptureSize(mmachine m)
_GETcaptureSize : This function the size of a capture device Prototype: fun [ObjCapture] [I I]
int _SETcaptureFocusPoint(mmachine m)
_SETcaptureFocusPoint : This function define the focus point on a mobile camera device Prototype: fun...
int _GETcaptureBufferExt(mmachine m)
_GETcaptureBufferExt : This function return the current pixel buffer Prototype: fun [ObjCapture] [Obj...
int _CRcapture(mmachine m)
_CRcapture : This function create a new capture device from a device index