www.pudn.com > webcam1.4.1.zip > dll.c
//Author: Peter Parente //Copyright: Licensed under the Academic Free License. See LICENSE.TXT for more details. // Patch from Philipp Spitzer #include#include #include "dll.h" HANDLE hEventOKToUpdate, hEventOKToGrab; HWND hWndC; LPBYTE pImage; DWORD dwSize; //Description: the start and end function of a DLL //Input: instance, reason for being called //Output: nothing important BOOL APIENTRY CALLBACK DllMain(HINSTANCE hInstance, DWORD fdwReason, PVOID pvReserved) { //select the proper action to execute based on the reason for being called switch(fdwReason) { case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; //when a process attaches to the DLL, create the events and initialize the variables //for that process case DLL_PROCESS_ATTACH: hEventOKToUpdate = CreateEvent(NULL, TRUE, TRUE, NULL); hEventOKToGrab = CreateEvent(NULL, TRUE, FALSE, NULL); pImage = NULL; hWndC = NULL; dwSize = 0; break; //when a process detaches from the DLL, stop any image capturing and destroy the window; //note that the window must be disconnected from the imaging device before this message //is passed otherwise a DLL_THREAD_DETACH message is sent and the DLL gets stuck; //the close function MUST be called before the process is detached or else a crash will //occur case DLL_PROCESS_DETACH: capSetCallbackOnFrame(hWndC, NULL); capPreview(hWndC, FALSE); DestroyWindow(hWndC); hWndC = NULL; dwSize = 0; break; } return TRUE; } //Description: gets the name of an imaging device associated with a given ID number //Input: digitizer ID number and a dummy string //Output: returns success (non-negative) or failure, digitizer name in dummy string EXPORT long GetDigitizer(long lID, CHAR *szName) { CHAR szVer[80]; CHAR szTemp[80]; //get the name of the capture device associated with the given ID if(!capGetDriverDescription (lID, szTemp, sizeof(szTemp), szVer, sizeof(szVer))) return -1; //copy the new device name over the dummy string provided by LabView else strcpy(szName, szTemp); return 0; } //Description: callback function for capture preview mode //Input: window handle of the child window in which to draw the image, structure // containing buffer data and length information (and more) //Output: nothing important LRESULT CALLBACK capFrame(HWND hWnd, LPVIDEOHDR lpVHdr) { //indicate that it's not OK to grab ResetEvent(hEventOKToGrab); //wait until it's OK to update WaitForSingleObject(hEventOKToUpdate, INFINITE); //point to the current frame pImage = lpVHdr->lpData; dwSize = lpVHdr->dwBytesUsed; //indicate it's OK to grab again SetEvent(hEventOKToGrab); return 0; } //Description: copies the current captured frame into a buffer provided //Input: length of the LabView buffer and LabView buffer //Output: returns success (non-negative) or failure EXPORT long Grab(long LVPictLength, unsigned char *LVPict) { DWORD i, j; //if the image previewing process has not yet begun, then don't grab anything if(pImage == NULL) return -1; if(dwSize*4 != (unsigned long) LVPictLength*3) return -2; //indicate that it's not OK to update ResetEvent(hEventOKToUpdate); //wait until it's OK to grab WaitForSingleObject(hEventOKToGrab, INFINITE); //copy current image into provided buffer; //not working quite right, the color information //is not being returned to LabView the way it used to be with the old DLL //(the gray channel is saturated for some reason); probably not hard to fix j = 0; for(i=dwSize-1; i>2; i-=3) { LVPict[j++] = (pImage[i]+pImage[i-1]+pImage[i-2])/3; LVPict[j++] = pImage[i]; LVPict[j++] = pImage[i-1]; LVPict[j++] = pImage[i-2]; } //indicate it's OK to update again SetEvent(hEventOKToUpdate); return 0; } //Description: sets up an imaging device for capture operations //Input: digitizer ID number and a dummy string //Output: returns success (non-negative) or failure EXPORT long SetUp(long driver, long width, long height){ //reset the image and size variables pImage = NULL; dwSize = 0; //make sure we don't already have a window if(hWndC == NULL) { //create the capture window, the window is currently being draw in the top left corner //because the buffer is filled with nothing if it is not being drawn on the screen; //only a window size of 1x1 is needed to get this to work hWndC = capCreateCaptureWindow(TEXT("Webcam Capture Window"), WS_CHILD | WS_VISIBLE, 0, 0, 1, 1, GetDesktopWindow(), 0); } //connect the selected driver to the window if(!capDriverConnect(hWndC, driver)) { DestroyWindow(hWndC); return -1; } //create a frame capture callback function if(!capSetCallbackOnFrame(hWndC, capFrame)) { capDriverDisconnect(hWndC); DestroyWindow(hWndC); return -1; } //begin previewing capPreviewRate(hWndC, 66); if(!capPreview(hWndC, TRUE)) { capDriverDisconnect(hWndC); DestroyWindow(hWndC); return -1; } return 0; } //Description: disconnects a capture window from a capture device // must be called before a process is dettached from the DLL //Input: none //Output: none EXPORT void Close(void) { capDriverDisconnect(hWndC); } //Description: shows a dialog box with web cam format options in it // not yet implemented because not sure which dialogs should be shown for given values //functions to call are commented out below //Input: the dialog to show //Output: none EXPORT void ShowDialog(long whichDialog) { if(whichDialog==0) { capDlgVideoFormat(hWndC); } else if(whichDialog==1) { capDlgVideoDisplay(hWndC); } }