1 /*M///////////////////////////////////////////////////////////////////////////////////////
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
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.
10 // Intel License Agreement
11 // For Open Source Computer Vision Library
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
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.
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.
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.
40 //M*/// HawkDoc.cpp : implementation of the CHawkDoc class
51 #include "HawkOptions.h"
52 #include "QuickWatch.h"
53 #include "wordcolors.h"
75 #include "CVEiCL\EiC\src\error.h"
76 #include "CVEiCL\EiC\src\preproc.h"
78 void set_highgui_mark(jmp_buf* mark);
81 void init_signal_handlers();
83 int __cdecl DS_ON_SIZE(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, int* ret);
84 unsigned long __stdcall ProcessEicErr(void* hawkDoc, int show = 1);
85 unsigned long __stdcall ProcessEicOut(void* hawkDoc);
86 unsigned long __stdcall RunScript(void*);
87 unsigned long _stdcall ReadPipeStream(void* data);
88 void __cdecl ImageTransform(void* in);
96 #define EIC_OUT ((CHawkApp*)AfxGetApp())->m_eicOut
97 #define EIC_ERR ((CHawkApp*)AfxGetApp())->m_eicErr
100 #define new DEBUG_NEW
102 static char THIS_FILE[] = __FILE__;
105 /////////////////////////////////////////////////////////////////////////////
108 IMPLEMENT_DYNCREATE(CHawkDoc, CDocument)
110 BEGIN_MESSAGE_MAP(CHawkDoc, CDocument)
111 //{{AFX_MSG_MAP(CHawkDoc)
112 ON_COMMAND(ID_RUN, OnRun)
113 ON_UPDATE_COMMAND_UI(ID_RUN, OnUpdateRun)
114 ON_COMMAND(ID_RUNDS, OnRunds)
115 ON_UPDATE_COMMAND_UI(ID_RUNDS, OnUpdateRunds)
116 ON_COMMAND(ID_STOPDS, OnStopds)
117 ON_UPDATE_COMMAND_UI(ID_STOPDS, OnUpdateStopds)
118 ON_COMMAND(ID_OPTIONS_CONFIGURATION, OnOptionsConfiguration)
119 ON_COMMAND(ID_OPTIONS_COLORS, OnOptionsColors)
120 ON_UPDATE_COMMAND_UI(ID_OPTIONS_COLORS, OnUpdateOptionsColors)
121 ON_COMMAND(ID_FILE_CLOSE, OnFileClose)
122 ON_UPDATE_COMMAND_UI(ID_FILE_CLOSE, OnUpdateFileClose)
123 ON_COMMAND(ID_FILE_SAVE, OnFileSave)
124 ON_COMMAND(ID_FILE_SAVE_AS, OnFileSaveAs)
125 ON_COMMAND(ID_EIC_QWATCH, OnEicQwatch)
129 /////////////////////////////////////////////////////////////////////////////
130 // CHawkDoc construction/destruction
132 CHawkDoc::CHawkDoc() /*: m_DSWnd(new CDSWnd)*/
138 m_hScriptMutex = NULL;
139 m_hScriptExec = NULL;
140 SetModifiedFlag(FALSE);
143 CHawkDoc::~CHawkDoc()
145 /* Close the therad... */
146 CHawkApp* app = (CHawkApp*)AfxGetApp();
147 // app->CloseEiCHandles();
148 if(WaitForSingleObject(m_hScriptExec, 0) == WAIT_TIMEOUT)
150 TerminateThread(m_hScriptExec, 0);
152 if(WaitForSingleObject( m_hThread, 0) == WAIT_TIMEOUT)
154 TerminateThread(m_hThread, 0);
156 CMainFrame* frame = (CMainFrame*)AfxGetMainWnd();
157 frame->SetIntRun(FALSE);
160 if(m_hScriptExec) CloseHandle(m_hScriptExec);
161 if(m_hScriptMutex) CloseHandle(m_hScriptMutex);
164 BOOL CHawkDoc::OnNewDocument()
166 if (!CDocument::OnNewDocument())
169 // TODO: add reinitialization code here
170 // (SDI documents will reuse this document)
177 /////////////////////////////////////////////////////////////////////////////
178 // CHawkDoc serialization
180 void CHawkDoc::Serialize(CArchive& ar)
182 CEditView* pView = GetHawkView();
183 pView->SerializeRaw(ar);
191 pView->GetEditCtrl().SetModify(FALSE);
195 /////////////////////////////////////////////////////////////////////////////
196 // CHawkDoc diagnostics
199 void CHawkDoc::AssertValid() const
201 CDocument::AssertValid();
204 void CHawkDoc::Dump(CDumpContext& dc) const
210 /////////////////////////////////////////////////////////////////////////////
213 void CHawkDoc::OnRun()
220 CHawkApp* app = (CHawkApp*)AfxGetApp();
221 CMainFrame* frame = (CMainFrame*)AfxGetMainWnd();
223 if(app->GetSBRun() && IsModified())
226 SetModifiedFlag(FALSE);
233 frame->SetIntRun(TRUE);
234 frame->m_pRunDoc = this;
241 mname.Format("Script semaphore,doc=0x%p", this);
242 m_hScriptMutex = CreateMutex(0, TRUE, LPCTSTR(mname));
248 m_hScriptExec = CreateThread(0, 0, RunScript, this, 0, &threadID);
250 // m_hThread = CreateThread(0, 0, ProcessEicOut, this, 0, &threadID);
252 // Let the script execution start...
253 ReleaseMutex(m_hScriptMutex);
254 while(m_execState == TRUE);
256 WaitForSingleObject(m_hScriptMutex, INFINITE);
260 void CHawkDoc::OnUpdateRun(CCmdUI* pCmdUI)
262 CHawkView* pHawkView = GetHawkView();
263 if(!::IsWindow(pHawkView->m_hWnd) || IsRunning())
265 pCmdUI->Enable(FALSE);
269 pCmdUI->Enable(pHawkView->GetBufferLength());
273 CHawkView* CHawkDoc::GetHawkView()
280 POSITION pos = GetFirstViewPosition();
284 pView = GetNextView(pos);
285 if(pView->IsKindOf(RUNTIME_CLASS(CHawkView)))
287 m_pHawkView = static_cast<CHawkView*>(pView);
297 void GenerateExceptionString(DWORD code, char* buffer)
301 case EXCEPTION_ACCESS_VIOLATION:
302 strcpy(buffer, "The thread attempted to read from or write to a virtual address \
303 for which it does not have the appropriate access.");
305 case EXCEPTION_BREAKPOINT: strcpy(buffer, "A breakpoint was encountered.");
306 case EXCEPTION_FLT_DIVIDE_BY_ZERO: strcpy(buffer, "The thread attempted to divide a floating-point \
307 value by a floating-point divisor of zero.");
308 case EXCEPTION_FLT_INVALID_OPERATION: strcpy(buffer, "This exception represents any floating-point \
309 exception not included in this list.");
310 case EXCEPTION_FLT_OVERFLOW: strcpy(buffer, "The exponent of a floating-point operation is greater \
311 than the magnitude allowed by the corresponding type.");
312 case EXCEPTION_FLT_UNDERFLOW: strcpy(buffer, "The exponent of a floating-point operation is less \
313 than the magnitude allowed by the corresponding type.");
314 case EXCEPTION_INT_DIVIDE_BY_ZERO: strcpy(buffer, "The thread attempted to divide an integer value \
315 by an integer divisor of zero.");
316 case EXCEPTION_INT_OVERFLOW: strcpy(buffer, "The result of an integer operation caused a carry out \
317 of the most significant bit of the result.");
321 sprintf(buffer, "Code 0x%08x.", code);
328 extern char* EiC_CurrentFile;
329 extern int EiC_CurrentLine;
331 int _Hawk_EiC_parseString(char* str, void* hawkDoc)
336 EiC_parseString(str);
338 __except(EXCEPTION_EXECUTE_HANDLER)
342 CMainFrame* frame = (CMainFrame*)AfxGetMainWnd();
343 CHawkDoc* pDoc = (CHawkDoc*)hawkDoc;
344 frame->SetIntRun(FALSE);
346 pDoc->m_hScriptExec = 0;
347 GenerateExceptionString(GetExceptionCode(), ex_info);
348 sprintf(info, "Exception in file %s, line %d: \n%s", EiC_CurrentFile, EiC_CurrentLine,
351 EiC_parseString(":reset");
355 EiC_parseString(str);
356 #endif /* HAWK_TEST */
360 unsigned long __stdcall RunScript(void* hawkDoc)
363 CHawkApp* app = (CHawkApp*)AfxGetApp();
364 CHawkDoc* pDoc = (CHawkDoc*)hawkDoc;
365 CMainFrame* frame = (CMainFrame*)AfxGetMainWnd();
366 CString fileName = pDoc->GetPathName();
367 char drive[_MAX_DRIVE], path[_MAX_PATH], file[_MAX_PATH], ext[_MAX_PATH];
368 _splitpath(LPCTSTR(fileName), drive, path, file, ext);
369 CString spath = CString(drive) + path;
370 fileName = CString(file) + ext;
372 char curDir[_MAX_PATH];
373 GetCurrentDirectory(_MAX_PATH, curDir);
374 init_signal_handlers();
376 // pDoc->m_readMutex = CreateMutex(NULL, TRUE, "EiC read mutex(for threads)");
379 frame->SetIntRun(FALSE);
381 while(pDoc->m_execState == FALSE);
382 while(WaitForSingleObject(pDoc->m_hScriptMutex, 10) != WAIT_OBJECT_0)
385 if(PeekMessage(&message, NULL, 0, 0, PM_REMOVE))
387 TranslateMessage(&message);
388 DispatchMessage(&message);
391 pDoc->m_execState = FALSE;
392 ReleaseMutex(pDoc->m_hScriptMutex);
394 /* Starting the execution... */
395 frame->SetIntRun(TRUE);
396 frame->SetDocRun(pDoc);
398 /* Clean the error stream */
399 ProcessEicErr(pDoc, 0);
401 EiC_parseString("#pragma push_unsafeptr");
402 CString inString = CString("#include \"") + fileName + CString("\"");
404 int ret = setjmp(app->m_mark);
407 // Execute the script
408 LPTSTR pstr = const_cast<char*>(LPCTSTR(inString));
409 SetCurrentDirectory(spath);
410 retval = _Hawk_EiC_parseString(pstr, hawkDoc);
411 SetCurrentDirectory(curDir);
415 SetCurrentDirectory(curDir);
416 // Catched long jump:
417 wrapexcept_t* err = (wrapexcept_t*)ret;
418 switch(err->result_code)
421 AfxMessageBox(err->message);
432 cvDestroyAllWindows();
439 //detach_all_controls();
440 inString = CString(":clear ") + fileName;//pDoc->GetPathName();
441 EiC_parseString(const_cast<char*>(LPCTSTR(inString)));
442 EiC_parseString("#pragma pop_ptr");
443 // EiC_parseString(":reset");
447 if(ProcessEicErr(pDoc))
449 // An error has been detected
452 // Return to the initial state of EiC
453 // EiC_parseString(":reset");// Commented because of possible EiC reset bug
460 /* This function should not be called... */
461 unsigned long __stdcall ProcessEicOut(void* hawkDoc)
463 CHawkDoc* pDoc = (CHawkDoc*)hawkDoc;
464 CHawkApp* app = (CHawkApp*)AfxGetApp();
465 HANDLE mutices[2]; /* Great spelling! */
466 mutices[0] = app->m_printfMutex;
467 mutices[1] = pDoc->m_readMutex;
468 // long pos = tell(EIC_OUT.read);
470 // fputc(0, EIC_OUT.write);
471 // fflush(EIC_OUT.write);
473 long buffer_size = 2048;
474 // char* textBuffer = (char*)malloc(buffer_size + 2);
475 // char* temp = textBuffer;
480 DWORD ret = WaitForMultipleObjects(2, mutices, FALSE, INFINITE);
481 if(ret != WAIT_OBJECT_0)
486 CString buf = app->m_EiCOut;
487 app->m_EiCOut.Empty();
488 ReleaseMutex(app->m_printfMutex);
489 pDoc->GetLogView()->AddString(LPCTSTR(buf));
491 /* if(textBuffer[out - 1] == 0)
499 // Now it is safe to close the application
500 ((CMainFrame*)AfxGetMainWnd())->SetIntRun(FALSE);
505 unsigned long __stdcall ProcessEicErr(void* hawkDoc, int show)
507 CHawkDoc* pDoc = (CHawkDoc*)hawkDoc;
510 rewind(EIC_ERR.read);
512 long buffer_size = 2048;
513 char* textBuffer = (char*)malloc(buffer_size);
514 char* temp = textBuffer;
515 int err, err_total = 0;
518 err = _read(_fileno(EIC_ERR.read), temp, buffer_size);
520 if(err < buffer_size)
525 temp = (char*)malloc(buffer_size + err_total);
526 memcpy(temp, textBuffer, err_total);
529 temp = &textBuffer[err_total];
534 if(textBuffer[err_total-1] == 26 || textBuffer[err_total-1] == 0)
536 textBuffer[--err_total] = 0;
540 textBuffer[err_total] = 0;
542 AfxMessageBox(textBuffer);
548 /* Clear the file... */
549 _chsize(_fileno(EIC_ERR.read), 0);
550 rewind(EIC_ERR.read);
554 unsigned long _stdcall ReadPipeStream(void* pdata)
556 data_pipe* data = static_cast<data_pipe*>(pdata);
561 OutText += fgetc(data->pipe.read);
563 while(OutText.GetAt(OutText.GetLength()) != 26);
565 data->text = _strdup(LPCTSTR(OutText));
570 CLogView* CHawkDoc::GetLogView()
577 POSITION pos = GetFirstViewPosition();
581 pView = GetNextView(pos);
582 if(pView->IsKindOf(RUNTIME_CLASS(CLogView)))
584 m_pLogView = static_cast<CLogView*>(pView);
594 BOOL CHawkDoc::Initialize()
596 GetHawkView()->UpdateCursorPos();
600 // An example of a bad idea. I tried to divide a C source into parts
601 // that can be accepted by EiC, for instance, single lines finished by a semicolon
602 // Put off to be on the safe side. Hope I'll never return to this idea.
603 void CHawkDoc::ParseString()
607 int bracketCount = 0;
609 char* text = new char[strlen(m_pScript)];
612 m_parsedStrings.RemoveAll();
613 for(i = 0; i < strlen(m_pScript); i++)
626 if(!braceCount && !bracketCount)
628 memcpy(text, m_pScript + start, i - start + 1);
629 text[i - start + 1] = 0;
633 m_parsedStrings.Add(str);
643 if(!braceCount && !bracketCount)
645 memcpy(text, m_pScript + start, i - start + 1);
646 text[i - start + 1] = 0;
651 m_parsedStrings.Add(str);
657 if(i == 0 || text[i - 1] == 10 || text[i - 1] == 13)
667 void CHawkDoc::OnRunds()
671 // We're already running
675 CHawkApp* app = (CHawkApp*)AfxGetApp();
676 if(app->GetSBRun() && IsModified())
685 if(ParseTransformFunction())
687 m_dsSimpleMode = TRUE;
688 CMainFrame* frame = (CMainFrame*)AfxGetMainWnd();
689 frame->SetIntRun(TRUE);
690 frame->m_pRunDoc = this;
691 frame->RunDS(ImageTransform);
695 void CHawkDoc::OnUpdateRunds(CCmdUI* pCmdUI)
697 pCmdUI->Enable(0/*((CMainFrame*)AfxGetMainWnd())->IsDirectShowOn()*/);
700 static void __cdecl ImageTransform(void* in)
702 CHawkApp* app = (CHawkApp*)AfxGetApp();
704 WaitForSingleObject(app->m_printfMutex, INFINITE);
705 TRACE0("\nCaptured printf mutex...");
706 IplImage* image = static_cast<IplImage*>(in);
709 inString.Format("__HAWK_IMAGE_TRANSFORM((IPLIMAGE)0x%x);", (int)in);
710 EiC_parseString(const_cast<char*>(LPCTSTR(inString)));
711 TRACE0("Preparing to release printf mutex...");
712 ReleaseMutex(app->m_printfMutex);
713 TRACE0("\nReleased printf mutex...");
716 BOOL CHawkDoc::ParseTransformFunction()
718 const char* dir = ((CHawkApp*)AfxGetApp())->GetModulePath();
719 char* tmpname = _strdup(_tempnam(dir, ""));
722 AfxMessageBox("Could not create a temporary file name");
726 m_tempName = CString(tmpname);
727 FILE* fp = fopen(tmpname, "wt");
730 AfxMessageBox("Could not open a temporary file");
734 fprintf(fp, "void __HAWK_IMAGE_TRANSFORM(IPPIIMAGE ds_image)\n");
736 fprintf(fp, "#include \"%s\"\n", GetPathName());
740 EiC_parseString("#pragma push_unsafeptr");
742 str.Format("#include \"%s\"", tmpname);
744 EiC_parseString(const_cast<char*>(LPCTSTR(str)));
745 EiC_parseString("#pragma pop_ptr");
747 return !ProcessEicErr(this);
750 void CHawkDoc::ClearTransformFunction()
753 inString.Format(":clear %s", LPCTSTR(m_tempName));
754 EiC_parseString(const_cast<char*>(LPCTSTR(inString)));
755 remove(const_cast<char*>(LPCTSTR(m_tempName)));
759 unsigned long __stdcall _StopDS(void* doc)
761 CMainFrame* frame = (CMainFrame*)AfxGetMainWnd();
762 CHawkApp* app = (CHawkApp*)AfxGetApp();
763 CHawkDoc* pDoc = (CHawkDoc*)doc;
764 WaitForSingleObject(app->m_printfMutex, INFINITE);
766 // VERIFY(m_DSWnd->DestroyWindow());
767 cvDestroyWindow("DirectShow");
768 // Clear the CVEiCL scope
769 if(pDoc->m_dsSimpleMode)
770 pDoc->ClearTransformFunction();
771 ReleaseMutex(app->m_printfMutex);
772 /* FILE* out = ((CHawkApp*)AfxGetApp())->m_eicOut.write;
775 if(pDoc->m_dsSimpleMode)
777 frame->SetIntRun(FALSE);
784 void CHawkDoc::OnStopds()
787 CreateThread(NULL, 0, _StopDS, this, 0, &tID);
790 void CHawkDoc::OnUpdateStopds(CCmdUI* pCmdUI)
792 pCmdUI->Enable(((CMainFrame*)AfxGetMainWnd())->IsDSRunning());
795 BOOL CHawkDoc::IsRunning()
797 CMainFrame* frame = (CMainFrame*)AfxGetMainWnd();
798 if(frame->IsIntRun() || frame->IsDSRunning())
800 // We're already running
809 BOOL CHawkDoc::CanCloseFrame(CFrameWnd* pFrame)
811 return !IsRunning() && !((CMainFrame*)AfxGetMainWnd())->IsDSRunning();
814 void CHawkDoc::OnOptionsConfiguration()
816 CHawkApp* app = (CHawkApp*)AfxGetApp();
817 CHawkOptions dlg(app->GetErrLevel(), app->GetSBRun());
818 if(dlg.DoModal() == IDOK)
820 app->SetErrLevel(dlg.m_errLevel ? safe : unsafe);
821 app->SetSBRun(dlg.m_sbRun);
825 BOOL CHawkDoc::IsModified()
827 // return GetHawkView()->m_edit.GetModify();
828 return CDocument::IsModified();
832 void CHawkDoc::OnOptionsColors()
835 GetHawkView()->Scheme = wc.DoModal(GetHawkView()->Scheme);
838 void CHawkDoc::OnUpdateOptionsColors(CCmdUI* pCmdUI)
843 BOOL CHawkDoc::OnOpenDocument(LPCTSTR lpszPathName)
845 if (!CDocument::OnOpenDocument(lpszPathName))
848 char drive[_MAX_DRIVE];
850 char fname[_MAX_FNAME];
852 _splitpath(lpszPathName, drive, path, fname, fext);
854 VERIFY(::SetCurrentDirectory(LPCTSTR(CString(drive) + CString(path))));
858 /* Currently this function should not be called! */
859 void CHawkDoc::OnFileClose()
861 /* Close the therad... */
862 CHawkApp* app = (CHawkApp*)AfxGetApp();
863 app->CloseEiCHandles();
864 if(WaitForSingleObject(m_hScriptExec, 0) == WAIT_TIMEOUT)
866 TerminateThread(m_hScriptExec, 0);
868 if(WaitForSingleObject( m_hThread, 0) == WAIT_TIMEOUT)
870 TerminateThread(m_hThread, 0);
872 app->InitEiCHandles();
874 CMainFrame* frame = (CMainFrame*)AfxGetMainWnd();
875 frame->SetIntRun(FALSE);
878 CDocument::OnFileClose();
881 void CHawkDoc::OnUpdateFileClose(CCmdUI* pCmdUI)
883 pCmdUI->Enable(!IsRunning());
886 int play_ds(void (*transform_image)(IplImage*))
888 CMainFrame* frame = (CMainFrame*)AfxGetMainWnd();
889 if(!frame->IsDirectShowOn())
893 frame->m_pRunDoc->m_dsSimpleMode = FALSE;
894 frame->RunDS((void(*)(void*))transform_image, FALSE);
898 void CHawkDoc::OnFileSave()
900 CDocument::OnFileSave();
901 SetModifiedFlag(FALSE);
904 void CHawkDoc::OnFileSaveAs()
906 CDocument::OnFileSaveAs();
907 SetModifiedFlag(FALSE);
910 void CHawkDoc::OnEicQwatch()