Update the changelog
[opencv] / apps / cvcsdemo / cvcsdemo.cpp
1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
5 //  By downloading, copying, installing or using the software you agree to this license.
6 //  If you do not agree to this license, do not download, install,
7 //  copy or use the software.
8 //
9 //
10 //                        Intel License Agreement
11 //                For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
15 //
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
18 //
19 //   * Redistribution's of source code must retain the above copyright notice,
20 //     this list of conditions and the following disclaimer.
21 //
22 //   * Redistribution's in binary form must reproduce the above copyright notice,
23 //     this list of conditions and the following disclaimer in the documentation
24 //     and/or other materials provided with the distribution.
25 //
26 //   * The name of Intel Corporation may not be used to endorse or promote products
27 //     derived from this software without specific prior written permission.
28 //
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
39 //
40 //M*/
41
42 #include <tcl.h>
43 #include <tk.h>
44 #include <stdlib.h>
45
46 #ifndef WIN32
47 #include <unistd.h>
48 #endif
49
50 #ifndef WIN32
51     #define Tk_GetHWND(id) id
52 #else
53     extern "C"
54     {
55     int Tk_GetHWND(int win);
56     }
57 #endif
58
59 #if _MSC_VER >= 1200
60 #pragma warning( disable: 4514 )
61 #endif
62
63 #include <math.h>
64 #include <string.h>
65 #include "cvcam.h"
66 #include "csdemoview.h"
67
68 #define SYSTEM_WIN_FROM_TK_WIN(tkwin) Tk_GetHWND(Tk_WindowId(tkwin))
69
70 char cmd[300];
71
72 void    MainEx(int argc, char ** /*argv*/, Tcl_AppInitProc *pfappInitProc, Tcl_Interp *pintrp,
73                char *pchfileName);
74 int     Tcl_AppInit(Tcl_Interp *pintrp);
75 void    WishPanic TCL_VARARGS_DEF(char *,arg1);
76 void    Panic (Tcl_Interp * pintrp, const char * pch);
77
78 CCsDemoView view;
79 CvImage limage;
80 bool g_created = false;
81 bool g_pressed = false;
82 bool g_paused = false;
83
84 int camtype = -1;
85
86 int X,Y;
87 cvcamWindow mainwin;
88
89 static char* module_path;
90 CvPoint P;
91
92 cvcamAVIFILE avifile = (cvcamAVIFILE)-1;
93
94
95 ///////////////////////////////////////////////////////////////////////////////
96 static char* GetPathFromModuleName( char* modulename )
97 {
98     int i;
99     if( !modulename )
100         return 0;
101 #ifndef WIN32
102     /* if module is link find real path */
103     int  len;
104     char real[1000];
105     strcpy( real, modulename );
106     while( (len = readlink( real, real, 1000 )) > 0 )
107         real[len] = 0;
108     char* path = (char*)malloc( strlen( real ) + 10 );
109     strcpy( path, real );
110 #else
111     char* path = (char*)malloc( strlen( modulename ) + 10 );
112     strcpy( path, modulename );
113 #endif
114
115     for( i = strlen( path ) - 1;
116          i > 0 && path[i] != '\\' && path[i] != '/';
117          i-- );
118
119     if( i <= 0 )
120     {
121         path[0] = '.';
122         i = 1;
123     }
124
125     path[i] = '/';
126     path[i + 1] = 0;
127
128 #ifdef WIN32
129     for( i = 0; i < (int)strlen( path ); i++ )
130         if( path[i] == '\\' )
131             path[i] = '/';
132 #endif
133
134     return path;
135 }
136
137 //----------------------------------------------------------------------------
138
139 void  CheckBackProject( CvImage* image )
140 {
141     if( view.m_params.view == 1 )
142     {
143         IplImage* src = view.m_cCamShift.get_back_project();
144         if( src && src->imageData && image )
145         {
146             //iplGrayToColor( src, image, 0, 0, 0 );
147             cvCvtPlaneToPix( src, src, src, 0, image);
148         }
149     }
150     else if( view.m_params.view == 2 && view.m_track)
151     {
152         int i, dims = 0;
153         CvSize size;
154
155         view.m_cCamShift.get_hist_dims( &dims );
156         cvGetImageRawData( image, 0, 0, &size );
157
158         for( i = 0; i < dims; i++ )
159         {
160             int val = cvRound(view.m_cCamShift.query(&i));
161             CvPoint p[4];
162
163             p[0].x = p[1].x = i*size.width/(2*dims);
164             p[2].x = p[3].x = (i+1)*size.width/(2*dims);
165
166             p[1].y = p[2].y = 0;
167             p[0].y = p[3].y = (val*size.height)/(3*255);
168
169             cvFillConvexPoly( image, p, 4, CV_RGB(255,0,0));
170         }
171     }
172 }
173
174
175 void  DrawCross( CvImage* image )
176 {
177     float cs = (float)cos( view.m_cCamShift.get_orientation() );
178     float sn = (float)sin( view.m_cCamShift.get_orientation() );
179
180     int x = view.m_object.x + view.m_object.width / 2;
181     int y = view.m_object.y + view.m_object.height / 2;
182
183     CvPoint p1 = {(int)(x + view.m_cCamShift.get_length() * cs / 2),
184         (int)(y + view.m_cCamShift.get_length() * sn / 2)};
185     CvPoint p2 = {(int)(x - view.m_cCamShift.get_length() * cs / 2),
186         (int)(y - view.m_cCamShift.get_length() * sn / 2)};
187     CvPoint p3 = {(int)(x + view.m_cCamShift.get_width() * sn / 2),
188         (int)(y - view.m_cCamShift.get_width() * cs / 2)};
189     CvPoint p4 = {(int)(x - view.m_cCamShift.get_width() * sn / 2),
190         (int)(y + view.m_cCamShift.get_width() * cs / 2)};
191     cvLine( image, p1, p2, CV_RGB(255,255,0) );
192     cvLine( image, p4, p3, CV_RGB(255,255,0) );
193 }
194
195 void  ApplyCamShift( CvImage* image, bool initialize )
196 {
197     CvSize size;
198     int bins = view.m_params.bins;
199
200     view.m_cCamShift.set_hist_dims( 1, &bins );
201     view.m_cCamShift.set_hist_bin_range( 0, 1, 180 );
202     view.m_cCamShift.set_threshold( 0 );
203     view.m_cCamShift.set_min_ch_val( 1, view.m_params.Smin );
204     view.m_cCamShift.set_max_ch_val( 1, 255 );
205     view.m_cCamShift.set_min_ch_val( 2, view.m_params.Vmin );
206     view.m_cCamShift.set_max_ch_val( 2, view.m_params.Vmax );
207
208     cvGetImageRawData( image, 0, 0, &size );
209
210     if( view.m_object.x < 0 ) view.m_object.x = 0;
211     if( view.m_object.x > size.width - view.m_object.width - 1 )
212         view.m_object.x = MAX(0, size.width - view.m_object.width - 1);
213
214     if( view.m_object.y < 0 ) view.m_object.y = 0;
215     if( view.m_object.y > size.height - view.m_object.height - 1 )
216         view.m_object.y = MAX(0, size.height - view.m_object.height - 1);
217
218     if( view.m_object.width > size.width - view.m_object.x )
219         view.m_object.width = MIN(size.width, size.width - view.m_object.x);
220
221     if( view.m_object.height > size.height - view.m_object.y )
222         view.m_object.height = MIN(size.height, size.height - view.m_object.y);
223     view.m_cCamShift.set_window(view.m_object);
224
225     if( initialize )
226     {
227         view.m_cCamShift.reset_histogram();
228         view.m_cCamShift.update_histogram( image );
229     }
230
231     view.m_cCamShift.track_object( image );
232     view.m_object = view.m_cCamShift.get_window();
233 }
234
235 // Callback function ----------------------------------------------------------
236 void testcallback(IplImage* img)
237 {
238     CvSize imgsize = view.SetImgSize( img->width, img->height );
239     int stride = (imgsize.width * 3 + 3) & -4;
240
241     cvInitImageHeader( &limage, imgsize, IPL_DEPTH_8U, 3, IPL_ORIGIN_TL, 4 );
242     //cvSetImageData( &image, pData,stride );
243     cvSetImageData( &limage, img->imageData,stride );
244
245     if(view.m_track == false)
246     {
247         if(view.m_init == false)
248         {
249             CvPoint p1, p2;
250             // Draw box
251             p1.x = cvRound( imgsize.width * view.m_params.x );
252             p1.y = cvRound( imgsize.height * view.m_params.y );
253
254             p2.x = cvRound( imgsize.width * (view.m_params.x + view.m_params.width));
255             p2.y = cvRound( imgsize.height * (view.m_params.y + view.m_params.height));
256
257             CheckBackProject( &limage );
258             cvRectangle( &limage, p1, p2, -1, 1 );
259             cvCircle(&limage, p1, 1, CV_RGB(255,0,0), 1);
260
261             view.m_cCamShift.set_window(view.m_object);
262         }
263         else
264         {
265             view.m_object.x = cvRound( imgsize.width * view.m_params.x );
266             view.m_object.y = cvRound( imgsize.height * view.m_params.y );
267
268             view.m_object.width = cvRound( imgsize.width * view.m_params.width );
269             view.m_object.height = cvRound( imgsize.height * view.m_params.height );
270
271
272             if( view.m_object.x < 0 ) view.m_object.x = 0;
273             if( view.m_object.x > imgsize.width - view.m_object.width - 1 )
274                 view.m_object.x = MAX(0, imgsize.width - view.m_object.width - 1);
275
276             if( view.m_object.y < 0 ) view.m_object.y = 0;
277             if( view.m_object.y > imgsize.height - view.m_object.height - 1 )
278                 view.m_object.y = MAX(0, imgsize.height - view.m_object.height - 1);
279
280             if( view.m_object.width > imgsize.width - view.m_object.x )
281                 view.m_object.width = MIN(imgsize.width, imgsize.width - view.m_object.x);
282
283             if( view.m_object.height > imgsize.height - view.m_object.y )
284                 view.m_object.height = MIN(imgsize.height, imgsize.height - view.m_object.y);
285
286             view.m_cCamShift.set_window(view.m_object);
287
288             ApplyCamShift( &limage, true );
289             CheckBackProject( &limage );
290
291             view.m_track = true;
292         }
293     }
294     else
295     {
296         ApplyCamShift( &limage, false );
297         CheckBackProject( &limage );
298
299         DrawCross( &limage );
300
301         CvPoint p1, p2;
302         // Draw box
303         p1.x = cvRound( imgsize.width * view.m_params.x );
304         p1.y = cvRound( imgsize.height * view.m_params.y );
305
306         p2.x = cvRound( imgsize.width * (view.m_params.x + view.m_params.width));
307         p2.y = cvRound( imgsize.height * (view.m_params.y + view.m_params.height));
308
309         cvRectangle( &limage, p1, p2, CV_RGB(0,0,255), 1 );
310         cvCircle(&limage, p1, 1, CV_RGB(255,0,0), 1);
311     }
312 }
313 //-----------------------------------------------------------------------------
314
315 /*
316  *----------------------------------------------------------------------
317  *
318  * Commands routines.
319  *
320  * Results:
321  *  TCL_OK - if sucsess, or TCL_ERROR
322  *
323  *----------------------------------------------------------------------
324  */
325
326 int Init_Camera (ClientData, Tcl_Interp *interp,
327                  int, char **)
328 {
329     int ncameras, ret;
330     Tk_Window win;
331     char com[1000]="set dlg [Dialog .dlg -parent . -modal local -separator 1 -title   \"Choice of cameras\" \
332         -side bottom -anchor  s -default 0]";
333     CameraDescription cd;
334
335     ncameras = cvcamGetCamerasCount();
336
337     if (ncameras==0)
338     {
339         Tcl_Eval(interp,"tk_dialog .pattern {Error} { Cameras not found.} {} 0 OK");
340         return TCL_ERROR;
341     }
342
343
344     if (ncameras > 1)
345     {
346         ret = Tcl_Eval(interp,com);
347
348         strcpy(com,"$dlg add -name ok -width 5");
349         ret = Tcl_Eval(interp,com);
350
351         strcpy(com, "set top [$dlg getframe]");
352         ret = Tcl_Eval(interp,com);
353
354         strcpy(com, "label $top.lab1 -text \"Several cameras has found in your system. Choose one of them.\" \n\
355             pack $top.lab1 -side top -anchor nw" );
356         ret = Tcl_Eval(interp,com);
357
358         strcpy(com, "label $top.lab2 -text \"\" \n\
359             pack $top.lab2 -side top -anchor nw");
360         ret = Tcl_Eval(interp,com);
361
362         strcpy(com, "label $top.lab3 -text \"Cameras:\" \n\
363             pack $top.lab3 -side top -anchor nw");
364         ret = Tcl_Eval(interp,com);
365
366         strcpy(com, "ComboBox $top.cb -width 50 -height 4 -editable no -modifycmd CVCsDemo::Modify");
367         ret = Tcl_Eval(interp,com);
368
369         strcpy(com, "pack $top.cb -side top");
370         ret = Tcl_Eval(interp,com);
371
372         strcpy(com, "$top.cb configure -values {");
373         for (int i=0; i<ncameras; i++)
374         {
375             cvcamGetProperty(i, CVCAM_DESCRIPTION, (void*)&cd);
376             strcat(com,"\"");
377             strcat(com,cd.DeviceDescription);
378             strcat(com,"\" ");
379         }
380         strcat(com,"}");
381         ret = Tcl_Eval(interp, com);
382
383         strcpy(com,"$top.cb setvalue @0 \n CVCsDemo::Modify \n set ret [$dlg draw]");
384         ret = Tcl_Eval(interp, com);
385
386         strcpy(com,"destroy $dlg");
387         ret = Tcl_Eval(interp, com);
388
389         ret = Tcl_Eval(interp, "set tmp $CVCsDemo::cam");
390
391         avifile = atoi(interp->result);
392     }
393     else
394     {
395         avifile=0;
396     }
397
398     ret = Tcl_Eval(interp, "set f $CVCsDemo::curframe");
399
400     win = Tk_NameToWindow(interp, interp->result,
401         Tk_MainWindow(interp));
402
403     Tk_MapWindow(win);
404     int w = Tk_Width(win);
405     int h = Tk_Height(win);
406
407     mainwin = SYSTEM_WIN_FROM_TK_WIN(win);
408
409     cvcamSetProperty(avifile, CVCAM_PROP_ENABLE, CVCAMTRUE);
410     cvcamSetProperty(avifile, CVCAM_PROP_RENDER, CVCAMTRUE);
411     cvcamSetProperty(avifile, CVCAM_PROP_WINDOW,  &mainwin);
412     cvcamSetProperty(avifile, CVCAM_PROP_CALLBACK, (void*)testcallback);
413     cvcamSetProperty(avifile, CVCAM_RNDWIDTH, (void*)&w);
414     cvcamSetProperty(avifile, CVCAM_RNDHEIGHT, (void*)&h);
415     view.SetVwSize(w,h);
416
417     cvcamInit();
418     camtype = 1;
419     g_created = true;
420     cvcamGetProperty(avifile, CVCAM_DESCRIPTION, (void*)&cd);
421     sprintf(com,"set CVCsDemo::curcam \"%s\"",cd.DeviceDescription);
422     Tcl_Eval(interp, com);
423
424     return TCL_OK;
425 }
426
427 int Close_Camera (ClientData, Tcl_Interp * /*interp*/,
428                   int, char ** /*argv*/)
429 {
430     view.m_start = false;
431     g_created = false;
432     cvcamExit();
433     camtype = -1;
434     avifile = (cvcamAVIFILE)-1;
435     return TCL_OK;
436 }
437
438 int Start_Camera (ClientData, Tcl_Interp * /*interp*/,
439                  int, char ** /*argv*/)
440 {
441     view.m_start = true;
442
443     cvcamStart();
444     return TCL_OK;
445 }
446
447 int Stop_Camera (ClientData, Tcl_Interp * /*interp*/,
448                   int, char ** /*argv*/)
449 {
450     view.m_start = false;
451
452     cvcamStop();
453     return TCL_OK;
454 }
455 #ifndef __WIN32
456 #define __stdcall
457 #endif
458
459 unsigned __stdcall thread_main(void * data)
460 {
461     CvSize sz;
462     sz = view.GetVwSize();
463     return cvcamPlayAVI(0,
464                         data,
465                         sz.width,
466                         sz.height,
467                         (void*)testcallback);
468 }
469
470 int Init_Avi (ClientData, Tcl_Interp *interp,
471                  int, char ** /*argv*/)
472 {
473     int ret;
474     Tk_Window win;
475
476     char * val = Tcl_GetVar(interp, "CVCsDemo::pagesnum", TCL_GLOBAL_ONLY);
477
478     if ( *val != '0' )
479     {
480         Tcl_Eval(interp, "tk_dialog .mes {Message} { CVCsDemo support only one tracker.} {} 0 OK");
481         return TCL_OK;
482     }
483
484     avifile = cvcamAVIOpenFile(NULL);
485     if (avifile == -1)
486     {
487         Tcl_Eval( interp, "tk_dialog .mes {Error} { Can't open file.} {} 0 OK");
488         return TCL_OK;
489     }
490
491     char com_ok[] = "incr CVCsDemo::pagescount \n"
492                     "incr CVCsDemo::pagesnum\n"
493                     "set CVCsDemo::avistate \"1\" \n"
494                     "CVCsDemo::longmenu 1 \n"
495                     "CVCsDemo::longbar 1 \n"
496                     "CVCsDemo::longstbar 1 \n"
497                     "set CVCsDemo::curpage p[expr $CVCsDemo::pagescount] \n"
498                     "lappend CVCsDemo::pages $CVCsDemo::curpage \n"
499                     "lappend CVCsDemo::cams \"AVI\" \n"
500                     "set text [format \"AVI %i\" $CVCsDemo::pagescount] \n"
501                     "CVCsDemo::createtab $CVCsDemo::curpage $text \n"
502                     "$CVCsDemo::nb see [$CVCsDemo::nb pages end] \n"
503                     "$CVCsDemo::nb raise [$CVCsDemo::nb pages end] \n"
504                     "update \n"
505                     "set CVCsDemo::capturestate 0 \n"
506                     "$CVCsDemo::tb.bbox2.b0 configure -state active \n"
507                     "$CVCsDemo::tb.bbox2.b1 configure -state disable \n"
508                     "$CVCsDemo::tb.bbox2.b2 configure -state disable ";
509
510     ret = Tcl_Eval(interp, com_ok);
511
512     ret = Tcl_Eval(interp, "set f $CVCsDemo::curframe");
513     win = Tk_NameToWindow(interp, interp->result,
514         Tk_MainWindow(interp));
515
516     Tk_MapWindow(win);
517     int w = Tk_Width(win);
518     int h = Tk_Height(win);
519
520     mainwin = SYSTEM_WIN_FROM_TK_WIN(win);
521
522     cvcamSetProperty(avifile, CVCAM_PROP_ENABLE, CVCAMTRUE);
523     cvcamSetProperty(avifile, CVCAM_PROP_RENDER, CVCAMTRUE);
524     cvcamSetProperty(avifile, CVCAM_PROP_WINDOW,  &mainwin);
525     cvcamSetProperty(avifile, CVCAM_PROP_CALLBACK, (void*)testcallback);
526     cvcamSetProperty(avifile, CVCAM_RNDWIDTH, (void*)&w);
527     cvcamSetProperty(avifile, CVCAM_RNDHEIGHT, (void*)&h);
528     view.SetVwSize(w,h);
529
530     sprintf(com_ok,"set CVCsDemo::curcam \"%s\"", "AVI");
531     Tcl_Eval(interp, com_ok);
532
533     g_created = true;
534     camtype = 0;
535
536     return TCL_OK;
537 }
538
539 int Pause_Camera (ClientData, Tcl_Interp * /*interp*/,
540                   int, char ** /*argv*/)
541 {
542     g_paused = true;
543     cvcamPause();
544
545     return TCL_OK;
546 }
547
548 int Resume_Camera (ClientData, Tcl_Interp * /*interp*/,
549                    int, char ** /*argv*/)
550 {
551     g_paused = false;
552     cvcamResume();
553
554     return TCL_OK;
555 }
556
557 int Pause_Avi (ClientData, Tcl_Interp * /*interp*/,
558                int, char ** /*argv*/)
559 {
560     g_paused = true;
561     cvcamAVIPause(avifile);
562
563     return TCL_OK;
564 }
565
566 int Resume_Avi (ClientData, Tcl_Interp * /*interp*/,
567                 int, char ** /*argv*/)
568 {
569     g_paused = false;
570     cvcamAVIResume(avifile);
571
572     return TCL_OK;
573 }
574
575 int Stop_Avi (ClientData, Tcl_Interp * /*interp*/,
576               int, char ** /*argv*/)
577 {
578     g_created = false;
579     view.m_start = false;
580     cvcamAVICloseFile(avifile);
581     avifile = (cvcamAVIFILE)-1;
582     camtype = -1;
583
584     return TCL_OK;
585 }
586
587
588 int Start_Avi (ClientData, Tcl_Interp *interp,
589                  int, char ** /*argv*/)
590 {
591     int ret;
592     Tk_Window win;
593
594     ret = Tcl_Eval(interp, "set f $CVCsDemo::curframe");
595     win = Tk_NameToWindow(interp, interp->result,
596         Tk_MainWindow(interp));
597
598     Tk_MapWindow(win);
599     int w = Tk_Width(win);
600     int h = Tk_Height(win);
601
602     mainwin = SYSTEM_WIN_FROM_TK_WIN(win);
603     view.SetVwSize(w,h);
604
605     ret = cvcamAVISetWindow(avifile, &mainwin);
606     ret = cvcamAVISetCallback(avifile,(void*)testcallback);
607     ret = cvcamAVISetSize(avifile, w, h);
608
609     ret = cvcamAVIRun(avifile);
610
611     view.m_start = true;
612
613     return TCL_OK;
614 }
615
616 int Set_Track (ClientData, Tcl_Interp * /*interp*/,
617                int, char ** /*argv*/)
618 {
619     view.m_init = true;
620     view.m_track = false;
621     view.m_params.view = 0;
622
623     return TCL_OK;
624 }
625
626 int Reset_Track (ClientData, Tcl_Interp * /*interp*/,
627                int, char ** /*argv*/)
628 {
629     view.m_init =  view.m_track = false;
630
631     return TCL_OK;
632 }
633
634 int Set_Night (ClientData, Tcl_Interp * /*interp*/,
635                int, char ** /*argv*/)
636 {
637     view.m_params.view = 1;
638     return TCL_OK;
639 }
640
641 int Reset_Night (ClientData, Tcl_Interp * /*interp*/,
642                  int, char ** /*argv*/)
643 {
644     view.m_params.view = 0;
645     return TCL_OK;
646 }
647
648 int Set_Hist (ClientData, Tcl_Interp * /*interp*/,
649                int, char ** /*argv*/)
650 {
651     view.m_params.view = 2;
652     return TCL_OK;
653 }
654
655 int Reset_Hist (ClientData, Tcl_Interp * /*interp*/,
656                  int, char ** /*argv*/)
657 {
658     view.m_params.view = 0;
659     return TCL_OK;
660 }
661
662 int Set_Video (ClientData, Tcl_Interp * /*interp*/,
663                int, char ** /*argv*/)
664 {
665     void *p = 0;
666     cvcamGetProperty(0,CVCAM_VIDEOFORMAT, p);
667
668     return TCL_OK;
669 }
670
671 int Set_CameraOpt (ClientData, Tcl_Interp * /*interp*/,
672                int, char ** /*argv*/)
673 {
674     void *p = 0;
675     cvcamGetProperty(0,CVCAM_CAMERAPROPS, p);
676
677     return TCL_OK;
678 }
679
680 int Button_Press (ClientData, Tcl_Interp * /*interp*/,
681                int, char ** argv)
682 {
683     if (view.m_start)
684     {
685         CvPoint p,imgp;
686         p.x = atoi(argv[1]);
687         p.y = atoi(argv[2]);
688     #ifdef WIN32
689         p.y = view.m_VwSize.height - p.y;
690     #endif
691         CvSize imgsize = view.GetImgSize();
692
693         imgp = view.ConvertViewToImage(p);
694         X = view.m_object.x = imgp.x;
695         Y = view.m_object.y = imgp.y;
696
697         view.m_params.x = ((float)imgp.x) / imgsize.width ;
698         view.m_params.y = ((float)imgp.y) / imgsize.height ;
699
700         g_pressed = true;
701     }
702     return TCL_OK;
703 }
704
705 int Button_Release (ClientData, Tcl_Interp * /*interp*/,
706                   int, char ** /*argv*/)
707 {
708     if (view.m_start)
709     {
710         g_pressed = false;
711         if (view.m_track)
712         {
713             view.m_init  = true;
714             view.m_track = false;
715         }
716     }
717
718     return TCL_OK;
719 }
720
721 int Motion (ClientData, Tcl_Interp * /*interp*/,
722                     int, char ** argv)
723 {
724     if (view.m_start)
725     {
726         if (g_pressed)
727         {
728
729             CvPoint p,imgp;
730             p.x = atoi(argv[1]);
731             p.y = atoi(argv[2]);
732     #ifdef WIN32
733             p.y = view.m_VwSize.height - p.y;
734     #endif
735             CvSize imgsize = view.GetImgSize();
736
737             imgp = view.ConvertViewToImage(p);
738
739             view.m_object.width  = abs(imgp.x - X);
740             view.m_object.height = abs(imgp.y - Y);
741
742
743             if (view.m_object.width == 0)
744             {
745                 view.m_object.width = 1;
746                 X--;
747             }
748
749             if (view.m_object.height == 0)
750             {
751                 view.m_object.height = 1;
752                 Y--;
753             }
754
755             if (imgp.x < X)
756                 view.m_object.x = imgp.x;
757             if (imgp.y < Y)
758                 view.m_object.y = imgp.y;
759
760             if( view.m_object.x < 0 ) view.m_object.x = 0;
761             if( view.m_object.x > imgsize.width - view.m_object.width - 1 )
762                 view.m_object.x = MAX(0, imgsize.width - view.m_object.width - 1);
763
764             if( view.m_object.y < 0 ) view.m_object.y = 0;
765             if( view.m_object.y > imgsize.height - view.m_object.height - 1 )
766                 view.m_object.y = MAX(0, imgsize.height - view.m_object.height - 1);
767
768             if( view.m_object.width > imgsize.width - view.m_object.x )
769                 view.m_object.width = MIN(imgsize.width, imgsize.width - view.m_object.x);
770
771             if( view.m_object.height > imgsize.height - view.m_object.y )
772                 view.m_object.height = MIN(imgsize.height, imgsize.height - view.m_object.y);
773
774             view.m_params.x = ((float)view.m_object.x) / imgsize.width ;
775             view.m_params.y = ((float)view.m_object.y) / imgsize.height ;
776             view.m_params.width  = ((float)view.m_object.width) / imgsize.width;
777             view.m_params.height  = ((float)view.m_object.height) / imgsize.height;
778
779             view.m_cCamShift.set_window(view.m_object);
780         }
781     }
782
783     return TCL_OK;
784 }
785
786 int Configure (ClientData, Tcl_Interp *interp,
787             int, char ** /*argv*/)
788 {
789     if (g_created)
790     {
791         Tk_Window win;
792         Tcl_Eval(interp, "set f $CVCsDemo::curframe");
793
794         win = Tk_NameToWindow(interp, interp->result,
795             Tk_MainWindow(interp));
796
797         Tk_MapWindow(win);
798         int w = Tk_Width(win);
799         int h = Tk_Height(win);
800
801         cvcamSetProperty(avifile, CVCAM_RNDWIDTH, (void*)&w);
802         cvcamSetProperty(avifile, CVCAM_RNDHEIGHT, (void*)&h);
803
804         view.SetVwSize(w,h);
805     }
806
807     return TCL_OK;
808 }
809
810 int Set_Bins (ClientData, Tcl_Interp * /*interp*/,
811                int, char ** argv )
812 {
813     view.m_params.bins = atoi(argv[1]);
814
815     if (view.m_track)
816     {
817         view.m_init  = true;
818         view.m_track = false;
819     }
820     return TCL_OK;
821 }
822
823 int Set_S (ClientData, Tcl_Interp * /*interp*/,
824               int, char ** argv)
825 {
826     view.m_params.Smin = atoi(argv[1]);
827     return TCL_OK;
828 }
829
830 int Set_V1 (ClientData, Tcl_Interp * /*interp*/,
831               int, char ** argv)
832 {
833     view.m_params.Vmin = atoi(argv[1]);
834     return TCL_OK;
835 }
836
837 int Set_V2 (ClientData, Tcl_Interp * /*interp*/,
838               int, char ** argv )
839 {
840     view.m_params.Vmax = atoi(argv[1]);
841     return TCL_OK;
842 }
843
844 //-----------------------------------------------------------------------------
845
846 /*
847  *----------------------------------------------------------------------
848  *
849  * Commands_Init --     Commands initialisation routine.
850  *
851  * Results:
852  *      TCL_OK - if sucsess, or TCL_ERROR
853  *
854  *----------------------------------------------------------------------
855  */
856 int
857 Commands_Init(Tcl_Interp *interp)
858 {
859     Tcl_CreateCommand (interp, "pInitCamera", Init_Camera,
860         (ClientData *) NULL, (Tcl_CmdDeleteProc *) NULL);
861     Tcl_CreateCommand (interp, "pStartCamera", Start_Camera,
862         (ClientData *) NULL, (Tcl_CmdDeleteProc *) NULL);
863     Tcl_CreateCommand (interp, "pCloseCamera", Close_Camera,
864         (ClientData *) NULL, (Tcl_CmdDeleteProc *) NULL);
865     Tcl_CreateCommand (interp, "pStopCamera", Stop_Camera,
866         (ClientData *) NULL, (Tcl_CmdDeleteProc *) NULL);
867
868     Tcl_CreateCommand (interp, "pInitAvi", Init_Avi,
869         (ClientData *) NULL, (Tcl_CmdDeleteProc *) NULL);
870     Tcl_CreateCommand (interp, "pStartAvi", Start_Avi,
871         (ClientData *) NULL, (Tcl_CmdDeleteProc *) NULL);
872     Tcl_CreateCommand (interp, "pStopAvi", Stop_Avi,
873         (ClientData *) NULL, (Tcl_CmdDeleteProc *) NULL);
874
875     Tcl_CreateCommand (interp, "pSetTrack", Set_Track,
876         (ClientData *) NULL, (Tcl_CmdDeleteProc *) NULL);
877     Tcl_CreateCommand (interp, "pResetTrack", Reset_Track,
878         (ClientData *) NULL, (Tcl_CmdDeleteProc *) NULL);
879     Tcl_CreateCommand (interp, "pSetNight", Set_Night,
880         (ClientData *) NULL, (Tcl_CmdDeleteProc *) NULL);
881     Tcl_CreateCommand (interp, "pResetNight", Reset_Night,
882         (ClientData *) NULL, (Tcl_CmdDeleteProc *) NULL);
883
884     Tcl_CreateCommand (interp, "pSetHist", Set_Hist,
885         (ClientData *) NULL, (Tcl_CmdDeleteProc *) NULL);
886     Tcl_CreateCommand (interp, "pResetHist", Reset_Hist,
887         (ClientData *) NULL, (Tcl_CmdDeleteProc *) NULL);
888
889     Tcl_CreateCommand (interp, "pSetVideo", Set_Video,
890         (ClientData *) NULL, (Tcl_CmdDeleteProc *) NULL);
891     Tcl_CreateCommand (interp, "pButtonPress", Button_Press,
892         (ClientData *) NULL, (Tcl_CmdDeleteProc *) NULL);
893     Tcl_CreateCommand (interp, "pButtonRelease", Button_Release,
894         (ClientData *) NULL, (Tcl_CmdDeleteProc *) NULL);
895     Tcl_CreateCommand (interp, "pMotion", Motion,
896         (ClientData *) NULL, (Tcl_CmdDeleteProc *) NULL);
897     Tcl_CreateCommand (interp, "pSetCameraOpt", Set_CameraOpt,
898         (ClientData *) NULL, (Tcl_CmdDeleteProc *) NULL);
899     Tcl_CreateCommand (interp, "pConfigure", Configure,
900         (ClientData *) NULL, (Tcl_CmdDeleteProc *) NULL);
901     Tcl_CreateCommand (interp, "pSetBins", Set_Bins,
902         (ClientData *) NULL, (Tcl_CmdDeleteProc *) NULL);
903     Tcl_CreateCommand (interp, "pSetS", Set_S,
904         (ClientData *) NULL, (Tcl_CmdDeleteProc *) NULL);
905     Tcl_CreateCommand (interp, "pSetV1", Set_V1,
906         (ClientData *) NULL, (Tcl_CmdDeleteProc *) NULL);
907     Tcl_CreateCommand (interp, "pSetV2", Set_V2,
908         (ClientData *) NULL, (Tcl_CmdDeleteProc *) NULL);
909
910     Tcl_CreateCommand (interp, "pPauseCamera", Pause_Camera,
911         (ClientData *) NULL, (Tcl_CmdDeleteProc *) NULL);
912     Tcl_CreateCommand (interp, "pPauseAvi", Pause_Avi,
913         (ClientData *) NULL, (Tcl_CmdDeleteProc *) NULL);
914     Tcl_CreateCommand (interp, "pResumeCamera", Resume_Camera,
915         (ClientData *) NULL, (Tcl_CmdDeleteProc *) NULL);
916     Tcl_CreateCommand (interp, "pResumeAvi", Resume_Avi,
917         (ClientData *) NULL, (Tcl_CmdDeleteProc *) NULL);
918
919     return TCL_OK;
920 }
921
922
923 /*
924  *----------------------------------------------------------------------
925  *
926  * MainEx -- Main program for Tk-based applications.
927  *
928  *----------------------------------------------------------------------
929  */
930 void
931 MainEx( int /*argc*/, char** /*argv*/, Tcl_AppInitProc *appInitProc,
932         Tcl_Interp *pintrp, char *fileName )
933 {
934     int code;
935
936     (*appInitProc)(pintrp);
937
938     if ( Commands_Init(pintrp) != TCL_OK)
939         Panic (pintrp,"Can't initialise commands!");
940
941     char set_path[1000];
942     strcat( strcat( strcpy( set_path, "set ::image_path \"" ), module_path ), "\"" );
943     code = Tcl_Eval( pintrp, set_path );
944
945     if (fileName != NULL)
946     {
947         char  script[1000];
948         strcat( strcat( strcpy( script, module_path ), "" ), fileName );
949         code = Tcl_EvalFile(pintrp, script);
950         if (code != TCL_OK)
951             Panic (pintrp,"Evaluate file error!");
952     }
953     else Tcl_SourceRCFile(pintrp);
954
955     Tcl_ResetResult(pintrp);
956
957     Tk_MainLoop();
958
959     Tcl_DeleteInterp(pintrp);
960     return;
961 }
962
963 /*
964  *----------------------------------------------------------------------
965  *
966  * WishPanic -- escape function.
967  *
968  *----------------------------------------------------------------------
969  */
970
971 void WishPanic TCL_VARARGS_DEF(char *,arg1)
972 {
973     va_list argList;
974     char buf[1024];
975     char *format;
976
977     format = TCL_VARARGS_START(char *,arg1,argList);
978     printf(buf, format, argList);
979 }
980
981 /*
982  *----------------------------------------------------------------------
983  *
984  * Panic -- error output & exit function.
985  *
986  *----------------------------------------------------------------------
987  */
988
989 void Panic (Tcl_Interp * pintrp, const char * pch)
990 {
991     printf("Thread %P:",Tcl_GetCurrentThread());
992     printf(pch);
993     printf("\n    Reason:");
994     printf(pintrp->result);
995     printf("\n");
996
997     Tcl_DeleteInterp(pintrp);
998     Tcl_Exit(1);
999 }
1000
1001 /*void Panic (Tcl_Interp * pintrp, const char * pch)
1002 {
1003     char buf[2048];
1004     sprintf(buf, "\nThread %p, Interpetator %p:\n",
1005         Tcl_GetCurrentThread(), pintrp);
1006
1007     Tcl_AddErrorInfo(pintrp, buf);
1008     Tcl_AddErrorInfo(pintrp, pch);
1009     TkpDisplayWarning(Tcl_GetVar(pintrp, "errorInfo",
1010     TCL_GLOBAL_ONLY), "Error in startup script");
1011     Tcl_DeleteInterp(pintrp);
1012     Tcl_Exit(1);
1013 }*/
1014
1015 /*
1016  *----------------------------------------------------------------------
1017  *
1018  * Tcl_AppInit -- Initialisation function.
1019  *
1020  *----------------------------------------------------------------------
1021  */
1022
1023
1024 int Tcl_AppInit(Tcl_Interp *pintrp)
1025 {
1026
1027     if (Tcl_InitStubs(pintrp, TCL_VERSION, 1) == NULL)
1028         Panic (pintrp,"Tcl stub's initialisation failed!");
1029
1030     if (Tcl_Init(pintrp) == TCL_ERROR)
1031         Panic (pintrp,"Tcl's initialisation failed!");
1032
1033     if (Tk_Init(pintrp) == TCL_ERROR)
1034         Panic (pintrp,"Tk's initialisation failed!");
1035
1036     return TCL_OK;
1037 }
1038
1039 // main body ------------------------------------------------------------------
1040
1041 int main(int argc, char* argv[])
1042 {
1043     module_path = GetPathFromModuleName( argv[0] );
1044
1045     Tcl_Interp* g_pInterp = Tcl_CreateInterp();
1046
1047     Tcl_SetPanicProc(WishPanic);
1048     Tcl_FindExecutable(argv[0]);
1049
1050     MainEx(argc, argv, Tcl_AppInit, g_pInterp, "cvcsdemo.tcl");
1051
1052     if (camtype == 1)
1053         cvcamExit();
1054
1055     if (camtype == 0)
1056         cvcamAVICloseFile(avifile);
1057
1058     return 0;
1059 }