This is the latest WPILib src, VisionSample2013, cRIO image, ... pulled down from firstforge.wpi.edu.

There might be risks in using the top of tree rather than an official release, but the commit messages do mention fixes for some deadlocks and race conditions.

git-svn-id: https://robotics.mvla.net/svn/frc971/2013/trunk/src@4066 f308d9b7-e957-4cde-b6ac-9a88185e7312
diff --git a/azaleasource/WPILibCProgramming/trunk/WPILib/Vision2009/AxisCamera.cpp b/azaleasource/WPILibCProgramming/trunk/WPILib/Vision2009/AxisCamera.cpp
new file mode 100644
index 0000000..d3fe857
--- /dev/null
+++ b/azaleasource/WPILibCProgramming/trunk/WPILib/Vision2009/AxisCamera.cpp
@@ -0,0 +1,1021 @@
+

+/********************************************************************************

+*  Project   		: FIRST Motor Controller

+*  File Name  		: AxisCamera.cpp        

+*  Contributors 	: TD, ELF, JDG, SVK

+*  Creation Date 	: July 29, 2008

+*  Revision History	: Source code & revision history maintained at sourceforge.WPI.edu    

+*  File Description	: Axis camera access for the FIRST Vision API

+*      The camera task runs as an independent thread 

+*/    

+/*----------------------------------------------------------------------------*/

+/*        Copyright (c) FIRST 2008.  All Rights Reserved.                     */

+/*  Open Source Software - may be modified and shared by FRC teams. The code  */

+/*  must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */

+/*----------------------------------------------------------------------------*/                   

+

+

+#include "sockLib.h" 

+#include "vxWorks.h" 

+

+#include "errno.h"

+#include "fioLib.h"

+#include "hostLib.h" 

+#include "inetLib.h" 

+#include "signal.h"

+#include "sigLib.h"		// for signal

+#include <string>

+#include "time.h"

+#include "usrLib.h"

+

+#include "AxisCamera.h" 

+#include "BaeUtilities.h"

+#include "FrcError.h"

+#include "Task.h"

+#include "Timer.h"

+#include "VisionAPI.h"

+

+/** packet size */

+#define DEFAULT_PACKET_SIZE 512

+

+/** Private NI function to decode JPEG */ 

+IMAQ_FUNC int Priv_ReadJPEGString_C(Image* _image, const unsigned char* _string, UINT32 _stringLength); 

+

+// To locally enable debug printing: set AxisCamera_debugFlag to a 1, to disable set to 0

+int AxisCamera_debugFlag = 0;

+#define DPRINTF if(AxisCamera_debugFlag)dprintf

+

+/** @brief Camera data to be accessed globally */

+struct {

+	int readerPID; // Set to taskID for signaling

+	int index; /* -1,0,1 */

+	int	acquire; /* 0:STOP CAMERA; 1:START CAMERA */

+	int cameraReady;  /* 0: CAMERA NOT INITIALIZED; 1: CAMERA INITIALIZED */

+	int	decode; /* 0:disable decoding; 1:enable decoding to HSL Image */

+	struct {

+		//

+		// To find the latest image timestamp, access:

+		// globalCamera.data[globalCamera.index].timestamp

+		//

+		double timestamp;       // when image was taken

+		char*	cameraImage;    // jpeg image string

+		int cameraImageSize;    // image size

+		Image* decodedImage;    // image decoded to NI Image object

+		int decodedImageSize;   // size of decoded image

+	}data[2];

+	int cameraMetrics[CAM_NUM_METRICS];

+}globalCamera;

+

+/* run flag */

+static short cont = 0;

+

+/**

+ * @brief Get the most recent camera image.

+ * Supports IMAQ_IMAGE_RGB and IMAQ_IMAGE_HSL.

+ * @param image Image to return to; image must have been first created using frcCreateImage. 

+ * When you are done, use frcDispose.

+ * @param timestamp Timestamp to return; will record the time at which the image was stored.

+ * @param lastImageTimestamp Input - timestamp of last image; prevents serving of stale images

+ * @return 0 is failure, 1 is success

+ * @sa frcCreateImage(), frcDispose()

+ */

+int GetImageBlocking(Image* image, double *timestamp, double lastImageTimestamp)

+{

+	char funcName[]="GetImageBlocking";

+	int success;

+	double startTime = GetTime();

+	

+	while (1)

+	{

+		success = GetImage(image, timestamp);

+		if (!success) return (success);

+		

+		if (*timestamp > lastImageTimestamp)

+			return (1); // GOOD IMAGE RETURNED

+

+		if (GetTime() > (startTime + MAX_BLOCKING_TIME_SEC))

+		{

+			imaqSetError(ERR_CAMERA_BLOCKING_TIMEOUT, funcName);

+			globalCamera.cameraMetrics[CAM_BLOCKING_TIMEOUT]++;

+			return (0); // NO IMAGE AVAILABLE WITHIN specified time

+		}

+		globalCamera.cameraMetrics[CAM_BLOCKING_COUNT]++;

+		taskDelay (1);

+	}

+}

+

+/**

+ * @brief Verifies that the camera is initialized

+ * @return 0 for failure, 1 for success

+ */

+int CameraInitialized()

+{

+	char funcName[]="CameraInitialized";

+	int success = 0;

+	/* check to see if camera is initialized */

+	if (!globalCamera.cameraReady)  {

+		imaqSetError(ERR_CAMERA_NOT_INITIALIZED, funcName);

+		DPRINTF (LOG_DEBUG, "Camera request before camera is initialized");

+		globalCamera.cameraMetrics[CAM_GETIMAGE_BEFORE_INIT]++;

+		globalCamera.cameraMetrics[CAM_GETIMAGE_FAILURE]++;

+		return success;

+	}

+	

+	if (globalCamera.index == -1){

+		imaqSetError(ERR_CAMERA_NO_BUFFER_AVAILABLE, funcName);

+		DPRINTF (LOG_DEBUG, "No camera image available");

+		globalCamera.cameraMetrics[CAM_GETIMAGE_BEFORE_AVAILABLE]++;

+		globalCamera.cameraMetrics[CAM_GETIMAGE_FAILURE]++;

+		return success;

+	}

+	return 1;

+}

+

+/**

+ * @brief Gets the most recent camera image, as long as it is not stale.

+ * Supported image types: IMAQ_IMAGE_RGB, IMAQ_IMAGE_HSL

+ * @param image Image to return, must have first been created with frcCreateImage or imaqCreate. 

+ * When you finish with the image, call frcDispose() to dispose of it.

+ * @param timestamp Returned timestamp of when the image was taken from the camera

+ * @return failure = 0, success = 1

+ */

+int GetImage(Image* image, double *timestamp)

+{

+	char funcName[]="GetImage";

+	int success = 0;

+	int readIndex;

+	int	readCount = 10;

+	double currentTime = time(NULL);

+	double currentImageTimestamp;

+

+	/* check to see if camera is initialized */

+	

+	if (!CameraInitialized()) {return success;}

+	

+	/* try readCount times to get an image */

+	while (readCount) {

+		readIndex = globalCamera.index;

+		if (!imaqDuplicate(image, globalCamera.data[readIndex].decodedImage)) {

+			int errorCode = GetLastVisionError(); 

+			DPRINTF (LOG_DEBUG,"Error duplicating image= %i  %s ", errorCode, GetVisionErrorText(errorCode));			

+		}

+		// save the timestamp to check before returning

+		currentImageTimestamp = globalCamera.data[readIndex].timestamp;

+		

+		// make sure this buffer is not being written to now

+		if (readIndex == globalCamera.index) break;

+		readCount--;

+	}

+	

+	/* were we successful ? */

+	if (readCount){

+		success = 1;

+		if (timestamp != NULL)

+			  *timestamp = currentImageTimestamp; // Return image timestamp	  

+	} else{

+		globalCamera.cameraMetrics[CAM_GETIMAGE_FAILURE]++;

+	}

+	

+	/* Ensure the buffered image is not too old - set this "stale time" above */

+	if (currentTime > globalCamera.data[globalCamera.index].timestamp + CAMERA_IMAGE_STALE_TIME_SEC){

+		DPRINTF (LOG_CRITICAL, "STALE camera image (THIS COULD BE A BAD IMAGE)");

+		imaqSetError(ERR_CAMERA_STALE_IMAGE, funcName);

+		globalCamera.cameraMetrics[CAM_STALE_IMAGE]++;

+		globalCamera.cameraMetrics[CAM_GETIMAGE_FAILURE]++;

+		success = 0;

+	}

+	globalCamera.cameraMetrics[CAM_GETIMAGE_SUCCESS]++;

+	return success;

+}

+

+/**

+ * @brief Method to get a raw image from the buffer

+ * @param imageData returned image data

+ * @param numBytes returned number of bytes in buffer

+ * @param currentImageTimestamp returned buffer time of image data

+ * @return 0 if failure; 1 if success

+ */

+int GetImageData(char** imageData, int* numBytes, double* currentImageTimestamp)

+{

+	int success = 0;

+	int readIndex;

+	int	readCount = 10;

+	int cameraImageSize;

+	char *cameraImageString;

+

+	/* check to see if camera is initialized */

+			

+	if (!CameraInitialized()) {return success;}

+			

+	/* try readCount times to get an image */

+	while (readCount) {

+		readIndex = globalCamera.index;

+		cameraImageSize = globalCamera.data[readIndex].cameraImageSize;

+		//cameraImageString = (Image *) malloc(cameraImageSize);

+		cameraImageString = new char[cameraImageSize];

+		if (NULL == cameraImageString) {

+					DPRINTF (LOG_DEBUG, "Unable to allocate cameraImage");

+					globalCamera.cameraMetrics[CAM_GETIMAGE_FAILURE]++;

+					return success;

+		}

+		memcpy (cameraImageString, globalCamera.data[readIndex].cameraImage, cameraImageSize);

+		*currentImageTimestamp = globalCamera.data[readIndex].timestamp;

+		// make sure this buffer is not being written to now

+		if (readIndex == globalCamera.index) break;

+		free (cameraImageString);

+		readCount--;

+	}

+	if (readCount){

+		*imageData = cameraImageString;

+		*numBytes = cameraImageSize;

+		return 1;

+	}		

+	return (OK);

+}

+

+/**

+ * @brief Blocking call to get images for PC.

+ * This should be called from a separate task to maintain camera read performance. 

+ * It is intended to be used for sending raw (undecoded) image data to the PC.

+ * @param imageData image data to return

+ * @param numBytes number of bytes in buffer

+ * @param timestamp timestamp of buffer returned

+ * @param lastImageTimestamp buffer time of last image data sent to PC

+ * @return 0 if failure; 1 if success

+ */

+int GetImageDataBlocking(char** imageData, int* numBytes, double* timestamp, double lastImageTimestamp)

+{

+

+	char funcName[]="GetImageDataBlocking";

+	int success;

+	double startTime = GetTime();

+	

+    *imageData = NULL;

+	while (1)

+	{

+		success = GetImageData(imageData, numBytes, timestamp);

+		if (!success) return (success);

+		

+		if (*timestamp > lastImageTimestamp)

+			return (1); // GOOD IMAGE DATA RETURNED

+

+        delete *imageData;

+        *imageData = NULL;

+

+		if (GetTime() > (startTime + MAX_BLOCKING_TIME_SEC))

+		{

+			imaqSetError(ERR_CAMERA_BLOCKING_TIMEOUT, funcName);

+			return (0); // NO IMAGE AVAILABLE WITHIN specified time

+		}

+		globalCamera.cameraMetrics[CAM_BLOCKING_COUNT]++;

+		taskDelay (1);

+	}

+}

+

+/**

+ * @brief Accessor for camera instrumentation data

+ * @param the counter queried

+ * @return the counter value

+ */

+int GetCameraMetric(FrcvCameraMetric metric)

+{	return globalCamera.cameraMetrics[metric];  }

+

+/**

+ * @brief Close socket & report error

+ * @param errstring String to print

+ * @param socket Socket to close

+ * @return error

+ */

+int CameraCloseSocket(char *errstring, int socket)

+{

+	DPRINTF (LOG_CRITICAL, "Closing socket - CAMERA ERROR: %s", errstring );

+	close (socket);

+	return (ERROR);

+}

+

+

+/**

+ * @brief Reads one line from the TCP stream.

+ * @param camSock         The socket.

+ * @param buffer          A buffer with bufSize allocated for it. 

+ *                        On return, bufSize-1 amount of data or data upto first line ending

+ *                        whichever is smaller, null terminated.

+ * @param bufSize         The size of buffer.

+ * @param stripLineEnding If true, strips the line ending chacters from the buffer before return.

+ * @return 0 if failure; 1 if success

+*/

+static int CameraReadLine(int camSock, char* buffer, int bufSize, bool stripLineEnding) {

+	char funcName[]="CameraReadLine";

+    // Need at least 3 bytes in the buffer to pull this off.

+	if (bufSize < 3) {

+		imaqSetError(ERR_CAMERA_FAILURE, funcName);

+		return 0;

+	}

+    //  Reduce size by 1 to allow for null terminator.

+    --bufSize;

+    //  Read upto bufSize characters.

+    for (int i=0;i < bufSize;++i, ++buffer) {

+        //  Read one character.

+        if (read (camSock, buffer, 1) <= 0) {

+    		imaqSetError(ERR_CAMERA_FAILURE, funcName);

+            return 0;

+        }

+        //  Line endings can be "\r\n" or just "\n". So always 

+        //  look for a "\n". If you got just a "\n" and 

+        //  stripLineEnding is false, then convert it into a \r\n

+        //  because callers expect a \r\n.

+        //  If the combination of the previous character and the current character

+        //  is "\r\n", the line ending

+        if (*buffer=='\n') {

+            //  If asked to strip the line ending, then set the buffer to the previous 

+            //  character.

+            if (stripLineEnding) {

+                if (i > 0 && *(buffer-1)=='\r') {

+                    --buffer;

+                }

+            }

+            else {

+                //  If the previous character was not a '\r', 

+                if (i == 0 || *(buffer-1)!='\r') {

+                    //  Make the current character a '\r'.

+                    *buffer = '\r';

+                    //  If space permits, add back the '\n'.

+                    if (i < bufSize-1) {

+                        ++buffer;

+                        *buffer = '\n';

+                    }

+                }

+                //  Set the buffer past the current character ('\n')

+                ++buffer;

+            }

+            break;

+        }

+    }

+    //  Null terminate.

+    *buffer = '\0';

+    return 1;

+}

+

+/**

+@brief Skips read data until the first empty line.

+

+@param camSock An open tcp socket to the camera to read the data from.

+@return sucess 0 if failure; 1 if success

+*/

+static int CameraSkipUntilEmptyLine(int camSock) {

+    char buffer[1024];

+    int success = 0;

+    while(1) {

+        success = CameraReadLine(camSock, buffer, sizeof(buffer), true);

+        if (*buffer == '\0') {

+            return success;

+        }

+    }

+    return success;

+}

+

+/**

+@brief Opens a socket.

+

+Issues the given http request with the required added information 

+and authentication. It  cycles through an array of predetermined 

+encrypted username, password combinations that we expect the users 

+to have at any point in time. If none of the username, password 

+combinations work, it outputs a "Unknown user or password" error.

+If the request succeeds, it returns the socket number.

+

+@param serverName The information about the host from which this request originates

+@param request   The request to send to the camera not including boilerplate or 

+                 authentication. This is usually in the form of "GET <string>"

+@return int - failure = ERROR; success = socket number;     

+*/

+static int CameraOpenSocketAndIssueAuthorizedRequest(const char* serverName, const char* request) 

+{

+    char funcName[]="cameraOpenSocketAndIssueAuthorizedRequest";

+	

+	struct sockaddr_in cameraAddr;

+	int sockAddrSize;  

+	int camSock = ERROR;    

+

+    // The camera is expected to have one of the following username, password combinations.

+    // This routine will return an error if it does not find one of these.

+    static const char* authenticationStrings[] = {

+        "RlJDOkZSQw==",     /* FRC, FRC */

+        "cm9vdDpwYXNz",     /* root, admin*/

+        "cm9vdDphZG1pbg=="  /* root, pass*/

+    };

+

+    static const int numAuthenticationStrings = sizeof(authenticationStrings)/sizeof(authenticationStrings[0]);

+	

+	static const char *requestTemplate = "%s "                              \

+                                         "HTTP/1.1\n"                       \

+                                         "User-Agent: HTTPStreamClient\n"   \

+                                         "Connection: Keep-Alive\n"         \

+                                         "Cache-Control: no-cache\n"        \

+                                         "Authorization: Basic %s\n\n";

+

+	int i = 0;

+    for (;i < numAuthenticationStrings;++i) {

+        char buffer[1024];

+

+        sprintf(buffer, requestTemplate, request, authenticationStrings[i]);

+

+        /* create camera socket */

+        //DPRINTF (LOG_DEBUG, "creating camSock" ); 

+        if ((camSock = socket (AF_INET, SOCK_STREAM, 0)) == ERROR) {

+    		imaqSetError(ERR_CAMERA_SOCKET_CREATE_FAILED, funcName);

+    		perror("Failed to create socket");

+    		return (ERROR);

+        }

+

+        sockAddrSize = sizeof (struct sockaddr_in);

+        bzero ((char *) &cameraAddr, sockAddrSize);

+        cameraAddr.sin_family = AF_INET;

+        cameraAddr.sin_len = (u_char) sockAddrSize;

+        cameraAddr.sin_port = htons (CAMERA_PORT);

+

+        if (( (int)(cameraAddr.sin_addr.s_addr = inet_addr (const_cast<char*>(serverName)) ) == ERROR) &&

+            ( (int)(cameraAddr.sin_addr.s_addr = hostGetByName (const_cast<char*>(serverName)) ) == ERROR)) 

+        {

+    		imaqSetError(ERR_CAMERA_CONNECT_FAILED, funcName);

+            return CameraCloseSocket("Failed to get IP, check hostname or IP", camSock);

+        }

+

+        //DPRINTF (LOG_INFO, "connecting camSock" ); 

+        if (connect (camSock, (struct sockaddr *) &cameraAddr, sockAddrSize) == ERROR) 	{

+    		imaqSetError(ERR_CAMERA_CONNECT_FAILED, funcName);

+            return CameraCloseSocket("Failed to connect to camera - check networ", camSock);

+        }

+

+        //DPRINTF (LOG_DEBUG, "writing GET request to camSock" ); 

+        if (write (camSock, buffer, strlen(buffer) ) == ERROR) {

+    		imaqSetError(ERR_CAMERA_CONNECT_FAILED, funcName);

+            return CameraCloseSocket("Failed to send GET request", camSock);

+        }

+

+        //  Read one line with the line ending removed.

+        if (!CameraReadLine(camSock, buffer, 1024, true)) {

+            return CameraCloseSocket("Bad response to GET request", camSock);

+        }

+

+        //  Check if the response is of the format HTTP/<version> 200 OK.

+        float discard;

+        if (sscanf(buffer, "HTTP/%f 200 OK", &discard) == 1) {

+            break;

+        }

+

+        //  We have to close the connection because in the case of failure

+        //  the server closes the connection.

+        close(camSock);

+    }

+    //  If none of the attempts were successful, then let the caller know.

+    if (numAuthenticationStrings == i) {

+		imaqSetError(ERR_CAMERA_AUTHORIZATION_FAILED, funcName);

+        fprintf(stderr, "Expected username/password combination not found on camera");

+        return ERROR;

+    }

+    return camSock;

+}

+

+

+/**

+ * @brief Sends a configuration message to the camera

+ * @param configString configuration message to the camera

+ * @return success: 0=failure; 1=success

+ */

+int ConfigureCamera(char *configString){

+	char funcName[]="ConfigureCamera";

+	char *serverName = "192.168.0.90";		/* camera @ */ 

+	int success = 0;

+	int camSock = 0;    

+	

+	/* Generate camera configuration string */

+	char * getStr1 = 

+		"GET /axis-cgi/admin/param.cgi?action=update&ImageSource.I0.Sensor.";

+	

+	char cameraRequest[strlen(getStr1) + strlen(configString)];

+    sprintf (cameraRequest, "%s%s",	getStr1, configString);

+	DPRINTF(LOG_DEBUG, "camera configuration string: \n%s", cameraRequest);

+	camSock = CameraOpenSocketAndIssueAuthorizedRequest(serverName, cameraRequest);

+	DPRINTF(LOG_DEBUG, "camera socket# = %i", camSock);

+	

+    //read response

+    success = CameraSkipUntilEmptyLine(camSock);

+	//DPRINTF(LOG_DEBUG, "succcess from CameraSkipUntilEmptyLine: %i", success);

+    char buffer[3];	// set property - 3

+    success = CameraReadLine(camSock, buffer, 3, true);

+	//DPRINTF(LOG_DEBUG, "succcess from CameraReadLine: %i", success);

+	DPRINTF(LOG_DEBUG, "line read from camera \n%s", buffer);

+    if (strcmp(buffer, "OK") != 0) {

+		imaqSetError(ERR_CAMERA_COMMAND_FAILURE, funcName);

+		DPRINTF(LOG_DEBUG, "setting ERR_CAMERA_COMMAND_FAILURE - OK not found");

+    }

+	DPRINTF (LOG_INFO, "\nConfigureCamera ENDING  success = %i\n", success );	

+

+	/* clean up */

+	close (camSock);

+	return (1);

+}

+

+

+/**

+ * @brief Sends a request message to the camera

+ * @param configString request message to the camera

+ * @param cameraResponse response from camera

+ * @return success: 0=failure; 1=success

+ */

+int GetCameraSetting(char *configString, char *cameraResponse){

+	char *serverName = "192.168.0.90";		/* camera @ */ 

+	int success = 0;

+	int camSock = 0;    

+	

+	/* Generate camera request string */

+	char * getStr1 = 

+		"GET /axis-cgi/admin/param.cgi?action=list&group=ImageSource.I0.Sensor.";

+	char cameraRequest[strlen(getStr1) + strlen(configString)];

+    sprintf (cameraRequest, "%s%s",	getStr1, configString);

+	DPRINTF(LOG_DEBUG, "camera configuration string: \n%s", cameraRequest);

+	camSock = CameraOpenSocketAndIssueAuthorizedRequest(serverName, cameraRequest);

+	DPRINTF(LOG_DEBUG, "return from CameraOpenSocketAndIssueAuthorizedRequest %i", camSock);

+	

+    //read response

+    success = CameraSkipUntilEmptyLine(camSock);

+    success = CameraReadLine(camSock, cameraResponse, 1024, true);

+	DPRINTF(LOG_DEBUG, "succcess from CameraReadLine: %i", success);

+	DPRINTF(LOG_DEBUG, "line read from camera \n%s", cameraResponse);

+	DPRINTF (LOG_INFO, "\nGetCameraSetting ENDING  success = %i\n", success );	

+

+	/* clean up */

+	close (camSock);

+	return (1);

+}

+

+/**

+ * @brief Sends a request message to the camera for image appearance property

+ * (resolution, compression, rotation)

+ * @param configString request message to the camera

+ * @param cameraResponse response from camera

+ * @return success: 0=failure; 1=success

+ */

+int GetImageSetting(char *configString, char *cameraResponse){

+	char *serverName = "192.168.0.90";		/* camera @ */ 

+	int success = 0;

+	int camSock = 0;    

+	

+	/* Generate camera request string */

+	char *getStr1 = "GET /axis-cgi/admin/param.cgi?action=list&group=Image.I0.Appearance.";

+	char cameraRequest[strlen(getStr1) + strlen(configString)];

+    sprintf (cameraRequest, "%s%s",	getStr1, configString);

+	DPRINTF(LOG_DEBUG, "camera configuration string: \n%s", cameraRequest);

+	camSock = CameraOpenSocketAndIssueAuthorizedRequest(serverName, cameraRequest);

+	DPRINTF(LOG_DEBUG, "return from CameraOpenSocketAndIssueAuthorizedRequest %i", camSock);

+	

+    //read response

+    success = CameraSkipUntilEmptyLine(camSock);

+    success = CameraReadLine(camSock, cameraResponse, 1024, true);

+	DPRINTF(LOG_DEBUG, "succcess from CameraReadLine: %i", success);

+	DPRINTF(LOG_DEBUG, "line read from camera \n%s", cameraResponse);

+	DPRINTF (LOG_INFO, "\nGetCameraSetting ENDING  success = %i\n", success );	

+

+	/* clean up */

+	close (camSock);

+	return (1);

+}

+

+

+#define MEASURE_SOCKET_TIME 1   

+

+/**

+ * @brief Manage access to the camera. Sets up sockets and reads images

+ * @param frames Frames per second 

+ * @param compression Camera image compression 

+ * @param resolution Camera image size 

+ * @param rotation Camera image rotation 

+ * @return error

+ */

+int cameraJPEGServer(int frames, int compression, ImageResolution resolution, ImageRotation rotation)

+{

+	char funcName[]="cameraJPEGServer";

+	char *serverName = "192.168.0.90";		/* camera @ */ 

+	cont = 1;

+	int errorCode = 0;

+	int printCounter = 0;

+	int	writeIndex;

+	int authorizeCount = 0;

+	int authorizeConfirmed = 0;

+	static const int authenticationStringsCount = 3;

+    static const char* authenticationStrings[] = {

+    		"cm9vdDphZG1pbg==", /* root, admin*/

+    		"RlJDOkZSQw==",     /* FRC, FRC */

+    		"cm9vdDpwYXNz=="    /* root, pass*/

+    };

+

+	DPRINTF (LOG_DEBUG, "cameraJPEGServer" ); 

+	

+	struct sockaddr_in cameraAddr;

+	int sockAddrSize;  

+	int camSock = 0;    

+

+	char resStr[10];

+	switch (resolution) {

+		case k640x480: { sprintf(resStr,"640x480"); break; }

+		case k320x240: { sprintf(resStr,"320x240"); break; }

+		case k160x120: { sprintf(resStr,"160x120"); break; }

+		default: {DPRINTF (LOG_DEBUG, "code error - resolution input" ); break; }

+	}

+	

+	/* Generate camera initialization string */

+	/* changed resolution to 160x120 from 320x240 */

+	/* supported resolutions are: 640x480, 640x360, 320x240, 160x120 */	

+	char * getStr1 = 

+	"GET /axis-cgi/mjpg/video.cgi?showlength=1&camera=1&";	

+		

+	char insertStr[100];

+	sprintf (insertStr, "des_fps=%i&compression=%i&resolution=%s&rotation=%i", 

+			frames, compression, resStr, (int)rotation);	

+	

+	char * getStr2 = " HTTP/1.1\n\

+User-Agent: HTTPStreamClient\n\

+Host: 192.150.1.100\n\

+Connection: Keep-Alive\n\

+Cache-Control: no-cache\n\

+Authorization: Basic %s;\n\n";

+

+	char getStr[strlen(getStr1) + strlen(insertStr) + strlen(getStr2)];      

+    sprintf (getStr, "%s:%s%s",	getStr1, insertStr, getStr2);

+

+	DPRINTF(LOG_DEBUG, "revised camera string: \n%s", getStr);

+	/* Allocation */

+	char tempBuffer[1024];

+    

+	RETRY:

+	Wait(0.1);  //bug fix - don't pester camera if it's booting

+	while (globalCamera.acquire == 0) Wait(0.1);

+

+	if (!authorizeConfirmed){

+	  if (authorizeCount < authenticationStringsCount){

+	    sprintf (tempBuffer, getStr, authenticationStrings[authorizeCount]);

+	  } else {

+		imaqSetError(ERR_CAMERA_AUTHORIZATION_FAILED, funcName);

+		fprintf(stderr, "Camera authorization failed ... Incorrect password on camera!!");

+		return (ERROR);

+	  }

+	}

+

+	while (1)

+	{

+	  globalCamera.cameraMetrics[CAM_SOCKET_INIT_ATTEMPTS]++;	  

+

+	  /* create camera socket */

+	  DPRINTF (LOG_DEBUG, "creating camSock" ); 

+	  if ((camSock = socket (AF_INET, SOCK_STREAM, 0)) == ERROR) {	

+		imaqSetError(ERR_CAMERA_SOCKET_CREATE_FAILED, funcName);

+		perror("Failed to create socket");

+		cont = 0;

+		return (ERROR);

+	  }

+

+	  sockAddrSize = sizeof (struct sockaddr_in);

+	  bzero ((char *) &cameraAddr, sockAddrSize);

+	  cameraAddr.sin_family = AF_INET;

+	  cameraAddr.sin_len = (u_char) sockAddrSize;

+	  cameraAddr.sin_port = htons (CAMERA_PORT);

+

+	  DPRINTF (LOG_DEBUG, "getting IP" );

+	  if (( (int)(cameraAddr.sin_addr.s_addr = inet_addr (serverName) ) == ERROR) &&

+		( (int)(cameraAddr.sin_addr.s_addr = hostGetByName (serverName) ) == ERROR)) 

+	  {	

+		  CameraCloseSocket("Failed to get IP, check hostname or IP", camSock);

+		continue;

+	  }

+	  

+	  DPRINTF (LOG_INFO, "Attempting to connect to camSock" ); 

+	  if (connect (camSock, (struct sockaddr *) &cameraAddr, sockAddrSize) == ERROR) 	{

+		imaqSetError(ERR_CAMERA_CONNECT_FAILED, funcName);

+		CameraCloseSocket("Failed to connect to camera - check network", camSock);

+		continue;

+	  }	  

+

+#if MEASURE_SOCKET_SETUP

+	  socketEndTime = GetTime(); 

+	  setupTime = socketEndTime - socketStartTime; 

+	  printf("\n***socket setup time = %g\n", setupTime );

+#endif	  

+	  

+	  globalCamera.cameraMetrics[CAM_SOCKET_OPEN]++;

+	  break;

+	} // end while (trying to connect to camera)

+

+	DPRINTF (LOG_DEBUG, "writing GET request to camSock" ); 

+	if (write (camSock, tempBuffer , strlen(tempBuffer) ) == ERROR) {

+		return CameraCloseSocket("Failed to send GET request", camSock);

+	}

+

+	//DPRINTF (LOG_DEBUG, "reading header" ); 

+	/* Find content-length, then read that many bytes */

+	int counter = 2;

+	char* contentString = "Content-Length: ";

+	char* authorizeString = "200 OK";

+	

+#define MEASURE_TIME 0

+#if MEASURE_TIME

+	//timing parameters - only measure one at the time

+	double loopStartTime = 0.0; // measuring speed of execution loop

+	double loopEndTime = 0.0;

+	double cameraStartTime = 0.0;

+	double cameraEndTime = 0.0;

+	double previousStartTime = 0.0;

+	int performanceLoopCounter = 0;

+	int maxCount = 30;

+#endif

+	

+	while (cont) {

+#if MEASURE_TIME

+		previousStartTime = loopStartTime;  // first time is bogus

+		loopStartTime = GetTime(); 

+#endif	

+		// If camera has been turned OFF, jump to RETRY

+		//if (globalCamera.acquire == 0) goto RETRY;

+		

+		/* Determine writer index */

+		if (globalCamera.index == 0)

+			writeIndex = 1;

+		else

+			writeIndex = 0;

+		

+		/* read header */

+		//TODO: check for error in header, increment ERR_CAMERA_HEADER_ERROR

+		char initialReadBuffer[DEFAULT_PACKET_SIZE] = "";

+		char intermediateBuffer[1];

+		char *trailingPtr = initialReadBuffer;

+		int trailingCounter = 0;

+		

+

+#if MEASURE_TIME

+		cameraStartTime = GetTime(); 

+#endif	

+

+		while (counter) {

+			if (read (camSock, intermediateBuffer, 1) <= 0) {

+				CameraCloseSocket("Failed to read image header", camSock);

+				globalCamera.cameraMetrics[ERR_CAMERA_HEADER_ERROR]++;

+				goto RETRY;

+			}

+

+			strncat(initialReadBuffer, intermediateBuffer, 1);

+			if (NULL != strstr(trailingPtr, "\r\n\r\n")) {

+

+				  if (!authorizeConfirmed){

+

+					  if (strstr(initialReadBuffer, authorizeString))

+					  {

+						  authorizeConfirmed = 1;

+						  /* set camera to initialized */

+						  globalCamera.cameraReady = 1; 

+					  }

+					  else

+					  {

+						  CameraCloseSocket("Not authorized to connect to camera", camSock);

+						  authorizeCount++;

+				  goto RETRY;

+					  }

+				}

+				--counter;

+			}

+			if (++trailingCounter >= 4) {

+				trailingPtr++;

+			}

+		}

+	

+		counter = 1;

+		char *contentLength = strstr(initialReadBuffer, contentString);

+		if (contentLength == NULL) {

+			globalCamera.cameraMetrics[ERR_CAMERA_HEADER_ERROR]++;

+			CameraCloseSocket("No content-length token found in packet", camSock);

+			goto RETRY;

+		}

+		/* get length of image content */

+		contentLength = contentLength + strlen(contentString);

+		globalCamera.data[writeIndex].cameraImageSize = atol (contentLength);

+		

+		if(globalCamera.data[writeIndex].cameraImage)

+			free(globalCamera.data[writeIndex].cameraImage);

+		//globalCamera.data[writeIndex].cameraImage = (Image *) malloc(globalCamera.data[writeIndex].cameraImageSize);

+		globalCamera.data[writeIndex].cameraImage = (char*)malloc(globalCamera.data[writeIndex].cameraImageSize);

+		if (NULL == globalCamera.data[writeIndex].cameraImage) {

+			return CameraCloseSocket("Failed to allocate space for imageString", camSock);

+		}

+		globalCamera.cameraMetrics[CAM_BUFFERS_WRITTEN]++;

+		

+		//

+		// This is a blocking camera read function, and will block if the camera

+		// has been disconnected from the cRIO.  If however the camera is

+		// POWERED OFF while connected to the cRIO, this function NEVER RETURNS

+		//

+		int bytesRead = fioRead (camSock, (char *)globalCamera.data[writeIndex].cameraImage,

+				globalCamera.data[writeIndex].cameraImageSize);

+

+#if MEASURE_TIME

+		cameraEndTime = GetTime(); 

+#endif	

+		

+		//DPRINTF (LOG_DEBUG, "Completed fioRead function - bytes read:%d", bytesRead);

+		if (bytesRead <= 0) {

+			CameraCloseSocket("Failed to read image data", camSock);

+			goto RETRY;

+		} else if (bytesRead != globalCamera.data[writeIndex].cameraImageSize){

+			fprintf(stderr, "ERROR: Failed to read entire image: readLength does not match bytes read");

+			globalCamera.cameraMetrics[CAM_BAD_IMAGE_SIZE]++;

+		}

+		// if decoding the JPEG to an HSL Image, do it here

+		if (globalCamera.decode) {

+			if(globalCamera.data[writeIndex].decodedImage)

+				frcDispose(globalCamera.data[writeIndex].decodedImage);

+			globalCamera.data[writeIndex].decodedImage = frcCreateImage(IMAQ_IMAGE_HSL);

+			if (! Priv_ReadJPEGString_C(globalCamera.data[writeIndex].decodedImage, 

+					(const unsigned char *)globalCamera.data[writeIndex].cameraImage, 

+					globalCamera.data[writeIndex].cameraImageSize) ) {

+				DPRINTF (LOG_DEBUG, "failure creating Image");			

+			}

+		}

+		

+		// TODO: React to partial image

+		globalCamera.data[writeIndex].timestamp = GetTime();

+		globalCamera.index = writeIndex;

+		

+		/* signal a listening task */

+		if (globalCamera.readerPID) {

+			if (taskKill (globalCamera.readerPID,SIGUSR1) == OK)

+				DPRINTF (LOG_DEBUG, "SIGNALING PID= %i", globalCamera.readerPID);

+			else

+				globalCamera.cameraMetrics[CAM_PID_SIGNAL_ERR]++;

+				DPRINTF (LOG_DEBUG, "ERROR SIGNALING PID= %i", globalCamera.readerPID);

+		}

+

+		globalCamera.cameraMetrics[CAM_NUM_IMAGE]++;	

+		printCounter ++;

+		if (printCounter == 1000) { 

+			DPRINTF (LOG_DEBUG, "imageCounter = %i", globalCamera.cameraMetrics[CAM_NUM_IMAGE]); 

+			printCounter=0; 

+		}

+		

+		taskDelay(1);  

+		

+#if MEASURE_TIME

+		loopEndTime = GetTime(); 

+		performanceLoopCounter++;

+		if (performanceLoopCounter <= maxCount) {

+			DPRINTF (LOG_DEBUG, "%i DONE!!!: loop = ,%g,  camera = ,%g,  difference = ,%g, loopRate= ,%g,",

+					performanceLoopCounter, loopEndTime-loopStartTime, cameraEndTime-cameraStartTime, 

+					(loopEndTime-loopStartTime) - (cameraEndTime-cameraStartTime),

+					loopStartTime-previousStartTime);						

+		}

+#endif	

+	}  /* end while (cont) */

+

+	/* clean up */

+	close (camSock);

+	cont = 0;

+	DPRINTF (LOG_INFO, "\nJPEG SERVER ENDING  errorCode = %i\n", errorCode );

+	

+	return (OK);

+}

+

+/**

+ * @brief Start signaling a task when new images are available

+ * @param taskID number for task to get the signal

+ */

+void StartImageSignal(int taskId) // Start issuing a SIGUSR1 signal to the specified taskId

+{	globalCamera.readerPID = taskId; }

+

+/**

+ * @brief Start serving images

+ */

+void StartImageAcquisition()

+{	

+	globalCamera.cameraMetrics[CAM_STARTS]++;  

+	globalCamera.acquire = 1; 

+	DPRINTF(LOG_DEBUG, "starting acquisition");

+}

+

+

+/**

+ * @brief Stop serving images

+ */

+void StopImageAcquisition()

+{	globalCamera.cameraMetrics[CAM_STOPS]++;  globalCamera.acquire = 0; }

+

+

+/**

+ * @brief This is the routine that is run when the task is spawned

+ * It initializes the camera with the image settings passed in, and

+ * starts image acquisition.

+ * @param frames Frames per second 

+ * @param compression Camera image compression 

+ * @param resolution Camera image size 

+ * @param rotation Camera image rotation 

+ */

+static int initCamera(int frames, int compression, ImageResolution resolution, ImageRotation rotation) 

+{

+	//SetDebugFlag ( DEBUG_SCREEN_AND_FILE  ) ;

+	

+	DPRINTF(LOG_DEBUG, "\n+++++ camera task starting: rotation = %i", (int)rotation);

+	int errorCode;

+

+	/* Initialize globalCamera area 

+	 * Set decode to 1 - always want to decode images for processing 

+	 * If ONLY sending images to the dashboard, you could set it to 0 */

+	bzero ((char *)&globalCamera, sizeof(globalCamera));

+	globalCamera.index = -1;

+	globalCamera.decode = 1;

+	

+	/* allow writing to vxWorks target */

+	Priv_SetWriteFileAllowed(1); 

+	

+	/* start acquisition immediately */

+	StartImageAcquisition();

+	

+	/*  cameraJPEGServer runs until camera is stopped */

+	DPRINTF (LOG_DEBUG, "calling cameraJPEGServer" ); 

+	errorCode = cameraJPEGServer(frames, compression, resolution, rotation);	

+	DPRINTF (LOG_INFO, "errorCode from cameraJPEGServer = %i\n", errorCode ); 

+	return (OK);

+}

+

+Task g_axisCameraTask("Camera", (FUNCPTR)initCamera);

+

+/**

+ * @brief Start the camera task

+ * @param frames Frames per second 

+ * @param compression Camera image compression 

+ * @param resolution Camera image size 

+ * @param rotation Camera image rotation (ROT_0 or ROT_180)

+ * @return TaskID of camera task, or -1 if error.

+ */

+int StartCameraTask()

+{

+	return StartCameraTask(10, 0, k160x120, ROT_0);

+}

+int StartCameraTask(int frames, int compression, ImageResolution resolution, ImageRotation rotation)

+{

+	char funcName[]="startCameraTask";

+	DPRINTF(LOG_DEBUG, "starting camera");

+

+	int cameraTaskID = 0;

+

+	//range check

+	if (frames < 1) frames = 1;

+	else if (frames > 30) frames = 30;

+	if (compression < 0) compression = 0;		

+	else if (compression > 100) compression = 100;

+

+	// stop any prior copy of running task

+	StopCameraTask(); 

+

+	// spawn camera task

+	bool started = g_axisCameraTask.Start(frames, compression, resolution, rotation);

+	cameraTaskID = g_axisCameraTask.GetID();

+	DPRINTF(LOG_DEBUG, "spawned task id %i", cameraTaskID);

+

+	if (!started)	{

+		DPRINTF(LOG_DEBUG, "camera task failed to start");

+		imaqSetError(ERR_CAMERA_TASK_SPAWN_FAILED, funcName);

+		return -1;

+	}

+	return cameraTaskID;

+}

+

+/**

+ * @brief Stops the camera task

+ * @return TaskID of camera task killed, or -1 if none was running.

+ */

+int StopCameraTask()

+{

+    std::string taskName("FRC_Camera");    

+	// check for prior copy of running task

+	int oldTaskID = taskNameToId(const_cast<char*>(taskName.c_str()));

+	if(oldTaskID != ERROR) { taskDelete(oldTaskID);  }

+	return oldTaskID;

+}

+

+#if 0

+/* if you want to run this task by itself to debug  

+ * enable this code and make RunProgram the entry point 

+ */

+extern "C"

+{

+void RunProgram();

+int AxisCamera_StartupLibraryInit();

+}

+/** * @brief Start point of the program */

+void RunProgram()

+{	StartCameraTask();}

+

+/** * @brief This is the main program that is run by the debugger or the robot on boot. */

+int AxisCamera_StartupLibraryInit()

+	{		RunProgram();		return 0;	}

+

+#endif

+

+

+

diff --git a/azaleasource/WPILibCProgramming/trunk/WPILib/Vision2009/AxisCamera.h b/azaleasource/WPILibCProgramming/trunk/WPILib/Vision2009/AxisCamera.h
new file mode 100644
index 0000000..4a6063a
--- /dev/null
+++ b/azaleasource/WPILibCProgramming/trunk/WPILib/Vision2009/AxisCamera.h
@@ -0,0 +1,92 @@
+/********************************************************************************

+*  Project   		: FIRST Motor Controller

+*  File Name  		: AxisCamera.h          

+*  Contributors   	: ELF

+*  Creation Date 	: August 12, 2008

+*  Revision History	: Source code & revision history maintained at sourceforge.WPI.edu    

+*  File Description	: Globally defined values for the FRC Camera API

+* 

+*  API: Because nivision.h uses C++ style comments, any file including this

+*  must be a .cpp instead of .c.

+* 

+*/

+/*----------------------------------------------------------------------------*/

+/*        Copyright (c) FIRST 2008.  All Rights Reserved.                     */

+/*  Open Source Software - may be modified and shared by FRC teams. The code  */

+/*  must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */

+/*----------------------------------------------------------------------------*/

+

+#ifndef __AXISCAMERA_H__

+#define __AXISCAMERA_H__

+

+#include "nivision.h"

+

+/** port for communicating with camera */

+#define CAMERA_PORT 80

+/** how old an image is before it's discarded */

+#define CAMERA_IMAGE_STALE_TIME_SEC 2.0  

+/** time to wait for a new image in blocking call */

+#define MAX_BLOCKING_TIME_SEC 0.5

+

+/*  Enumerated Types */

+/** @brief Counters for camera metrics */

+enum FrcvCameraMetric {CAM_STARTS, CAM_STOPS, 

+	CAM_NUM_IMAGE, CAM_BUFFERS_WRITTEN, CAM_BLOCKING_COUNT,

+	

+	CAM_SOCKET_OPEN, CAM_SOCKET_INIT_ATTEMPTS, CAM_BLOCKING_TIMEOUT,

+	CAM_GETIMAGE_SUCCESS, CAM_GETIMAGE_FAILURE, 

+	

+	CAM_STALE_IMAGE, CAM_GETIMAGE_BEFORE_INIT, CAM_GETIMAGE_BEFORE_AVAILABLE,

+	CAM_READ_JPEG_FAILURE, CAM_PID_SIGNAL_ERR, 

+	

+	CAM_BAD_IMAGE_SIZE, CAM_HEADER_ERROR};

+

+#define CAM_NUM_METRICS 17

+

+/** Private NI function needed to write to the VxWorks target */

+IMAQ_FUNC int Priv_SetWriteFileAllowed(UINT32 enable); 

+

+/**

+@brief Possible image sizes that you can set on the camera.

+*/

+enum ImageResolution { k640x480, k320x240, k160x120 };

+

+/**

+@brief Possible rotation values that you can set on the camera.

+*/

+enum ImageRotation { ROT_0 = 0, ROT_180 = 180 };

+

+

+

+int StartCameraTask();

+

+extern "C" {

+/*  Image Acquisition functions */

+/* obtains an image from the camera server */

+int GetImage(Image* cameraImage, double *timestamp);

+int GetImageBlocking(Image* cameraImage, double *timestamp, double lastImageTimestamp);

+/* obtains raw image string to send to PC */

+int GetImageData(char** imageData, int* numBytes, double* currentImageTimestamp);

+int GetImageDataBlocking(char** imageData, int* numBytes, double* timestamp, double lastImageTimestamp);

+

+/* start the camera server */

+void StartImageAcquisition();

+void StopImageAcquisition();

+void StartImageSignal(int taskId);

+

+/* status & metrics */

+int frcCameraInitialized();

+int GetCameraMetric(FrcvCameraMetric metric);

+

+/* camera configuration */

+int ConfigureCamera(char *configString);

+int GetCameraSetting(char *configString, char *cameraResponse);

+int GetImageSetting(char *configString, char *cameraResponse);

+

+/* camera task control */

+

+int StartCameraTask(int frames, int compression, ImageResolution resolution, ImageRotation rotation);

+int StopCameraTask();

+}

+#endif

+

diff --git a/azaleasource/WPILibCProgramming/trunk/WPILib/Vision2009/BaeUtilities.cpp b/azaleasource/WPILibCProgramming/trunk/WPILib/Vision2009/BaeUtilities.cpp
new file mode 100644
index 0000000..066fbd3
--- /dev/null
+++ b/azaleasource/WPILibCProgramming/trunk/WPILib/Vision2009/BaeUtilities.cpp
@@ -0,0 +1,400 @@
+/********************************************************************************

+*  Project   		: FIRST Motor Controller

+*  File Name  		: BaeUtilities.cpp        

+*  Contributors   	: JDG, ELF, EMF

+*  Creation Date 	: July 20, 2008

+*  Revision History	: Source code & revision history maintained at sourceforge.WPI.edu    

+*  File Description	: Open source utility extensions for FIRST Vision API.

+*/                            

+/*----------------------------------------------------------------------------*/

+/*        Copyright (c) FIRST 2008.  All Rights Reserved.                     */

+/*  Open Source Software - may be modified and shared by FRC teams. The code  */

+/*  must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */

+/*----------------------------------------------------------------------------*/

+#include <stdio.h>

+#include <sys/types.h>

+#include <sys/stat.h>

+#include <unistd.h>

+#include <string.h>

+#include <math.h>

+#include <stdioLib.h> 

+ 

+#include "BaeUtilities.h"

+#include "Servo.h"

+#include "Timer.h"

+

+/**

+ *   Utility functions 

+ */

+

+/**

+ * debug output flag options:

+ * DEBUG_OFF, DEBUG_MOSTLY_OFF, DEBUG_SCREEN_ONLY, DEBUG_FILE_ONLY, DEBUG_SCREEN_AND_FILE

+ */

+static DebugOutputType	dprintfFlag = DEBUG_OFF;  

+

+/**

+ * Set the debug flag to print to screen, file on cRIO, both or neither

+ * @param tempString The format string.

+ */

+void SetDebugFlag ( DebugOutputType flag  )  

+{ dprintfFlag = flag; }

+

+/**

+ * Debug print to a file and/or a terminal window.

+ * Call like you would call printf.

+ * Set functionName in the function if you want the correct function name to print out.

+ * The file line number will also be printed.

+ * @param tempString The format string.

+ */

+void dprintf ( char * tempString, ...  )  /* Variable argument list */

+{

+  va_list	args;			  /* Input argument list */

+  int		line_number;      /* Line number passed in argument */

+  int		type;

+  char		*functionName;    /* Format passed in argument */

+  char		*fmt;             /* Format passed in argument */

+  char		text[512];   	  /* Text string */

+  char		outtext[512];     /* Text string */

+  FILE		*outfile_fd;      /* Output file pointer */

+  char		filepath[128];    /* Text string */

+  int		fatalFlag=0;

+  char		*filename;

+  int		index;

+  int		tempStringLen;

+

+  if (dprintfFlag == DEBUG_OFF) { return; }

+  

+  va_start (args, tempString);

+  

+  tempStringLen = strlen(tempString);

+  filename = tempString;

+  for (index=0;index<tempStringLen;index++){

+	  if (tempString[index] == ' ') {

+		  printf( "ERROR in dprintf: malformed calling sequence (%s)\n",tempString);return;

+	  	}

+	  if (tempString[index] == '\\' || tempString[index] == '/')

+		  filename = tempString + index + 1;

+  }

+  

+  /* Extract function name */

+  functionName = va_arg (args, char *);

+ 

+ /* Extract line number from argument list */

+  line_number = va_arg (args, int);

+

+ /* Extract information type from argument list */

+  type = va_arg (args, int);

+

+ /* Extract format from argument list */

+  fmt = va_arg (args, char *);

+

+  vsprintf (text, fmt, args);

+

+  va_end (args);

+

+  /* Format output statement */

+  switch (type)

+   {

+   case DEBUG_TYPE:

+     sprintf (outtext, "[%s:%s@%04d] DEBUG %s\n",

+              filename, functionName, line_number, text);

+     break;

+   case INFO_TYPE:

+     sprintf (outtext, "[%s:%s@%04d] INFO %s\n",

+              filename, functionName, line_number, text);

+     break;

+   case ERROR_TYPE:

+     sprintf (outtext, "[%s:%s@%04d] ERROR %s\n",

+              filename, functionName, line_number, text);

+     break;

+   case CRITICAL_TYPE:

+     sprintf (outtext, "[%s:%s@%04d] CRITICAL %s\n",

+              filename, functionName, line_number, text);

+     break;

+   case FATAL_TYPE:

+     fatalFlag = 1;

+     sprintf (outtext, "[%s:%s@%04d] FATAL %s\n",

+              filename, functionName, line_number, text);

+     break;

+   default:

+     printf( "ERROR in dprintf: malformed calling sequence\n");

+     return;

+     break;

+   }

+

+  sprintf (filepath, "%s.debug", filename);

+

+  /* Write output statement */

+  switch (dprintfFlag)

+  {

+  default:

+  case DEBUG_OFF: 

+  	break;

+  case DEBUG_MOSTLY_OFF: 

+  	if (fatalFlag)	{

+	  if ((outfile_fd = fopen (filepath, "a+")) != NULL)	  {

+	    fwrite (outtext, sizeof (char), strlen (outtext), outfile_fd);

+	    fclose (outfile_fd);

+	  }

+	}

+  	break;

+  case DEBUG_SCREEN_ONLY: 

+  	printf ("%s", outtext);

+  	break;

+  case DEBUG_FILE_ONLY: 

+	if ((outfile_fd = fopen (filepath, "a+")) != NULL)	{

+	  fwrite (outtext, sizeof (char), strlen (outtext), outfile_fd);

+	  fclose (outfile_fd);

+	}

+  	break;

+  case DEBUG_SCREEN_AND_FILE: // BOTH

+  	printf ("%s", outtext);

+	if ((outfile_fd = fopen (filepath, "a+")) != NULL)	{

+	  fwrite (outtext, sizeof (char), strlen (outtext), outfile_fd);

+	  fclose (outfile_fd);

+	}

+  	break;

+  }

+}

+

+/**

+ * @brief Normalizes a value in a range, used for drive input

+ * @param position The position in the range, starting at 0

+ * @param range The size of the range that position is in

+ * @return The normalized position from -1 to +1

+ */

+double RangeToNormalized(double position, int range){

+	return(((position*2.0)/(double)range)-1.0);

+}

+

+/**

+ * @brief Convert a normalized value to the corresponding value in a range.

+ * This is used to convert normalized values to the servo command range.

+ * @param normalizedValue The normalized value (in the -1 to +1 range)

+ * @param minRange The minimum of the range (0 is default)

+ * @param maxRange The maximum of the range (1 is default)

+ * @return The value in the range corresponding to the input normalized value

+ */

+float NormalizeToRange(float normalizedValue, float minRange, float maxRange) {

+	float range = maxRange-minRange;

+	float temp = (float)((normalizedValue / 2.0)+ 0.5)*range;

+	return (temp + minRange);

+}	

+float NormalizeToRange(float normalizedValue) {

+	return (float)((normalizedValue / 2.0) + 0.5);

+}	

+

+/**

+ * @brief Displays an activity indicator to console. 

+ * Call this function like you would call printf.

+ * @param fmt The format string

+*/

+void ShowActivity (char *fmt, ...)

+{

+  static char   activity_indication_string[] = "|/-\\";

+  static int    ai = 3;

+  va_list       args;

+  char          text[1024];

+

+  va_start (args, fmt);

+

+  vsprintf (text, fmt, args);

+

+  ai = ai == 3 ? 0 : ai + 1;

+

+  printf ("%c %s \r", activity_indication_string[ai], text);

+  fflush (stdout);

+

+  va_end (args);

+}

+

+#define PI 3.14159265358979

+/**

+ * @brief Calculate sine wave increments (-1.0 to 1.0). 

+ * The first time this is called, it sets up the time increment. Subsequent calls

+ * will give values along the sine wave depending on current time. If the wave is

+ * stopped and restarted, it must be reinitialized with a new "first call".

+ * 

+ * @param period length of time to complete a complete wave

+ * @param sinStart Where to start the sine wave (0.0 = 2 pi, pi/2 = 1.0, etc.)

+ */

+double SinPosition (double *period, double sinStart)

+{

+  double rtnVal;

+  static double sinePeriod=0.0;

+  static double timestamp;

+  double sinArg;

+

+  //1st call

+  if (period != NULL) {

+    sinePeriod = *period;

+	timestamp = GetTime();

+	return 0.0;

+  }

+

+  //Multiplying by 2*pi to the time difference makes sinePeriod work if it's measured in seconds.

+  //Adding sinStart to the part multiplied by PI, but not by 2, allows it to work as described in the comments.

+  sinArg = PI *((2.0 * (GetTime() - timestamp)) + sinStart) / sinePeriod;

+  rtnVal = sin (sinArg);  

+  return (rtnVal);

+}

+

+

+/**

+ * @brief Find the elapsed time since a specified time.

+ * @param startTime The starting time

+ * @return How long it has been since the starting time

+ */

+double ElapsedTime ( double startTime )  

+{

+	double realTime = GetTime();	

+	return (realTime-startTime);

+}

+

+/**

+ * @brief Initialize pan parameters

+ * @param period The number of seconds to complete one pan

+ */

+void panInit()	{

+	double period = 3.0;  	// number of seconds for one complete pan

+	SinPosition(&period, 0.0);	// initial call to set up time

+}

+

+void panInit(double period)	{

+	if (period < 0.0) period=3.0;

+	SinPosition(&period, 0.0);	// initial call to set up time

+}

+

+/**

+ * @brief Move the horizontal servo back and forth.

+ * @param panServo The servo object to move

+ * @param sinStart The position on the sine wave to begin the pan

+ */

+void panForTarget(Servo *panServo)	{ panForTarget(panServo, 0.0); }

+

+void panForTarget(Servo *panServo, double sinStart)	{

+	float normalizedSinPosition = (float)SinPosition(NULL, sinStart);

+	float newServoPosition = NormalizeToRange(normalizedSinPosition);

+	panServo->Set( newServoPosition );

+	//ShowActivity ("pan x: normalized %f newServoPosition = %f" , 

+	//		normalizedSinPosition, newServoPosition );

+}

+

+

+/** @brief Read a file and return non-comment output string 

+

+Call the first time with 0 lineNumber to get the number of lines to read

+Then call with each lineNumber to get one camera parameter. There should

+be one property=value entry on each line, i.e. "exposure=auto"

+

+ * @param inputFile filename to read

+ * @param outputString one string

+ * @param lineNumber if 0, return number of lines; else return that line number

+ * @return int number of lines or -1 if error

+ **/

+int processFile(char *inputFile, char *outputString, int lineNumber)

+{

+	FILE *infile;

+	int stringSize = 80;		// max size of one line in file 

+	char inputStr[stringSize];

+	struct stat fileStatus;

+	int fileSize=0;

+	int lineCount=0;

+	  

+	if (lineNumber < 0)

+		  return (-1);

+

+	if ((infile = fopen (inputFile, "r")) == NULL) {

+	    printf ("Fatal error opening file %s\n",inputFile);

+	    return (0);

+	}

+    memset (&fileStatus, 0, sizeof(fileStatus));

+    if (!stat(inputFile, &fileStatus)) {

+      if (S_ISREG(fileStatus.st_mode)) {

+        fileSize = fileStatus.st_size;

+      }

+    }

+

+  while (!feof(infile)) {

+    if (fgets (inputStr, stringSize, infile) != NULL) {

+      // Skip empty lines

+      if (emptyString(inputStr))

+        continue;

+      // Skip comment lines

+      if (inputStr[0] == '#' || inputStr[0] == '!')

+        continue;

+

+      lineCount++;

+      if (lineNumber == 0)

+        continue;

+      else

+      {

+    	  if (lineCount == lineNumber)

+    		  break;

+      }

+    }

+  }

+

+  // close file 

+  fclose (infile);

+  // if number lines requested return the count

+  if (lineNumber == 0)

+	  return (lineCount);

+  // check for input out of range

+  if (lineNumber > lineCount)

+	  return (-1);

+  // return the line selected

+  if (lineCount) {

+    stripString(inputStr);

+    strcpy(outputString, inputStr);

+    return(lineCount);

+  } 

+  else {

+    return(-1);

+  }

+}

+

+/** Ignore empty string 

+ * @param string to check if empty

+ **/

+int emptyString(char *string)

+{

+  int i,len;

+

+  if(string == NULL)

+    return(1);

+

+  len = strlen(string);

+  for(i=0; i<len; i++) {

+    // Ignore the following characters

+    if (string[i] == '\n' || string[i] == '\r' ||

+        string[i] == '\t' || string[i] == ' ')

+      continue;

+    return(0);

+  }

+  return(1);

+}

+

+/** Remove special characters from string 

+ * @param string to process

+ **/

+void stripString(char *string)

+{

+  int i,j,len;

+

+  if(string == NULL)

+    return;

+

+  len = strlen(string);

+  for(i=0,j=0; i<len; i++) {

+    // Remove the following characters from the string

+    if (string[i] == '\n' || string[i] == '\r' || string[i] == '\"')

+      continue;

+    // Copy anything else

+    string[j++] = string[i];

+  }

+  string[j] = '\0'; 

+}

+

+

diff --git a/azaleasource/WPILibCProgramming/trunk/WPILib/Vision2009/BaeUtilities.h b/azaleasource/WPILibCProgramming/trunk/WPILib/Vision2009/BaeUtilities.h
new file mode 100644
index 0000000..898c9e7
--- /dev/null
+++ b/azaleasource/WPILibCProgramming/trunk/WPILib/Vision2009/BaeUtilities.h
@@ -0,0 +1,68 @@
+/********************************************************************************

+*  Project   		: FIRST Motor Controller

+*  File Name  		: BaeUtilities.h          

+*  Contributors   	: JDG, ELF

+*  Creation Date 	: August 12, 2008

+*  Revision History	: Source code & revision history maintained at sourceforge.WPI.edu      

+*  File Description	: Globally defined values for utilities

+*/

+/*----------------------------------------------------------------------------*/

+/*        Copyright (c) FIRST 2008.  All Rights Reserved.                     */

+/*     Open Source Software - may be modified and shared by FRC teams.        */

+/*   Must be accompanied by the BSD license file in $(WIND_BASE)/WPILib.      */

+/*----------------------------------------------------------------------------*/

+

+#ifndef __BAEUTILITIES_H__

+#define __BAEUTILITIES_H__

+

+/*  Constants */

+#define LOG_DEBUG    __FILE__,__FUNCTION__,__LINE__,DEBUG_TYPE

+#define LOG_INFO     __FILE__,__FUNCTION__,__LINE__,INFO_TYPE

+#define LOG_ERROR    __FILE__,__FUNCTION__,__LINE__,ERROR_TYPE

+#define LOG_CRITICAL __FILE__,__FUNCTION__,__LINE__,CRITICAL_TYPE

+#define LOG_FATAL    __FILE__,__FUNCTION__,__LINE__,FATAL_TYPE

+#define LOG_DEBUG    __FILE__,__FUNCTION__,__LINE__,DEBUG_TYPE

+

+/*   Enumerated Types */

+

+/** debug levels */

+enum dprint_type {DEBUG_TYPE, INFO_TYPE, ERROR_TYPE, CRITICAL_TYPE, FATAL_TYPE};

+

+/** debug output setting */

+typedef enum DebugOutputType_enum { 

+	DEBUG_OFF, DEBUG_MOSTLY_OFF, DEBUG_SCREEN_ONLY, DEBUG_FILE_ONLY, DEBUG_SCREEN_AND_FILE

+}DebugOutputType;

+

+/*  Enumerated Types */

+

+/* Utility functions */

+

+/* debug */

+void SetDebugFlag ( DebugOutputType flag  ); 

+void dprintf ( char * tempString, ...  );  /* Variable argument list */

+

+/* set FRC ranges for drive */

+double RangeToNormalized(double pixel, int range);

+/* change normalized value to any range - used for servo */

+float NormalizeToRange(float normalizedValue, float minRange, float maxRange);

+float NormalizeToRange(float normalizedValue);

+

+/* system utilities */

+void ShowActivity (char *fmt, ...);

+double ElapsedTime (double startTime);

+

+/* servo panning utilities */

+class Servo;

+double SinPosition (double *period, double sinStart);

+void panInit();

+void panInit(double period);

+void panForTarget(Servo *panServo);

+void panForTarget(Servo *panServo, double sinStart);

+

+/* config file read utilities */

+int processFile(char *inputFile, char *outputString, int lineNumber);

+int emptyString(char *string);

+void stripString(char *string);

+

+#endif

+

diff --git a/azaleasource/WPILibCProgramming/trunk/WPILib/Vision2009/FrcError.cpp b/azaleasource/WPILibCProgramming/trunk/WPILib/Vision2009/FrcError.cpp
new file mode 100644
index 0000000..8c1c9f4
--- /dev/null
+++ b/azaleasource/WPILibCProgramming/trunk/WPILib/Vision2009/FrcError.cpp
@@ -0,0 +1,1235 @@
+/********************************************************************************

+*  Project   		: FIRST Motor Controller

+*  File Name  		: FrcError.cpp        

+*  Contributors   	: JDG, ELF

+*  Creation Date 	: July 20, 2008

+*  Revision History	: Source code & revision history maintained at sourceforge.WPI.edu    

+*  File Description	: Error handling functionality for C routines

+*/                            

+/*----------------------------------------------------------------------------*/

+/*        Copyright (c) FIRST 2008.  All Rights Reserved.                     */

+/*  Open Source Software - may be modified and shared by FRC teams. The code  */

+/*  must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */

+/*----------------------------------------------------------------------------*/

+ 

+#include "nivision.h" 

+#include "FrcError.h" 

+

+/**

+ * Get the error code returned from the NI Vision library

+ * @return The last error code.

+ */

+int GetLastVisionError()

+{

+	//int errorCode = imaqGetLastVisionError();     // error code: 0 = no error	

+	//char* errorText = GetVisionErrorText(errorCode);

+	//dprintf (LOG_DEBUG, "Error = %i  %s ", errorCode, errorText);

+	return imaqGetLastError();

+}

+	

+/**

+* Get the error text for an NI Vision error code.

+* Note: imaqGetErrorText() is not supported on real time system, so

+* so relevant strings are hardcoded here - the maintained version is

+* in the LabWindows/CVI help file.

+* @param errorCode The error code to find the text for.

+* @return The error text

+*/

+char* GetVisionErrorText(int errorCode)

+{

+	char* errorText;

+

+	switch (errorCode)

+	{

+		default:

+			{ errorText = "UNKNOWN_ERROR";break;}

+		case -1074395138:

+			{ errorText = "ERR_OCR_REGION_TOO_SMALL";break;}

+		case -1074395139:

+			{ errorText = "ERR_IMAQ_QR_DIMENSION_INVALID";break;}

+		case -1074395140:

+			{ errorText = "ERR_OCR_CHAR_REPORT_CORRUPTED";break;}

+		case -1074395141:

+			{ errorText = "ERR_OCR_NO_TEXT_FOUND";break;}

+		case -1074395142:

+			{ errorText = "ERR_QR_DETECTION_MODELTYPE";break;}

+		case -1074395143:

+			{ errorText = "ERR_QR_DETECTION_MODE";break;}

+		case -1074395144:

+			{ errorText = "ERR_QR_INVALID_BARCODE";break;}

+		case -1074395145:

+			{ errorText = "ERR_QR_INVALID_READ";break;}

+		case -1074395146:

+			{ errorText = "ERR_QR_DETECTION_VERSION";break;}

+		case -1074395147:

+			{ errorText = "ERR_BARCODE_RSSLIMITED";break;}

+		case -1074395148:

+			{ errorText = "ERR_OVERLAY_GROUP_NOT_FOUND";break;}

+		case -1074395149:

+			{ errorText = "ERR_DUPLICATE_TRANSFORM_TYPE";break;}

+		case -1074395151:

+			{ errorText = "ERR_OCR_CORRECTION_FAILED";break;}

+		case -1074395155:

+			{ errorText = "ERR_OCR_ORIENT_DETECT_FAILED";break;}

+		case -1074395156:

+			{ errorText = "ERR_OCR_SKEW_DETECT_FAILED";break;}

+		case -1074395158:

+			{ errorText = "ERR_OCR_INVALID_CONTRASTMODE";break;}

+		case -1074395159:

+			{ errorText = "ERR_OCR_INVALID_TOLERANCE";break;}

+		case -1074395160:

+			{ errorText = "ERR_OCR_INVALID_MAXPOINTSIZE";break;}

+		case -1074395161:

+			{ errorText = "ERR_OCR_INVALID_CORRECTIONLEVEL";break;}

+		case -1074395162:

+			{ errorText = "ERR_OCR_INVALID_CORRECTIONMODE";break;}

+		case -1074395163:

+			{ errorText = "ERR_OCR_INVALID_CHARACTERPREFERENCE";break;}

+		case -1074395164:

+			{ errorText = "ERR_OCR_ADD_WORD_FAILED";break;}

+		case -1074395165:

+			{ errorText = "ERR_OCR_WTS_DIR_NOT_FOUND";break;}

+		case -1074395166:

+			{ errorText = "ERR_OCR_BIN_DIR_NOT_FOUND";break;}

+		case -1074395167:

+			{ errorText = "ERR_OCR_INVALID_OUTPUTDELIMITER";break;}

+		case -1074395168:

+			{ errorText = "ERR_OCR_INVALID_AUTOCORRECTIONMODE";break;}

+		case -1074395169:

+			{ errorText = "ERR_OCR_INVALID_RECOGNITIONMODE";break;}

+		case -1074395170:

+			{ errorText = "ERR_OCR_INVALID_CHARACTERTYPE";break;}

+		case -1074395171:

+			{ errorText = "ERR_OCR_INI_FILE_NOT_FOUND";break;}

+		case -1074395172:

+			{ errorText = "ERR_OCR_INVALID_CHARACTERSET";break;}

+		case -1074395173:

+			{ errorText = "ERR_OCR_INVALID_LANGUAGE";break;}

+		case -1074395174:

+			{ errorText = "ERR_OCR_INVALID_AUTOORIENTMODE";break;}

+		case -1074395175:

+			{ errorText = "ERR_OCR_BAD_USER_DICTIONARY";break;}

+		case -1074395178:

+			{ errorText = "ERR_OCR_RECOGNITION_FAILED";break;}

+		case -1074395179:

+			{ errorText = "ERR_OCR_PREPROCESSING_FAILED";break;}

+		case -1074395200:

+			{ errorText = "ERR_OCR_INVALID_PARAMETER";break;}

+		case -1074395201:

+			{ errorText = "ERR_OCR_LOAD_LIBRARY";break;}

+		case -1074395203:

+			{ errorText = "ERR_OCR_LIB_INIT";break;}

+		case -1074395210:

+			{ errorText = "ERR_OCR_CANNOT_MATCH_TEXT_TEMPLATE";break;}

+		case -1074395211:

+			{ errorText = "ERR_OCR_BAD_TEXT_TEMPLATE";break;}

+		case -1074395212:

+			{ errorText = "ERR_OCR_TEMPLATE_WRONG_SIZE";break;}

+		case -1074395233:

+			{ errorText = "ERR_TEMPLATE_IMAGE_TOO_LARGE";break;}

+		case -1074395234:

+			{ errorText = "ERR_TEMPLATE_IMAGE_TOO_SMALL";break;}

+		case -1074395235:

+			{ errorText = "ERR_TEMPLATE_IMAGE_CONTRAST_TOO_LOW";break;}

+		case -1074395237:

+			{ errorText = "ERR_TEMPLATE_DESCRIPTOR_SHIFT_1";break;}

+		case -1074395238:

+			{ errorText = "ERR_TEMPLATE_DESCRIPTOR_NOSHIFT";break;}

+		case -1074395239:

+			{ errorText = "ERR_TEMPLATE_DESCRIPTOR_SHIFT";break;}

+		case -1074395240:

+			{ errorText = "ERR_TEMPLATE_DESCRIPTOR_ROTATION_1";break;}

+		case -1074395241:

+			{ errorText = "ERR_TEMPLATE_DESCRIPTOR_NOROTATION";break;}

+		case -1074395242:

+			{ errorText = "ERR_TEMPLATE_DESCRIPTOR_ROTATION";break;}

+		case -1074395243:

+			{ errorText = "ERR_TEMPLATE_DESCRIPTOR_4";break;}

+		case -1074395244:

+			{ errorText = "ERR_TEMPLATE_DESCRIPTOR_3";break;}

+		case -1074395245:

+			{ errorText = "ERR_TEMPLATE_DESCRIPTOR_2";break;}

+		case -1074395246:

+			{ errorText = "ERR_TEMPLATE_DESCRIPTOR_1";break;}

+		case -1074395247:

+			{ errorText = "ERR_TEMPLATE_DESCRIPTOR";break;}

+		case -1074395248:

+			{ errorText = "ERR_TOO_MANY_ROTATION_ANGLE_RANGES";break;}

+		case -1074395249:

+			{ errorText = "ERR_ROTATION_ANGLE_RANGE_TOO_LARGE";break;}

+		case -1074395250:

+			{ errorText = "ERR_MATCH_SETUP_DATA";break;}

+		case -1074395251:

+			{ errorText = "ERR_INVALID_MATCH_MODE";break;}

+		case -1074395252:

+			{ errorText = "ERR_LEARN_SETUP_DATA";break;}

+		case -1074395253:

+			{ errorText = "ERR_INVALID_LEARN_MODE";break;}

+		case -1074395256:

+			{ errorText = "ERR_EVEN_WINDOW_SIZE";break;}

+		case -1074395257:

+			{ errorText = "ERR_INVALID_EDGE_DIR";break;}

+		case -1074395258:

+			{ errorText = "ERR_BAD_FILTER_WIDTH";break;}

+		case -1074395260:

+			{ errorText = "ERR_HEAP_TRASHED";break;}

+		case -1074395261:

+			{ errorText = "ERR_GIP_RANGE";break;}

+		case -1074395262:

+			{ errorText = "ERR_LCD_BAD_MATCH";break;}

+		case -1074395263:

+			{ errorText = "ERR_LCD_NO_SEGMENTS";break;}

+		case -1074395265:

+			{ errorText = "ERR_BARCODE";break;}

+		case -1074395267:

+			{ errorText = "ERR_COMPLEX_ROOT";break;}

+		case -1074395268:

+			{ errorText = "ERR_LINEAR_COEFF";break;}

+		case -1074395269:

+			{ errorText = "ERR_NULL_POINTER";break;}

+		case -1074395270:

+			{ errorText = "ERR_DIV_BY_ZERO";break;}

+		case -1074395275:

+			{ errorText = "ERR_INVALID_BROWSER_IMAGE";break;}

+		case -1074395276:

+			{ errorText = "ERR_LINES_PARALLEL";break;}

+		case -1074395277:

+			{ errorText = "ERR_BARCODE_CHECKSUM";break;}

+		case -1074395278:

+			{ errorText = "ERR_LCD_NOT_NUMERIC";break;}

+		case -1074395279:

+			{ errorText = "ERR_ROI_NOT_POLYGON";break;}

+		case -1074395280:

+			{ errorText = "ERR_ROI_NOT_RECT";break;}

+		case -1074395281:

+			{ errorText = "ERR_IMAGE_SMALLER_THAN_BORDER";break;}

+		case -1074395282:

+			{ errorText = "ERR_CANT_DRAW_INTO_VIEWER";break;}

+		case -1074395283:

+			{ errorText = "ERR_INVALID_RAKE_DIRECTION";break;}

+		case -1074395284:

+			{ errorText = "ERR_INVALID_EDGE_PROCESS";break;}

+		case -1074395285:

+			{ errorText = "ERR_INVALID_SPOKE_DIRECTION";break;}

+		case -1074395286:

+			{ errorText = "ERR_INVALID_CONCENTRIC_RAKE_DIRECTION";break;}

+		case -1074395287:

+			{ errorText = "ERR_INVALID_LINE";break;}

+		case -1074395290:

+			{ errorText = "ERR_SHAPEMATCH_BADTEMPLATE";break;}

+		case -1074395291:

+			{ errorText = "ERR_SHAPEMATCH_BADIMAGEDATA";break;}

+		case -1074395292:

+			{ errorText = "ERR_POINTS_ARE_COLLINEAR";break;}

+		case -1074395293:

+			{ errorText = "ERR_CONTOURID_NOT_FOUND";break;}

+		case -1074395294:

+			{ errorText = "ERR_CONTOUR_INDEX_OUT_OF_RANGE";break;}

+		case -1074395295:

+			{ errorText = "ERR_INVALID_INTERPOLATIONMETHOD_INTERPOLATEPOINTS";break;}

+		case -1074395296:

+			{ errorText = "ERR_INVALID_BARCODETYPE";break;}

+		case -1074395297:

+			{ errorText = "ERR_INVALID_PARTICLEINFOMODE";break;}

+		case -1074395298:

+			{ errorText = "ERR_COMPLEXPLANE_NOT_REAL_OR_IMAGINARY";break;}

+		case -1074395299:

+			{ errorText = "ERR_INVALID_COMPLEXPLANE";break;}

+		case -1074395300:

+			{ errorText = "ERR_INVALID_METERARCMODE";break;}

+		case -1074395301:

+			{ errorText = "ERR_ROI_NOT_2_LINES";break;}

+		case -1074395302:

+			{ errorText = "ERR_INVALID_THRESHOLDMETHOD";break;}

+		case -1074395303:

+			{ errorText = "ERR_INVALID_NUM_OF_CLASSES";break;}

+		case -1074395304:

+			{ errorText = "ERR_INVALID_MATHTRANSFORMMETHOD";break;}

+		case -1074395305:

+			{ errorText = "ERR_INVALID_REFERENCEMODE";break;}

+		case -1074395306:

+			{ errorText = "ERR_INVALID_TOOL";break;}

+		case -1074395307:

+			{ errorText = "ERR_PRECISION_NOT_GTR_THAN_0";break;}

+		case -1074395308:

+			{ errorText = "ERR_INVALID_COLORSENSITIVITY";break;}

+		case -1074395309:

+			{ errorText = "ERR_INVALID_WINDOW_THREAD_POLICY";break;}

+		case -1074395310:

+			{ errorText = "ERR_INVALID_PALETTE_TYPE";break;}

+		case -1074395311:

+			{ errorText = "ERR_INVALID_COLOR_SPECTRUM";break;}

+		case -1074395312:

+			{ errorText = "ERR_LCD_CALIBRATE";break;}

+		case -1074395313:

+			{ errorText = "ERR_WRITE_FILE_NOT_SUPPORTED";break;}

+		case -1074395316:

+			{ errorText = "ERR_INVALID_KERNEL_CODE";break;}

+		case -1074395317:

+			{ errorText = "ERR_UNDEF_POINT";break;}

+		case -1074395318:

+			{ errorText = "ERR_INSF_POINTS";break;}

+		case -1074395319:

+			{ errorText = "ERR_INVALID_SUBPIX_TYPE";break;}

+		case -1074395320:

+			{ errorText = "ERR_TEMPLATE_EMPTY";break;}

+		case -1074395321:

+			{ errorText = "ERR_INVALID_MORPHOLOGYMETHOD";break;}

+		case -1074395322:

+			{ errorText = "ERR_INVALID_TEXTALIGNMENT";break;}

+		case -1074395323:

+			{ errorText = "ERR_INVALID_FONTCOLOR";break;}

+		case -1074395324:

+			{ errorText = "ERR_INVALID_SHAPEMODE";break;}

+		case -1074395325:

+			{ errorText = "ERR_INVALID_DRAWMODE";break;}

+		case -1074395326:

+			{ errorText = "ERR_INVALID_DRAWMODE_FOR_LINE";break;}

+		case -1074395327:

+			{ errorText = "ERR_INVALID_SCALINGMODE";break;}

+		case -1074395328:

+			{ errorText = "ERR_INVALID_INTERPOLATIONMETHOD";break;}

+		case -1074395329:

+			{ errorText = "ERR_INVALID_OUTLINEMETHOD";break;}

+		case -1074395330:

+			{ errorText = "ERR_INVALID_BORDER_SIZE";break;}

+		case -1074395331:

+			{ errorText = "ERR_INVALID_BORDERMETHOD";break;}

+		case -1074395332:

+			{ errorText = "ERR_INVALID_COMPAREFUNCTION";break;}

+		case -1074395333:

+			{ errorText = "ERR_INVALID_VERTICAL_TEXT_ALIGNMENT";break;}

+		case -1074395334:

+			{ errorText = "ERR_INVALID_CONVERSIONSTYLE";break;}

+		case -1074395335:

+			{ errorText = "ERR_DISPATCH_STATUS_CONFLICT";break;}

+		case -1074395336:

+			{ errorText = "ERR_UNKNOWN_ALGORITHM";break;}

+		case -1074395340:

+			{ errorText = "ERR_INVALID_SIZETYPE";break;}

+		case -1074395343:

+			{ errorText = "ERR_FILE_FILENAME_NULL";break;}

+		case -1074395345:

+			{ errorText = "ERR_INVALID_FLIPAXIS";break;}

+		case -1074395346:

+			{ errorText = "ERR_INVALID_INTERPOLATIONMETHOD_FOR_ROTATE";break;}

+		case -1074395347:

+			{ errorText = "ERR_INVALID_3DDIRECTION";break;}

+		case -1074395348:

+			{ errorText = "ERR_INVALID_3DPLANE";break;}

+		case -1074395349:

+			{ errorText = "ERR_INVALID_SKELETONMETHOD";break;}

+		case -1074395350:

+			{ errorText = "ERR_INVALID_VISION_INFO";break;}

+		case -1074395351:

+			{ errorText = "ERR_INVALID_RECT";break;}

+		case -1074395352:

+			{ errorText = "ERR_INVALID_FEATURE_MODE";break;}

+		case -1074395353:

+			{ errorText = "ERR_INVALID_SEARCH_STRATEGY";break;}

+		case -1074395354:

+			{ errorText = "ERR_INVALID_COLOR_WEIGHT";break;}

+		case -1074395355:

+			{ errorText = "ERR_INVALID_NUM_MATCHES_REQUESTED";break;}

+		case -1074395356:

+			{ errorText = "ERR_INVALID_MIN_MATCH_SCORE";break;}

+		case -1074395357:

+			{ errorText = "ERR_INVALID_COLOR_IGNORE_MODE";break;}

+		case -1074395360:

+			{ errorText = "ERR_COMPLEX_PLANE";break;}

+		case -1074395361:

+			{ errorText = "ERR_INVALID_STEEPNESS";break;}

+		case -1074395362:

+			{ errorText = "ERR_INVALID_WIDTH";break;}

+		case -1074395363:

+			{ errorText = "ERR_INVALID_SUBSAMPLING_RATIO";break;}

+		case -1074395364:

+			{ errorText = "ERR_IGNORE_COLOR_SPECTRUM_SET";break;}

+		case -1074395365:

+			{ errorText = "ERR_COLOR_TEMPLATE_DESCRIPTOR_NOSPECTRUM";break;}

+		case -1074395366:

+			{ errorText = "ERR_COLOR_TEMPLATE_DESCRIPTOR_NOSHAPE";break;}

+		case -1074395367:

+			{ errorText = "ERR_COLOR_TEMPLATE_DESCRIPTOR_ROTATION_5";break;}

+		case -1074395368:

+			{ errorText = "ERR_COLOR_TEMPLATE_DESCRIPTOR_ROTATION_4";break;}

+		case -1074395369:

+			{ errorText = "ERR_COLOR_TEMPLATE_DESCRIPTOR_ROTATION_3";break;}

+		case -1074395370:

+			{ errorText = "ERR_COLOR_TEMPLATE_DESCRIPTOR_ROTATION_2";break;}

+		case -1074395371:

+			{ errorText = "ERR_COLOR_TEMPLATE_DESCRIPTOR_ROTATION_1";break;}

+		case -1074395372:

+			{ errorText = "ERR_COLOR_TEMPLATE_DESCRIPTOR_NOROTATION";break;}

+		case -1074395373:

+			{ errorText = "ERR_COLOR_TEMPLATE_DESCRIPTOR_ROTATION";break;}

+		case -1074395374:

+			{ errorText = "ERR_COLOR_TEMPLATE_DESCRIPTOR_SHIFT_2";break;}

+		case -1074395375:

+			{ errorText = "ERR_COLOR_TEMPLATE_DESCRIPTOR_SHIFT_1";break;}

+		case -1074395376:

+			{ errorText = "ERR_COLOR_TEMPLATE_DESCRIPTOR_NOSHIFT";break;}

+		case -1074395377:

+			{ errorText = "ERR_COLOR_TEMPLATE_DESCRIPTOR_SHIFT";break;}

+		case -1074395378:

+			{ errorText = "ERR_COLOR_TEMPLATE_DESCRIPTOR_6";break;}

+		case -1074395379:

+			{ errorText = "ERR_COLOR_TEMPLATE_DESCRIPTOR_5";break;}

+		case -1074395380:

+			{ errorText = "ERR_COLOR_TEMPLATE_DESCRIPTOR_4";break;}

+		case -1074395381:

+			{ errorText = "ERR_COLOR_TEMPLATE_DESCRIPTOR_3";break;}

+		case -1074395382:

+			{ errorText = "ERR_COLOR_TEMPLATE_DESCRIPTOR_2";break;}

+		case -1074395383:

+			{ errorText = "ERR_COLOR_TEMPLATE_DESCRIPTOR_1";break;}

+		case -1074395384:

+			{ errorText = "ERR_COLOR_TEMPLATE_DESCRIPTOR";break;}

+		case -1074395385:

+			{ errorText = "ERR_COLOR_ROTATION_REQUIRES_SHAPE_FEATURE";break;}

+		case -1074395386:

+			{ errorText = "ERR_COLOR_MATCH_SETUP_DATA_SHAPE";break;}

+		case -1074395387:

+			{ errorText = "ERR_COLOR_MATCH_SETUP_DATA";break;}

+		case -1074395388:

+			{ errorText = "ERR_COLOR_LEARN_SETUP_DATA_SHAPE";break;}

+		case -1074395389:

+			{ errorText = "ERR_COLOR_LEARN_SETUP_DATA";break;}

+		case -1074395390:

+			{ errorText = "ERR_COLOR_TEMPLATE_IMAGE_LUMINANCE_CONTRAST_TOO_LOW";break;}

+		case -1074395391:

+			{ errorText = "ERR_COLOR_TEMPLATE_IMAGE_HUE_CONTRAST_TOO_LOW";break;}

+		case -1074395392:

+			{ errorText = "ERR_COLOR_TEMPLATE_IMAGE_TOO_LARGE";break;}

+		case -1074395393:

+			{ errorText = "ERR_COLOR_TEMPLATE_IMAGE_TOO_SMALL";break;}

+		case -1074395394:

+			{ errorText = "ERR_COLOR_SPECTRUM_MASK";break;}

+		case -1074395395:

+			{ errorText = "ERR_COLOR_IMAGE_REQUIRED";break;}

+		case -1074395397:

+			{ errorText = "ERR_COMPLEX_IMAGE_REQUIRED";break;}

+		case -1074395399:

+			{ errorText = "ERR_MULTICORE_INVALID_ARGUMENT";break;}

+		case -1074395400:

+			{ errorText = "ERR_MULTICORE_OPERATION";break;}

+		case -1074395401:

+			{ errorText = "ERR_INVALID_MATCHFACTOR";break;}

+		case -1074395402:

+			{ errorText = "ERR_INVALID_MAXPOINTS";break;}

+		case -1074395403:

+			{ errorText = "ERR_EXTRAINFO_VERSION";break;}

+		case -1074395404:

+			{ errorText = "ERR_INVALID_INTERPOLATIONMETHOD_FOR_UNWRAP";break;}

+		case -1074395405:

+			{ errorText = "ERR_INVALID_TEXTORIENTATION";break;}

+		case -1074395406:

+			{ errorText = "ERR_COORDSYS_NOT_FOUND";break;}

+		case -1074395407:

+			{ errorText = "ERR_INVALID_CONTRAST";break;}

+		case -1074395408:

+			{ errorText = "ERR_INVALID_DETECTION_MODE";break;}

+		case -1074395409:

+			{ errorText = "ERR_INVALID_SUBPIXEL_DIVISIONS";break;}

+		case -1074395410:

+			{ errorText = "ERR_INVALID_ICONS_PER_LINE";break;}

+		case -1074395549:

+			{ errorText = "ERR_NIOCR_INVALID_NUMBER_OF_OBJECTS_TO_VERIFY";break;}

+		case -1074395550:

+			{ errorText = "ERR_NIOCR_INVALID_CHARACTER_VALUE";break;}

+		case -1074395551:

+			{ errorText = "ERR_NIOCR_RENAME_REFCHAR";break;}

+		case -1074395552:

+			{ errorText = "ERR_NIOCR_NOT_A_VALID_CHARACTER_SET";break;}

+		case -1074395553:

+			{ errorText = "ERR_NIOCR_INVALID_MIN_BOUNDING_RECT_HEIGHT";break;}

+		case -1074395554:

+			{ errorText = "ERR_NIOCR_INVALID_READ_RESOLUTION";break;}

+		case -1074395555:

+			{ errorText = "ERR_NIOCR_INVALID_SPACING_RANGE";break;}

+		case -1074395556:

+			{ errorText = "ERR_NIOCR_INVALID_BOUNDING_RECT_HEIGHT_RANGE";break;}

+		case -1074395557:

+			{ errorText = "ERR_NIOCR_INVALID_BOUNDING_RECT_WIDTH_RANGE";break;}

+		case -1074395558:

+			{ errorText = "ERR_NIOCR_INVALID_CHARACTER_SIZE_RANGE";break;}

+		case -1074395559:

+			{ errorText = "ERR_NIOCR_INVALID_READ_OPTION";break;}

+		case -1074395560:

+			{ errorText = "ERR_NIOCR_INVALID_OBJECT_INDEX";break;}

+		case -1074395561:

+			{ errorText = "ERR_NIOCR_INVALID_NUMBER_OF_CHARACTERS";break;}

+		case -1074395562:

+			{ errorText = "ERR_NIOCR_BOOLEAN_VALUE_FOR_STRING_ATTRIBUTE";break;}

+		case -1074395563:

+			{ errorText = "ERR_NIOCR_UNLICENSED";break;}

+		case -1074395564:

+			{ errorText = "ERR_NIOCR_INVALID_PREDEFINED_CHARACTER";break;}

+		case -1074395565:

+			{ errorText = "ERR_NIOCR_MUST_BE_SINGLE_CHARACTER";break;}

+		case -1074395566:

+			{ errorText = "ERR_NIOCR_BOOLEAN_VALUE_FOR_INTEGER_ATTRIBUTE";break;}

+		case -1074395567:

+			{ errorText = "ERR_NIOCR_STRING_VALUE_FOR_BOOLEAN_ATTRIBUTE";break;}

+		case -1074395568:

+			{ errorText = "ERR_NIOCR_STRING_VALUE_FOR_INTEGER_ATTRIBUTE";break;}

+		case -1074395569:

+			{ errorText = "ERR_NIOCR_INVALID_ATTRIBUTE";break;}

+		case -1074395570:

+			{ errorText = "ERR_NIOCR_INTEGER_VALUE_FOR_BOOLEAN_ATTRIBUTE";break;}

+		case -1074395571:

+			{ errorText = "ERR_NIOCR_GET_ONLY_ATTRIBUTE";break;}

+		case -1074395572:

+			{ errorText = "ERR_NIOCR_INTEGER_VALUE_FOR_STRING_ATTRIBUTE";break;}

+		case -1074395573:

+			{ errorText = "ERR_NIOCR_INVALID_CHARACTER_SET_FILE_VERSION";break;}

+		case -1074395574:

+			{ errorText = "ERR_NIOCR_CHARACTER_SET_DESCRIPTION_TOO_LONG";break;}

+		case -1074395575:

+			{ errorText = "ERR_NIOCR_INVALID_NUMBER_OF_EROSIONS";break;}

+		case -1074395576:

+			{ errorText = "ERR_NIOCR_CHARACTER_VALUE_TOO_LONG";break;}

+		case -1074395577:

+			{ errorText = "ERR_NIOCR_CHARACTER_VALUE_CANNOT_BE_EMPTYSTRING";break;}

+		case -1074395578:

+			{ errorText = "ERR_NIOCR_INVALID_CHARACTER_SET_FILE";break;}

+		case -1074395579:

+			{ errorText = "ERR_NIOCR_INVALID_ASPECT_RATIO";break;}

+		case -1074395580:

+			{ errorText = "ERR_NIOCR_INVALID_MIN_BOUNDING_RECT_WIDTH";break;}

+		case -1074395581:

+			{ errorText = "ERR_NIOCR_INVALID_MAX_VERT_ELEMENT_SPACING";break;}

+		case -1074395582:

+			{ errorText = "ERR_NIOCR_INVALID_MAX_HORIZ_ELEMENT_SPACING";break;}

+		case -1074395583:

+			{ errorText = "ERR_NIOCR_INVALID_MIN_CHAR_SPACING";break;}

+		case -1074395584:

+			{ errorText = "ERR_NIOCR_INVALID_THRESHOLD_LIMITS";break;}

+		case -1074395585:

+			{ errorText = "ERR_NIOCR_INVALID_UPPER_THRESHOLD_LIMIT";break;}

+		case -1074395586:

+			{ errorText = "ERR_NIOCR_INVALID_LOWER_THRESHOLD_LIMIT";break;}

+		case -1074395587:

+			{ errorText = "ERR_NIOCR_INVALID_THRESHOLD_RANGE";break;}

+		case -1074395588:

+			{ errorText = "ERR_NIOCR_INVALID_HIGH_THRESHOLD_VALUE";break;}

+		case -1074395589:

+			{ errorText = "ERR_NIOCR_INVALID_LOW_THRESHOLD_VALUE";break;}

+		case -1074395590:

+			{ errorText = "ERR_NIOCR_INVALID_NUMBER_OF_VALID_CHARACTER_POSITIONS";break;}

+		case -1074395591:

+			{ errorText = "ERR_NIOCR_INVALID_CHARACTER_INDEX";break;}

+		case -1074395592:

+			{ errorText = "ERR_NIOCR_INVALID_READ_STRATEGY";break;}

+		case -1074395593:

+			{ errorText = "ERR_NIOCR_INVALID_NUMBER_OF_BLOCKS";break;}

+		case -1074395594:

+			{ errorText = "ERR_NIOCR_INVALID_SUBSTITUTION_CHARACTER";break;}

+		case -1074395595:

+			{ errorText = "ERR_NIOCR_INVALID_THRESHOLD_MODE";break;}

+		case -1074395596:

+			{ errorText = "ERR_NIOCR_INVALID_CHARACTER_SIZE";break;}

+		case -1074395597:

+			{ errorText = "ERR_NIOCR_NOT_A_VALID_SESSION";break;}

+		case -1074395598:

+			{ errorText = "ERR_NIOCR_INVALID_ACCEPTANCE_LEVEL";break;}

+		case -1074395600:

+			{ errorText = "ERR_INFO_NOT_FOUND";break;}

+		case -1074395601:

+			{ errorText = "ERR_INVALID_EDGE_THRESHOLD";break;}

+		case -1074395602:

+			{ errorText = "ERR_INVALID_MINIMUM_CURVE_LENGTH";break;}

+		case -1074395603:

+			{ errorText = "ERR_INVALID_ROW_STEP";break;}

+		case -1074395604:

+			{ errorText = "ERR_INVALID_COLUMN_STEP";break;}

+		case -1074395605:

+			{ errorText = "ERR_INVALID_MAXIMUM_END_POINT_GAP";break;}

+		case -1074395606:

+			{ errorText = "ERR_INVALID_MINIMUM_FEATURES_TO_MATCH";break;}

+		case -1074395607:

+			{ errorText = "ERR_INVALID_MAXIMUM_FEATURES_PER_MATCH";break;}

+		case -1074395608:

+			{ errorText = "ERR_INVALID_SUBPIXEL_ITERATIONS";break;}

+		case -1074395609:

+			{ errorText = "ERR_INVALID_SUBPIXEL_TOLERANCE";break;}

+		case -1074395610:

+			{ errorText = "ERR_INVALID_INITIAL_MATCH_LIST_LENGTH";break;}

+		case -1074395611:

+			{ errorText = "ERR_INVALID_MINIMUM_RECTANGLE_DIMENSION";break;}

+		case -1074395612:

+			{ errorText = "ERR_INVALID_MINIMUM_FEATURE_RADIUS";break;}

+		case -1074395613:

+			{ errorText = "ERR_INVALID_MINIMUM_FEATURE_LENGTH";break;}

+		case -1074395614:

+			{ errorText = "ERR_INVALID_MINIMUM_FEATURE_ASPECT_RATIO";break;}

+		case -1074395615:

+			{ errorText = "ERR_INVALID_MINIMUM_FEATURE_STRENGTH";break;}

+		case -1074395616:

+			{ errorText = "ERR_INVALID_EDGE_FILTER_SIZE";break;}

+		case -1074395617:

+			{ errorText = "ERR_INVALID_NUMBER_OF_FEATURES_RANGE";break;}

+		case -1074395618:

+			{ errorText = "ERR_TOO_MANY_SCALE_RANGES";break;}

+		case -1074395619:

+			{ errorText = "ERR_TOO_MANY_OCCLUSION_RANGES";break;}

+		case -1074395620:

+			{ errorText = "ERR_INVALID_CURVE_EXTRACTION_MODE";break;}

+		case -1074395621:

+			{ errorText = "ERR_INVALID_LEARN_GEOMETRIC_PATTERN_SETUP_DATA";break;}

+		case -1074395622:

+			{ errorText = "ERR_INVALID_MATCH_GEOMETRIC_PATTERN_SETUP_DATA";break;}

+		case -1074395623:

+			{ errorText = "ERR_INVALID_SCALE_RANGE";break;}

+		case -1074395624:

+			{ errorText = "ERR_INVALID_OCCLUSION_RANGE";break;}

+		case -1074395625:

+			{ errorText = "ERR_INVALID_MATCH_CONSTRAINT_TYPE";break;}

+		case -1074395626:

+			{ errorText = "ERR_NOT_ENOUGH_TEMPLATE_FEATURES";break;}

+		case -1074395627:

+			{ errorText = "ERR_NOT_ENOUGH_TEMPLATE_FEATURES_1";break;}

+		case -1074395628:

+			{ errorText = "ERR_INVALID_GEOMETRIC_MATCHING_TEMPLATE";break;}

+		case -1074395629:

+			{ errorText = "ERR_INVALID_MAXIMUM_PIXEL_DISTANCE_FROM_LINE";break;}

+		case -1074395630:

+			{ errorText = "ERR_INVALID_MAXIMUM_FEATURES_LEARNED";break;}

+		case -1074395631:

+			{ errorText = "ERR_INVALID_MIN_MATCH_SEPARATION_DISTANCE";break;}

+		case -1074395632:

+			{ errorText = "ERR_INVALID_MIN_MATCH_SEPARATION_ANGLE";break;}

+		case -1074395633:

+			{ errorText = "ERR_INVALID_MIN_MATCH_SEPARATION_SCALE";break;}

+		case -1074395634:

+			{ errorText = "ERR_INVALID_MAX_MATCH_OVERLAP";break;}

+		case -1074395635:

+			{ errorText = "ERR_INVALID_SHAPE_DESCRIPTOR";break;}

+		case -1074395636:

+			{ errorText = "ERR_DIRECTX_NOT_FOUND";break;}

+		case -1074395637:

+			{ errorText = "ERR_HARDWARE_DOESNT_SUPPORT_NONTEARING";break;}

+		case -1074395638:

+			{ errorText = "ERR_INVALID_FILL_STYLE";break;}

+		case -1074395639:

+			{ errorText = "ERR_INVALID_HATCH_STYLE";break;}

+		case -1074395640:

+			{ errorText = "ERR_TOO_MANY_ZONES";break;}

+		case -1074395641:

+			{ errorText = "ERR_DUPLICATE_LABEL";break;}

+		case -1074395642:

+			{ errorText = "ERR_LABEL_NOT_FOUND";break;}

+		case -1074395643:

+			{ errorText = "ERR_INVALID_NUMBER_OF_MATCH_OPTIONS";break;}

+		case -1074395644:

+			{ errorText = "ERR_LABEL_TOO_LONG";break;}

+		case -1074395645:

+			{ errorText = "ERR_INVALID_NUMBER_OF_LABELS";break;}

+		case -1074395646:

+			{ errorText = "ERR_NO_TEMPLATE_TO_LEARN";break;}

+		case -1074395647:

+			{ errorText = "ERR_INVALID_MULTIPLE_GEOMETRIC_TEMPLATE";break;}

+		case -1074395648:

+			{ errorText = "ERR_TEMPLATE_NOT_LEARNED";break;}

+		case -1074395649:

+			{ errorText = "ERR_INVALID_GEOMETRIC_FEATURE_TYPE";break;}

+		case -1074395650:

+			{ errorText = "ERR_CURVE_EXTRACTION_MODE_MUST_BE_SAME";break;}

+		case -1074395651:

+			{ errorText = "ERR_EDGE_FILTER_SIZE_MUST_BE_SAME";break;}

+		case -1074395652:

+			{ errorText = "ERR_OPENING_NEWER_GEOMETRIC_MATCHING_TEMPLATE";break;}

+		case -1074395653:

+			{ errorText = "ERR_OPENING_NEWER_MULTIPLE_GEOMETRIC_TEMPLATE";break;}

+		case -1074395654:

+			{ errorText = "ERR_GRADING_INFORMATION_NOT_FOUND";break;}

+		case -1074395655:

+			{ errorText = "ERR_ENABLE_CALIBRATION_SUPPORT_MUST_BE_SAME";break;}

+		case -1074395656:

+			{ errorText = "ERR_SMOOTH_CONTOURS_MUST_BE_SAME";break;}

+		case -1074395700:

+			{ errorText = "ERR_REQUIRES_WIN2000_OR_NEWER";break;}

+		case -1074395701:

+			{ errorText = "ERR_INVALID_MATRIX_SIZE_RANGE";break;}

+		case -1074395702:

+			{ errorText = "ERR_INVALID_LENGTH";break;}

+		case -1074395703:

+			{ errorText = "ERR_INVALID_TYPE_OF_FLATTEN";break;}

+		case -1074395704:

+			{ errorText = "ERR_INVALID_COMPRESSION_TYPE";break;}

+		case -1074395705:

+			{ errorText = "ERR_DATA_CORRUPTED";break;}

+		case -1074395706:

+			{ errorText = "ERR_AVI_SESSION_ALREADY_OPEN";break;}

+		case -1074395707:

+			{ errorText = "ERR_AVI_WRITE_SESSION_REQUIRED";break;}

+		case -1074395708:

+			{ errorText = "ERR_AVI_READ_SESSION_REQUIRED";break;}

+		case -1074395709:

+			{ errorText = "ERR_AVI_UNOPENED_SESSION";break;}

+		case -1074395710:

+			{ errorText = "ERR_TOO_MANY_PARTICLES";break;}

+		case -1074395711:

+			{ errorText = "ERR_NOT_ENOUGH_REGIONS";break;}

+		case -1074395712:

+			{ errorText = "ERR_WRONG_REGION_TYPE";break;}

+		case -1074395713:

+			{ errorText = "ERR_VALUE_NOT_IN_ENUM";break;}

+		case -1074395714:

+			{ errorText = "ERR_INVALID_AXIS_ORIENTATION";break;}

+		case -1074395715:

+			{ errorText = "ERR_INVALID_CALIBRATION_UNIT";break;}

+		case -1074395716:

+			{ errorText = "ERR_INVALID_SCALING_METHOD";break;}

+		case -1074395717:

+			{ errorText = "ERR_INVALID_RANGE";break;}

+		case -1074395718:

+			{ errorText = "ERR_LAB_VERSION";break;}

+		case -1074395719:

+			{ errorText = "ERR_BAD_ROI_BOX";break;}

+		case -1074395720:

+			{ errorText = "ERR_BAD_ROI";break;}

+		case -1074395721:

+			{ errorText = "ERR_INVALID_BIT_DEPTH";break;}

+		case -1074395722:

+			{ errorText = "ERR_CLASSIFIER_CLASSIFY_IMAGE_WITH_CUSTOM_SESSION";break;}

+		case -1074395723:

+			{ errorText = "ERR_CUSTOMDATA_KEY_NOT_FOUND";break;}

+		case -1074395724:

+			{ errorText = "ERR_CUSTOMDATA_INVALID_SIZE";break;}

+		case -1074395725:

+			{ errorText = "ERR_DATA_VERSION";break;}

+		case -1074395726:

+			{ errorText = "ERR_MATCHFACTOR_OBSOLETE";break;}

+		case -1074395727:

+			{ errorText = "ERR_UNSUPPORTED_2D_BARCODE_SEARCH_MODE";break;}

+		case -1074395728:

+			{ errorText = "ERR_INVALID_2D_BARCODE_SEARCH_MODE";break;}

+		case -1074395754:

+			{ errorText = "ERR_TRIG_TIMEOUT";break;}

+		case -1074395756:

+			{ errorText = "ERR_DLL_FUNCTION_NOT_FOUND";break;}

+		case -1074395757:

+			{ errorText = "ERR_DLL_NOT_FOUND";break;}

+		case -1074395758:

+			{ errorText = "ERR_BOARD_NOT_OPEN";break;}

+		case -1074395760:

+			{ errorText = "ERR_BOARD_NOT_FOUND";break;}

+		case -1074395762:

+			{ errorText = "ERR_INVALID_NIBLACK_DEVIATION_FACTOR";break;}

+		case -1074395763:

+			{ errorText = "ERR_INVALID_NORMALIZATION_METHOD";break;}

+		case -1074395766:

+			{ errorText = "ERR_DEPRECATED_FUNCTION";break;}

+		case -1074395767:

+			{ errorText = "ERR_INVALID_ALIGNMENT";break;}

+		case -1074395768:

+			{ errorText = "ERR_INVALID_SCALE";break;}

+		case -1074395769:

+			{ errorText = "ERR_INVALID_EDGE_THICKNESS";break;}

+		case -1074395770:

+			{ errorText = "ERR_INVALID_INSPECTION_TEMPLATE";break;}

+		case -1074395771:

+			{ errorText = "ERR_OPENING_NEWER_INSPECTION_TEMPLATE";break;}

+		case -1074395772:

+			{ errorText = "ERR_INVALID_REGISTRATION_METHOD";break;}

+		case -1074395773:

+			{ errorText = "ERR_NO_DEST_IMAGE";break;}

+		case -1074395774:

+			{ errorText = "ERR_NO_LABEL";break;}

+		case -1074395775:

+			{ errorText = "ERR_ROI_HAS_OPEN_CONTOURS";break;}

+		case -1074395776:

+			{ errorText = "ERR_INVALID_USE_OF_COMPACT_SESSION_FILE";break;}

+		case -1074395777:

+			{ errorText = "ERR_INCOMPATIBLE_CLASSIFIER_TYPES";break;}

+		case -1074395778:

+			{ errorText = "ERR_INVALID_KERNEL_SIZE";break;}

+		case -1074395779:

+			{ errorText = "ERR_CANNOT_COMPACT_UNTRAINED";break;}

+		case -1074395780:

+			{ errorText = "ERR_INVALID_PARTICLE_TYPE";break;}

+		case -1074395781:

+			{ errorText = "ERR_CLASSIFIER_INVALID_ENGINE_TYPE";break;}

+		case -1074395782:

+			{ errorText = "ERR_DESCRIPTION_TOO_LONG";break;}

+		case -1074395783:

+			{ errorText = "ERR_BAD_SAMPLE_INDEX";break;}

+		case -1074395784:

+			{ errorText = "ERR_INVALID_LIMITS";break;}

+		case -1074395785:

+			{ errorText = "ERR_NO_PARTICLE";break;}

+		case -1074395786:

+			{ errorText = "ERR_INVALID_PARTICLE_OPTIONS";break;}

+		case -1074395787:

+			{ errorText = "ERR_INVALID_CLASSIFIER_TYPE";break;}

+		case -1074395788:

+			{ errorText = "ERR_NO_SAMPLES";break;}

+		case -1074395789:

+			{ errorText = "ERR_OPENING_NEWER_CLASSIFIER_SESSION";break;}

+		case -1074395790:

+			{ errorText = "ERR_INVALID_DISTANCE_METRIC";break;}

+		case -1074395791:

+			{ errorText = "ERR_CLASSIFIER_INVALID_SESSION_TYPE";break;}

+		case -1074395792:

+			{ errorText = "ERR_CLASSIFIER_SESSION_NOT_TRAINED";break;}

+		case -1074395793:

+			{ errorText = "ERR_INVALID_OPERATION_ON_COMPACT_SESSION_ATTEMPTED";break;}

+		case -1074395794:

+			{ errorText = "ERR_K_TOO_HIGH";break;}

+		case -1074395795:

+			{ errorText = "ERR_K_TOO_LOW";break;}

+		case -1074395796:

+			{ errorText = "ERR_INVALID_KNN_METHOD";break;}

+		case -1074395797:

+			{ errorText = "ERR_INVALID_CLASSIFIER_SESSION";break;}

+		case -1074395798:

+			{ errorText = "ERR_INVALID_CUSTOM_SAMPLE";break;}

+		case -1074395799:

+			{ errorText = "ERR_INTERNAL";break;}

+		case -1074395800:

+			{ errorText = "ERR_PROTECTION";break;}

+		case -1074395801:

+			{ errorText = "ERR_TOO_MANY_CONTOURS";break;}

+		case -1074395837:

+			{ errorText = "ERR_INVALID_COMPRESSION_RATIO";break;}

+		case -1074395840:

+			{ errorText = "ERR_BAD_INDEX";break;}

+		case -1074395875:

+			{ errorText = "ERR_BARCODE_PHARMACODE";break;}

+		case -1074395876:

+			{ errorText = "ERR_UNSUPPORTED_COLOR_MODE";break;}

+		case -1074395877:

+			{ errorText = "ERR_COLORMODE_REQUIRES_CHANGECOLORSPACE2";break;}

+		case -1074395878:

+			{ errorText = "ERR_PROP_NODE_WRITE_NOT_SUPPORTED";break;}

+		case -1074395879:

+			{ errorText = "ERR_BAD_MEASURE";break;}

+		case -1074395880:

+			{ errorText = "ERR_PARTICLE";break;}

+		case -1074395920:

+			{ errorText = "ERR_NUMBER_CLASS";break;}

+		case -1074395953:

+			{ errorText = "ERR_INVALID_WAVELET_TRANSFORM_MODE";break;}

+		case -1074395954:

+			{ errorText = "ERR_INVALID_QUANTIZATION_STEP_SIZE";break;}

+		case -1074395955:

+			{ errorText = "ERR_INVALID_MAX_WAVELET_TRANSFORM_LEVEL";break;}

+		case -1074395956:

+			{ errorText = "ERR_INVALID_QUALITY";break;}

+		case -1074395957:

+			{ errorText = "ERR_ARRAY_SIZE_MISMATCH";break;}

+		case -1074395958:

+			{ errorText = "ERR_WINDOW_ID";break;}

+		case -1074395959:

+			{ errorText = "ERR_CREATE_WINDOW";break;}

+		case -1074395960:

+			{ errorText = "ERR_INIT";break;}

+		case -1074395971:

+			{ errorText = "ERR_INVALID_OFFSET";break;}

+		case -1074395972:

+			{ errorText = "ERR_DIRECTX_ENUMERATE_FILTERS";break;}

+		case -1074395973:

+			{ errorText = "ERR_JPEG2000_UNSUPPORTED_MULTIPLE_LAYERS";break;}

+		case -1074395974:

+			{ errorText = "ERR_UNSUPPORTED_JPEG2000_COLORSPACE_METHOD";break;}

+		case -1074395975:

+			{ errorText = "ERR_AVI_TIMEOUT";break;}

+		case -1074395976:

+			{ errorText = "ERR_NUMBER_OF_PALETTE_COLORS";break;}

+		case -1074395977:

+			{ errorText = "ERR_AVI_VERSION";break;}

+		case -1074395978:

+			{ errorText = "ERR_INVALID_PARTICLE_NUMBER";break;}

+		case -1074395979:

+			{ errorText = "ERR_INVALID_PARTICLE_INFO";break;}

+		case -1074395980:

+			{ errorText = "ERR_COM_INITIALIZE";break;}

+		case -1074395981:

+			{ errorText = "ERR_INSUFFICIENT_BUFFER_SIZE";break;}

+		case -1074395982:

+			{ errorText = "ERR_INVALID_FRAMES_PER_SECOND";break;}

+		case -1074395983:

+			{ errorText = "ERR_FILE_NO_SPACE";break;}

+		case -1074395984:

+			{ errorText = "ERR_FILE_INVALID_DATA_TYPE";break;}

+		case -1074395985:

+			{ errorText = "ERR_FILE_OPERATION";break;}

+		case -1074395986:

+			{ errorText = "ERR_FILE_FORMAT";break;}

+		case -1074395987:

+			{ errorText = "ERR_FILE_EOF";break;}

+		case -1074395988:

+			{ errorText = "ERR_FILE_WRITE";break;}

+		case -1074395989:

+			{ errorText = "ERR_FILE_READ";break;}

+		case -1074395990:

+			{ errorText = "ERR_FILE_GET_INFO";break;}

+		case -1074395991:

+			{ errorText = "ERR_FILE_INVALID_TYPE";break;}

+		case -1074395992:

+			{ errorText = "ERR_FILE_PERMISSION";break;}

+		case -1074395993:

+			{ errorText = "ERR_FILE_IO_ERR";break;}

+		case -1074395994:

+			{ errorText = "ERR_FILE_TOO_MANY_OPEN";break;}

+		case -1074395995:

+			{ errorText = "ERR_FILE_NOT_FOUND";break;}

+		case -1074395996:

+			{ errorText = "ERR_FILE_OPEN";break;}

+		case -1074395997:

+			{ errorText = "ERR_FILE_ARGERR";break;}

+		case -1074395998:

+			{ errorText = "ERR_FILE_COLOR_TABLE";break;}

+		case -1074395999:

+			{ errorText = "ERR_FILE_FILE_TYPE";break;}

+		case -1074396000:

+			{ errorText = "ERR_FILE_FILE_HEADER";break;}

+		case -1074396001:

+			{ errorText = "ERR_TOO_MANY_AVI_SESSIONS";break;}

+		case -1074396002:

+			{ errorText = "ERR_INVALID_LINEGAUGEMETHOD";break;}

+		case -1074396003:

+			{ errorText = "ERR_AVI_DATA_EXCEEDS_BUFFER_SIZE";break;}

+		case -1074396004:

+			{ errorText = "ERR_DIRECTX_CERTIFICATION_FAILURE";break;}

+		case -1074396005:

+			{ errorText = "ERR_INVALID_AVI_SESSION";break;}

+		case -1074396006:

+			{ errorText = "ERR_DIRECTX_UNKNOWN_COMPRESSION_FILTER";break;}

+		case -1074396007:

+			{ errorText = "ERR_DIRECTX_INCOMPATIBLE_COMPRESSION_FILTER";break;}

+		case -1074396008:

+			{ errorText = "ERR_DIRECTX_NO_FILTER";break;}

+		case -1074396009:

+			{ errorText = "ERR_DIRECTX";break;}

+		case -1074396010:

+			{ errorText = "ERR_INVALID_FRAME_NUMBER";break;}

+		case -1074396011:

+			{ errorText = "ERR_RPC_BIND";break;}

+		case -1074396012:

+			{ errorText = "ERR_RPC_EXECUTE";break;}

+		case -1074396013:

+			{ errorText = "ERR_INVALID_VIDEO_MODE";break;}

+		case -1074396014:

+			{ errorText = "ERR_INVALID_VIDEO_BLIT";break;}

+		case -1074396015:

+			{ errorText = "ERR_RPC_EXECUTE_IVB";break;}

+		case -1074396016:

+			{ errorText = "ERR_NO_VIDEO_DRIVER";break;}

+		case -1074396017:

+			{ errorText = "ERR_OPENING_NEWER_AIM_GRADING_DATA";break;}

+		case -1074396018:

+			{ errorText = "ERR_INVALID_EDGE_POLARITY_SEARCH_MODE";break;}

+		case -1074396019:

+			{ errorText = "ERR_INVALID_THRESHOLD_PERCENTAGE";break;}

+		case -1074396020:

+			{ errorText = "ERR_INVALID_GRADING_MODE";break;}

+		case -1074396021:

+			{ errorText = "ERR_INVALID_KERNEL_SIZE_FOR_EDGE_DETECTION";break;}

+		case -1074396022:

+			{ errorText = "ERR_INVALID_SEARCH_MODE_FOR_STRAIGHT_EDGE";break;}

+		case -1074396023:

+			{ errorText = "ERR_INVALID_ANGLE_TOL_FOR_STRAIGHT_EDGE";break;}

+		case -1074396024:

+			{ errorText = "ERR_INVALID_MIN_COVERAGE_FOR_STRAIGHT_EDGE";break;}

+		case -1074396025:

+			{ errorText = "ERR_INVALID_ANGLE_RANGE_FOR_STRAIGHT_EDGE";break;}

+		case -1074396026:

+			{ errorText = "ERR_INVALID_PROCESS_TYPE_FOR_EDGE_DETECTION";break;}

+		case -1074396032:

+			{ errorText = "ERR_TEMPLATEDESCRIPTOR_ROTATION_SEARCHSTRATEGY";break;}

+		case -1074396033:

+			{ errorText = "ERR_TEMPLATEDESCRIPTOR_LEARNSETUPDATA";break;}

+		case -1074396034:

+			{ errorText = "ERR_TEMPLATEIMAGE_EDGEINFO";break;}

+		case -1074396035:

+			{ errorText = "ERR_TEMPLATEIMAGE_NOCIRCLE";break;}

+		case -1074396036:

+			{ errorText = "ERR_INVALID_SKELETONMODE";break;}

+		case -1074396037:

+			{ errorText = "ERR_TIMEOUT";break;}

+		case -1074396038:

+			{ errorText = "ERR_FIND_COORDSYS_MORE_THAN_ONE_EDGE";break;}

+		case -1074396039:

+			{ errorText = "ERR_IO_ERROR";break;}

+		case -1074396040:

+			{ errorText = "ERR_DRIVER";break;}

+		case -1074396041:

+			{ errorText = "ERR_INVALID_2D_BARCODE_TYPE";break;}

+		case -1074396042:

+			{ errorText = "ERR_INVALID_2D_BARCODE_CONTRAST";break;}

+		case -1074396043:

+			{ errorText = "ERR_INVALID_2D_BARCODE_CELL_SHAPE";break;}

+		case -1074396044:

+			{ errorText = "ERR_INVALID_2D_BARCODE_SHAPE";break;}

+		case -1074396045:

+			{ errorText = "ERR_INVALID_2D_BARCODE_SUBTYPE";break;}

+		case -1074396046:

+			{ errorText = "ERR_INVALID_2D_BARCODE_CONTRAST_FOR_ROI";break;}

+		case -1074396047:

+			{ errorText = "ERR_INVALID_LINEAR_AVERAGE_MODE";break;}

+		case -1074396048:

+			{ errorText = "ERR_INVALID_CELL_SAMPLE_SIZE";break;}

+		case -1074396049:

+			{ errorText = "ERR_INVALID_MATRIX_POLARITY";break;}

+		case -1074396050:

+			{ errorText = "ERR_INVALID_ECC_TYPE";break;}

+		case -1074396051:

+			{ errorText = "ERR_INVALID_CELL_FILTER_MODE";break;}

+		case -1074396052:

+			{ errorText = "ERR_INVALID_DEMODULATION_MODE";break;}

+		case -1074396053:

+			{ errorText = "ERR_INVALID_BORDER_INTEGRITY";break;}

+		case -1074396054:

+			{ errorText = "ERR_INVALID_CELL_FILL_TYPE";break;}

+		case -1074396055:

+			{ errorText = "ERR_INVALID_ASPECT_RATIO";break;}

+		case -1074396056:

+			{ errorText = "ERR_INVALID_MATRIX_MIRROR_MODE";break;}

+		case -1074396057:

+			{ errorText = "ERR_INVALID_SEARCH_VECTOR_WIDTH";break;}

+		case -1074396058:

+			{ errorText = "ERR_INVALID_ROTATION_MODE";break;}

+		case -1074396059:

+			{ errorText = "ERR_INVALID_MAX_ITERATIONS";break;}

+		case -1074396060:

+			{ errorText = "ERR_JPEG2000_LOSSLESS_WITH_FLOATING_POINT";break;}

+		case -1074396061:

+			{ errorText = "ERR_INVALID_WINDOW_SIZE";break;}

+		case -1074396062:

+			{ errorText = "ERR_INVALID_TOLERANCE";break;}

+		case -1074396063:

+			{ errorText = "ERR_EXTERNAL_ALIGNMENT";break;}

+		case -1074396064:

+			{ errorText = "ERR_EXTERNAL_NOT_SUPPORTED";break;}

+		case -1074396065:

+			{ errorText = "ERR_CANT_RESIZE_EXTERNAL";break;}

+		case -1074396066:

+			{ errorText = "ERR_INVALID_POINTSYMBOL";break;}

+		case -1074396067:

+			{ errorText = "ERR_IMAGES_NOT_DIFF";break;}

+		case -1074396068:

+			{ errorText = "ERR_INVALID_ACTION";break;}

+		case -1074396069:

+			{ errorText = "ERR_INVALID_COLOR_MODE";break;}

+		case -1074396070:

+			{ errorText = "ERR_INVALID_FUNCTION";break;}

+		case -1074396071:

+			{ errorText = "ERR_INVALID_SCAN_DIRECTION";break;}

+		case -1074396072:

+			{ errorText = "ERR_INVALID_BORDER";break;}

+		case -1074396073:

+			{ errorText = "ERR_MASK_OUTSIDE_IMAGE";break;}

+		case -1074396074:

+			{ errorText = "ERR_INCOMP_SIZE";break;}

+		case -1074396075:

+			{ errorText = "ERR_COORD_SYS_SECOND_AXIS";break;}

+		case -1074396076:

+			{ errorText = "ERR_COORD_SYS_FIRST_AXIS";break;}

+		case -1074396077:

+			{ errorText = "ERR_INCOMP_TYPE";break;}

+		case -1074396079:

+			{ errorText = "ERR_INVALID_METAFILE_HANDLE";break;}

+		case -1074396080:

+			{ errorText = "ERR_INVALID_IMAGE_TYPE";break;}

+		case -1074396081:

+			{ errorText = "ERR_BAD_PASSWORD";break;}

+		case -1074396082:

+			{ errorText = "ERR_PALETTE_NOT_SUPPORTED";break;}

+		case -1074396083:

+			{ errorText = "ERR_ROLLBACK_TIMEOUT";break;}

+		case -1074396084:

+			{ errorText = "ERR_ROLLBACK_DELETE_TIMER";break;}

+		case -1074396085:

+			{ errorText = "ERR_ROLLBACK_INIT_TIMER";break;}

+		case -1074396086:

+			{ errorText = "ERR_ROLLBACK_START_TIMER";break;}

+		case -1074396087:

+			{ errorText = "ERR_ROLLBACK_STOP_TIMER";break;}

+		case -1074396088:

+			{ errorText = "ERR_ROLLBACK_RESIZE";break;}

+		case -1074396089:

+			{ errorText = "ERR_ROLLBACK_RESOURCE_REINITIALIZE";break;}

+		case -1074396090:

+			{ errorText = "ERR_ROLLBACK_RESOURCE_ENABLED";break;}

+		case -1074396091:

+			{ errorText = "ERR_ROLLBACK_RESOURCE_UNINITIALIZED_ENABLE";break;}

+		case -1074396092:

+			{ errorText = "ERR_ROLLBACK_RESOURCE_NON_EMPTY_INITIALIZE";break;}

+		case -1074396093:

+			{ errorText = "ERR_ROLLBACK_RESOURCE_LOCKED";break;}

+		case -1074396094:

+			{ errorText = "ERR_ROLLBACK_RESOURCE_CANNOT_UNLOCK";break;}

+		case -1074396095:

+			{ errorText = "ERR_CALIBRATION_DUPLICATE_REFERENCE_POINT";break;}

+		case -1074396096:

+			{ errorText = "ERR_NOT_AN_OBJECT";break;}

+		case -1074396097:

+			{ errorText = "ERR_INVALID_PARTICLE_PARAMETER_VALUE";break;}

+		case -1074396098:

+			{ errorText = "ERR_RESERVED_MUST_BE_NULL";break;}

+		case -1074396099:

+			{ errorText = "ERR_CALIBRATION_INFO_SIMPLE_TRANSFORM";break;}

+		case -1074396100:

+			{ errorText = "ERR_CALIBRATION_INFO_PERSPECTIVE_PROJECTION";break;}

+		case -1074396101:

+			{ errorText = "ERR_CALIBRATION_INFO_MICRO_PLANE";break;}

+		case -1074396102:

+			{ errorText = "ERR_CALIBRATION_INFO_6";break;}

+		case -1074396103:

+			{ errorText = "ERR_CALIBRATION_INFO_5";break;}

+		case -1074396104:

+			{ errorText = "ERR_CALIBRATION_INFO_4";break;}

+		case -1074396105:

+			{ errorText = "ERR_CALIBRATION_INFO_3";break;}

+		case -1074396106:

+			{ errorText = "ERR_CALIBRATION_INFO_2";break;}

+		case -1074396107:

+			{ errorText = "ERR_CALIBRATION_INFO_1";break;}

+		case -1074396108:

+			{ errorText = "ERR_CALIBRATION_ERRORMAP";break;}

+		case -1074396109:

+			{ errorText = "ERR_CALIBRATION_INVALID_SCALING_FACTOR";break;}

+		case -1074396110:

+			{ errorText = "ERR_CALIBRATION_INFO_VERSION";break;}

+		case -1074396111:

+			{ errorText = "ERR_CALIBRATION_FAILED_TO_FIND_GRID";break;}

+		case -1074396112:

+			{ errorText = "ERR_INCOMP_MATRIX_SIZE";break;}

+		case -1074396113:

+			{ errorText = "ERR_CALIBRATION_IMAGE_UNCALIBRATED";break;}

+		case -1074396114:

+			{ errorText = "ERR_CALIBRATION_INVALID_ROI";break;}

+		case -1074396115:

+			{ errorText = "ERR_CALIBRATION_IMAGE_CORRECTED";break;}

+		case -1074396116:

+			{ errorText = "ERR_CALIBRATION_INSF_POINTS";break;}

+		case -1074396117:

+			{ errorText = "ERR_MATRIX_SIZE";break;}

+		case -1074396118:

+			{ errorText = "ERR_INVALID_STEP_SIZE";break;}

+		case -1074396119:

+			{ errorText = "ERR_CUSTOMDATA_INVALID_KEY";break;}

+		case -1074396120:

+			{ errorText = "ERR_NOT_IMAGE";break;}

+		case -1074396121:

+			{ errorText = "ERR_SATURATION_THRESHOLD_OUT_OF_RANGE";break;}

+		case -1074396122:

+			{ errorText = "ERR_DRAWTEXT_COLOR_MUST_BE_GRAYSCALE";break;}

+		case -1074396123:

+			{ errorText = "ERR_INVALID_CALIBRATION_MODE";break;}

+		case -1074396124:

+			{ errorText = "ERR_INVALID_CALIBRATION_ROI_MODE";break;}

+		case -1074396125:

+			{ errorText = "ERR_INVALID_CONTRAST_THRESHOLD";break;}

+		case -1074396126:

+			{ errorText = "ERR_ROLLBACK_RESOURCE_CONFLICT_1";break;}

+		case -1074396127:

+			{ errorText = "ERR_ROLLBACK_RESOURCE_CONFLICT_2";break;}

+		case -1074396128:

+			{ errorText = "ERR_ROLLBACK_RESOURCE_CONFLICT_3";break;}

+		case -1074396129:

+			{ errorText = "ERR_ROLLBACK_UNBOUNDED_INTERFACE";break;}

+		case -1074396130:

+			{ errorText = "ERR_NOT_RECT_OR_ROTATED_RECT";break;}

+		case -1074396132:

+			{ errorText = "ERR_MASK_NOT_TEMPLATE_SIZE";break;}

+		case -1074396133:

+			{ errorText = "ERR_THREAD_COULD_NOT_INITIALIZE";break;}

+		case -1074396134:

+			{ errorText = "ERR_THREAD_INITIALIZING";break;}

+		case -1074396135:

+			{ errorText = "ERR_INVALID_BUTTON_LABEL";break;}

+		case -1074396136:

+			{ errorText = "ERR_DIRECTX_INVALID_FILTER_QUALITY";break;}

+		case -1074396137:

+			{ errorText = "ERR_DIRECTX_DLL_NOT_FOUND";break;}

+		case -1074396138:

+			{ errorText = "ERR_ROLLBACK_NOT_SUPPORTED";break;}

+		case -1074396139:

+			{ errorText = "ERR_ROLLBACK_RESOURCE_OUT_OF_MEMORY";break;}

+		case -1074396140:

+			{ errorText = "ERR_BARCODE_CODE128_SET";break;}

+		case -1074396141:

+			{ errorText = "ERR_BARCODE_CODE128_FNC";break;}

+		case -1074396142:

+			{ errorText = "ERR_BARCODE_INVALID";break;}

+		case -1074396143:

+			{ errorText = "ERR_BARCODE_TYPE";break;}

+		case -1074396144:

+			{ errorText = "ERR_BARCODE_CODE93_SHIFT";break;}

+		case -1074396145:

+			{ errorText = "ERR_BARCODE_UPCA";break;}

+		case -1074396146:

+			{ errorText = "ERR_BARCODE_MSI";break;}

+		case -1074396147:

+			{ errorText = "ERR_BARCODE_I25";break;}

+		case -1074396148:

+			{ errorText = "ERR_BARCODE_EAN13";break;}

+		case -1074396149:

+			{ errorText = "ERR_BARCODE_EAN8";break;}

+		case -1074396150:

+			{ errorText = "ERR_BARCODE_CODE128";break;}

+		case -1074396151:

+			{ errorText = "ERR_BARCODE_CODE93";break;}

+		case -1074396152:

+			{ errorText = "ERR_BARCODE_CODE39";break;}

+		case -1074396153:

+			{ errorText = "ERR_BARCODE_CODABAR";break;}

+		case -1074396154:

+			{ errorText = "ERR_IMAGE_TOO_SMALL";break;}

+		case -1074396155:

+			{ errorText = "ERR_UNINIT";break;}

+		case -1074396156:

+			{ errorText = "ERR_NEED_FULL_VERSION";break;}

+		case -1074396157:

+			{ errorText = "ERR_UNREGISTERED";break;}

+		case -1074396158:

+			{ errorText = "ERR_MEMORY_ERROR";break;}

+		case -1074396159:

+			{ errorText = "ERR_OUT_OF_MEMORY";break;}

+		case -1074396160:

+			{ errorText = "ERR_SYSTEM_ERROR";break;}

+		case 0:

+			{ errorText = "ERR_SUCCESS";break;}

+		// end National Instruments defined errors

+			

+		// begin BAE defined errors

+		case ERR_VISION_GENERAL_ERROR:

+			{ errorText = "ERR_VISION_GENERAL_ERROR";break;}

+		case ERR_COLOR_NOT_FOUND:

+			{ errorText = "ERR_COLOR_NOT_FOUND";break;}

+		case ERR_PARTICLE_TOO_SMALL:

+			{ errorText = "ERR_PARTICLE_TOO_SMALL";break;}

+		case ERR_CAMERA_FAILURE:

+			{ errorText = "ERR_CAMERA_FAILURE";break;}

+		case ERR_CAMERA_SOCKET_CREATE_FAILED:

+			{ errorText = "ERR_CAMERA_SOCKET_CREATE_FAILED";break;}

+		case ERR_CAMERA_CONNECT_FAILED:

+			{ errorText = "ERR_CAMERA_CONNECT_FAILED";break;}

+		case ERR_CAMERA_STALE_IMAGE:

+			{ errorText = "ERR_CAMERA_STALE_IMAGE";break;}

+		case ERR_CAMERA_NOT_INITIALIZED:

+			{ errorText = "ERR_CAMERA_NOT_INITIALIZED";break;}

+		case ERR_CAMERA_NO_BUFFER_AVAILABLE:

+			{ errorText = "ERR_CAMERA_NO_BUFFER_AVAILABLE";break;}

+		case ERR_CAMERA_HEADER_ERROR:

+			{ errorText = "ERR_CAMERA_HEADER_ERROR";break;}

+		case ERR_CAMERA_BLOCKING_TIMEOUT:

+			{ errorText = "ERR_CAMERA_BLOCKING_TIMEOUT";break;}

+		case ERR_CAMERA_AUTHORIZATION_FAILED:

+			{ errorText = "ERR_CAMERA_AUTHORIZATION_FAILED";break;}

+		case ERR_CAMERA_TASK_SPAWN_FAILED:

+			{ errorText = "ERR_CAMERA_TASK_SPAWN_FAILED";break;}

+		case ERR_CAMERA_TASK_INPUT_OUT_OF_RANGE:

+			{ errorText = "ERR_CAMERA_TASK_INPUT_OUT_OF_RANGE";break;}

+		case ERR_CAMERA_COMMAND_FAILURE:

+			{ errorText = "ERR_CAMERA_COMMAND_FAILURE";break;}

+	}

+	

+	return errorText;

+}

+

+

+

diff --git a/azaleasource/WPILibCProgramming/trunk/WPILib/Vision2009/FrcError.h b/azaleasource/WPILibCProgramming/trunk/WPILib/Vision2009/FrcError.h
new file mode 100644
index 0000000..931bf03
--- /dev/null
+++ b/azaleasource/WPILibCProgramming/trunk/WPILib/Vision2009/FrcError.h
@@ -0,0 +1,41 @@
+/********************************************************************************

+*  Project   		: FIRST Motor Controller

+*  File Name  		: FrcError.h          

+*  Contributors   	: JDG, ELF

+*  Creation Date 	: August 12, 2008

+*  Revision History	: Source code & revision history maintained at sourceforge.WPI.edu      

+*  File Description	: Error handling values for C routines

+*/

+/*----------------------------------------------------------------------------*/

+/*        Copyright (c) FIRST 2008.  All Rights Reserved.                     */

+/*     Open Source Software - may be modified and shared by FRC teams.        */

+/*   Must be accompanied by the BSD license file in $(WIND_BASE)/WPILib.      */

+/*----------------------------------------------------------------------------*/

+

+#ifndef __FRCERROR_H__

+#define __FRCERROR_H__

+

+/* Error Codes */

+#define ERR_VISION_GENERAL_ERROR			166000	// 

+#define ERR_COLOR_NOT_FOUND					166100	// TrackAPI.cpp

+#define ERR_PARTICLE_TOO_SMALL				166101	// TrackAPI.cpp

+

+#define ERR_CAMERA_FAILURE					166200	// AxisCamera.cpp

+#define ERR_CAMERA_SOCKET_CREATE_FAILED		166201	// AxisCamera.cpp

+#define ERR_CAMERA_CONNECT_FAILED			166202	// AxisCamera.cpp

+#define ERR_CAMERA_STALE_IMAGE				166203	// AxisCamera.cpp

+#define ERR_CAMERA_NOT_INITIALIZED			166204	// AxisCamera.cpp

+#define ERR_CAMERA_NO_BUFFER_AVAILABLE		166205	// AxisCamera.cpp

+#define ERR_CAMERA_HEADER_ERROR				166206	// AxisCamera.cpp

+#define ERR_CAMERA_BLOCKING_TIMEOUT			166207	// AxisCamera.cpp

+#define ERR_CAMERA_AUTHORIZATION_FAILED		166208	// AxisCamera.cpp

+#define ERR_CAMERA_TASK_SPAWN_FAILED		166209	// AxisCamera.cpp

+#define ERR_CAMERA_TASK_INPUT_OUT_OF_RANGE	166210	// AxisCamera.cpp

+#define ERR_CAMERA_COMMAND_FAILURE			166211	// AxisCamera.cpp

+

+/* error handling functions */

+int GetLastVisionError();

+char* GetVisionErrorText(int errorCode);

+

+#endif

+

diff --git a/azaleasource/WPILibCProgramming/trunk/WPILib/Vision2009/TrackAPI.cpp b/azaleasource/WPILibCProgramming/trunk/WPILib/Vision2009/TrackAPI.cpp
new file mode 100644
index 0000000..41d40bc
--- /dev/null
+++ b/azaleasource/WPILibCProgramming/trunk/WPILib/Vision2009/TrackAPI.cpp
@@ -0,0 +1,481 @@
+/********************************************************************************

+*  Project   		: FIRST Motor Controller

+*  File Name  		: TrackAPI.cpp        

+*  Contributors   	: ELF, DWD

+*  Creation Date 	: August 10, 2008

+*  Revision History	: Source code & revision history maintained at sourceforge.WPI.edu   

+*  File Description	: Tracking Routines for FIRST Vision API

+*/ 

+/*----------------------------------------------------------------------------*/

+/*        Copyright (c) FIRST 2008.  All Rights Reserved.                     */

+/*  Open Source Software - may be modified and shared by FRC teams. The code  */

+/*  must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */

+/*----------------------------------------------------------------------------*/

+

+#include "string.h"

+#include "vxWorks.h" 

+

+#include "AxisCamera.h" 

+#include "FrcError.h"

+#include "TrackAPI.h" 

+#include "VisionAPI.h" 

+

+int TrackAPI_debugFlag = 0;

+#define DPRINTF if(TrackAPI_debugFlag)dprintf

+

+/**

+* @brief Find the largest particle that meets a criteria 

+* @param binaryImage Image to inspect

+* @param rect area to search

+* @return 0 = error

+*/

+bool InArea(Image* binaryImage, int particleIndex, Rect rect)

+{ 

+	double position;

+	

+	imaqMeasureParticle(binaryImage, particleIndex, 0, 

+			IMAQ_MT_BOUNDING_RECT_LEFT, &position);

+	if ( position < (rect.left             ) ) return false; // outside left of rectangle?

+	

+	imaqMeasureParticle(binaryImage, particleIndex, 0, 

+			IMAQ_MT_BOUNDING_RECT_TOP, &position);

+	if ( position < (rect.top              ) ) return false; // outside top of rectangle ?

+

+	imaqMeasureParticle(binaryImage, particleIndex, 0, 

+			IMAQ_MT_BOUNDING_RECT_RIGHT, &position);

+	if (position > (rect.left + rect.width) ) return false;	// outside right of rectangle ?

+	

+	imaqMeasureParticle(binaryImage, particleIndex, 0, 

+			IMAQ_MT_BOUNDING_RECT_BOTTOM, &position);

+	if (position > (rect.top + rect.height) ) return false; // outside bottom of rectangle ?	

+

+	DPRINTF(LOG_INFO, "particle %i is in (%i %i) height %i width %i\n", 

+			particleIndex, rect.left, rect.top, rect.height, rect.width);

+	return true; 

+}

+

+/**

+* @brief Find the largest particle that meets a criteria 

+* @param binaryImage Image to inspect

+* @param largestParticleIndex Index of the largest particle 

+* @param rect area to search

+* @return 0 = error

+*/

+int GetLargestParticle(Image* binaryImage, int* largestParticleIndex)

+{ return GetLargestParticle(binaryImage, largestParticleIndex, IMAQ_NO_RECT); }

+

+int GetLargestParticle(Image* binaryImage, int* largestParticleIndex, Rect rect)

+{

+	*largestParticleIndex = 0; // points to caller-provided variable

+	

+	/* determine number of particles in thresholded image */	

+	int numParticles;

+	int success = frcCountParticles(binaryImage, &numParticles);

+	if ( !success )	{  return success; 	}			

+	

+	/* if no particles found we can quit here */

+	if (numParticles == 0)  {  return 0; 	}  // unsuccessful if zero particles found

+	

+	// find the largest particle

+	double largestParticleArea = 0;

+	double particleArea;

+	for (int i = 0; i < numParticles; ++i) {		

+		success = imaqMeasureParticle(binaryImage, i, 0, IMAQ_MT_AREA, &particleArea);

+		if ( !success )	{ return success; }		

+		if (particleArea > largestParticleArea) 	{

+			// see if is in the right area

+			if ( InArea(binaryImage, i, rect) ) {

+				largestParticleArea = particleArea;

+				*largestParticleIndex = i;  // return index to caller

+			}

+		}

+	}

+	

+	return success;

+}

+

+/**

+* @brief Search for a color. Supports IMAQ_IMAGE_HSL. 

+* @param color Definition for the hue range 

+* @param trackReport Values for tracking: center of particle, particle size, color

+* @return 0 = error

+*/

+int FindColor(FrcHue color, ParticleAnalysisReport* trackReport)

+{

+	int success = 0;		// return: 0 = error

+	

+	/* track color */

+	// use ACTIVE_LIGHT or WHITE_LIGHT for brightly lit objects

+	TrackingThreshold td = GetTrackingData(color, PASSIVE_LIGHT);

+

+	success = FindColor(IMAQ_HSL, &td.hue, &td.saturation, &td.luminance, trackReport); 

+	if ( !success )	{ 

+		DPRINTF (LOG_INFO, "did not find color - errorCode= %i",GetLastVisionError());	

+		return success;

+	}

+

+	//PrintReport(par);

+	

+	/* set an image quality restriction */

+	if (trackReport->particleToImagePercent < PARTICLE_TO_IMAGE_PERCENT) {

+		imaqSetError(ERR_PARTICLE_TOO_SMALL, __FUNCTION__);

+		success = 0;

+	}	

+	return success;

+}

+

+/**

+* @brief Search for a color. Supports IMAQ_IMAGE_HSL. 

+* @param hueRange The range for the first plane

+* @param trackReport Values for tracking: center of particle, particle size, color

+* @return 0 = error

+*/

+int FindColor(const Range* hueRange, ParticleAnalysisReport *trackReport)

+{ return FindColor(hueRange, DEFAULT_SATURATION_THRESHOLD, trackReport); }

+

+/**

+* @brief Search for a color. Supports IMAQ_IMAGE_HSL. 

+* @param hueRange The range for the first plane

+* @param minSaturation The lower range saturation

+* @param trackReport Values for tracking: center of particle, particle size, color

+* @return 0 = error

+*/

+int FindColor(const Range* hueRange, int minSaturation, ParticleAnalysisReport *trackReport)

+{

+	Range satRange;

+	satRange.minValue = minSaturation;

+	satRange.maxValue = 255;

+	Range lumRange;

+	lumRange.minValue = 0;

+	lumRange.maxValue = 255;

+	ColorMode cmode = IMAQ_HSL;

+	return FindColor(cmode, hueRange, &satRange, &lumRange, trackReport);

+}

+

+/**

+* @brief Search for a color. Supports IMAQ_IMAGE_HSL and IMAQ_IMAGE_RGB. 

+* @param mode Color mode, either IMAQ_HSL or IMAQ_RGB

+* @param plane1Range The range for the first plane (hue or red)

+* @param plane2Range The range for the second plane (saturation or green)

+* @param plane3Range The range for the third plane (luminance or blue)

+* @param trackReport Values for tracking: center of particle, particle size, etc

+* @return 0 = error

+*/

+int FindColor(ColorMode mode, const Range* plane1Range, const Range* plane2Range, 

+		const Range* plane3Range, ParticleAnalysisReport *trackReport)

+{

+	return FindColor(mode, plane1Range, plane2Range, plane3Range, trackReport, NULL);

+}

+

+/**

+* @brief Search for a color. Supports IMAQ_IMAGE_HSL and IMAQ_IMAGE_RGB. 

+* @param mode Color mode, either IMAQ_HSL or IMAQ_RGB

+* @param plane1Range The range for the first plane (hue or red)

+* @param plane2Range The range for the second plane (saturation or green)

+* @param plane3Range The range for the third plane (luminance or blue)

+* @param trackReport Values for tracking: center of particle, particle size, etc

+* @param colorReport Color charactaristics of the particle

+* @return 0 = error

+*/

+int FindColor(ColorMode mode, const Range* plane1Range, const Range* plane2Range, 

+		const Range* plane3Range, ParticleAnalysisReport *trackReport, 

+		ColorReport *colorReport)

+{

+	return FindColor(mode, plane1Range, plane2Range, plane3Range, trackReport, 

+			NULL, IMAQ_NO_RECT);

+}

+

+/**

+* @brief Search for a color. Supports IMAQ_IMAGE_HSL and IMAQ_IMAGE_RGB. 

+* @param mode Color mode, either IMAQ_HSL or IMAQ_RGB

+* @param plane1Range The range for the first plane (hue or red)

+* @param plane2Range The range for the second plane (saturation or green)

+* @param plane3Range The range for the third plane (luminance or blue)

+* @param trackReport Values for tracking: center of particle, particle size, etc

+* @param colorReport Color charactaristics of the particle

+* @param rect Rectangle to confine search to

+* @return 0 = error

+*/

+int FindColor(ColorMode mode, const Range* plane1Range, const Range* plane2Range, 

+		const Range* plane3Range, ParticleAnalysisReport *trackReport, 

+		ColorReport *colorReport, Rect rect)

+{

+	int errorCode = 0;

+	int success = 0;

+	

+	/* create an image object */

+	Image* cameraImage = frcCreateImage(IMAQ_IMAGE_HSL);

+	if (!cameraImage)  { return success; }

+	

+	/* get image from camera - if the camera has not finished initializing,

+	 * this will fail 

+	 */

+	double imageTime;

+	success = GetImage(cameraImage, &imageTime);

+	if (!success){

+		DPRINTF(LOG_INFO, "No camera Image available Error = %i %s", 

+				errorCode, GetVisionErrorText(errorCode));

+		frcDispose(cameraImage); 

+		imaqSetError(errorCode, __FUNCTION__);	//reset error code for the caller	

+		return success;		

+	}	

+	

+	/* save a copy of the image to another image for color thresholding later */

+	Image* histImage = frcCreateImage(IMAQ_IMAGE_HSL);

+	if (!histImage)  { frcDispose(cameraImage); return success; }

+	success = frcCopyImage(histImage,cameraImage);

+	if ( !success )	{ 

+		errorCode = GetLastVisionError(); 

+		frcDispose(__FUNCTION__,cameraImage,histImage,NULL); 

+		return success; 

+	}	

+	

+	/* Color threshold the image */

+	success = frcColorThreshold(cameraImage, cameraImage, mode, plane1Range, plane2Range, plane3Range);

+	if ( !success )	{ 

+		errorCode = GetLastVisionError(); 

+		DPRINTF (LOG_DEBUG, "Error = %i  %s ", errorCode, GetVisionErrorText(errorCode));

+		frcDispose(__FUNCTION__,cameraImage,histImage,NULL); 

+		return success; 

+	}	

+

+	int largestParticleIndex = 0;

+	success = GetLargestParticle(cameraImage, &largestParticleIndex, rect );

+	if ( !success )	{

+		errorCode = GetLastVisionError(); 

+		DPRINTF (LOG_DEBUG, "Error after GetLargestParticle = %i  %s ", errorCode, GetVisionErrorText(errorCode));

+		frcDispose(__FUNCTION__,cameraImage,histImage,NULL); 

+		imaqSetError(ERR_COLOR_NOT_FOUND, __FUNCTION__);

+		return success; 

+	}

+	DPRINTF(LOG_INFO, "largestParticleIndex = %i\n", largestParticleIndex);

+

+	/* Particles were found  */

+		/* 

+		 * Fill in report information for largest particle found

+		 */

+		success = frcParticleAnalysis(cameraImage, largestParticleIndex, trackReport);

+		trackReport->imageTimestamp = imageTime;

+		

+		/* clean up */

+		if (!success) {frcDispose(__FUNCTION__,cameraImage,histImage,NULL); return success;}

+		

+		/* particle color statistics */

+		/* only if a color report requested */

+		if (colorReport != NULL)

+		{

+			/* first filter out the other particles */

+			ParticleFilterCriteria2 criteria;

+			ParticleFilterOptions* options = NULL;

+			Rect rect;

+			int numParticles;

+			success = frcParticleFilter(cameraImage, cameraImage, &criteria, 1, options, 

+					rect, &numParticles);

+			if ( !success )	{ 

+				DPRINTF(LOG_INFO, "frcParticleFilter errorCode %i", GetLastVisionError()); 

+			}	

+					

+			/* histogram the original image using the thresholded image as a mask */

+			int numClasses = 10; //how many classes?

+			ColorHistogramReport* chrep = imaqColorHistogram2(histImage, numClasses, IMAQ_HSL, 

+						NULL, cameraImage);

+			if (chrep == NULL) { 

+				DPRINTF(LOG_INFO, "NULL Color Histogram");

+				errorCode = GetLastVisionError(); 

+			} else {

+				colorReport->particleHueMax = chrep->plane1.max;

+				colorReport->particleHueMin = chrep->plane1.min;

+				colorReport->particleHueMean = chrep->plane1.mean;

+				colorReport->particleSatMax = chrep->plane2.max;

+				colorReport->particleSatMin  = chrep->plane2.min;

+				colorReport->particleSatMean = chrep->plane2.mean;

+				colorReport->particleLumMax = chrep->plane3.max;

+				colorReport->particleLumMin = chrep->plane3.min;

+				colorReport->particleLumMean = chrep->plane3.mean;

+				colorReport->numberParticlesFound = numParticles;

+				frcDispose(chrep); 

+			}

+		}

+

+	/* clean up */

+	frcDispose(__FUNCTION__,cameraImage,histImage,NULL); 

+	

+	return success;	

+}

+

+

+/**

+ *   Data functions for tracking

+ */

+

+

+/**

+ * @brief Get default HSL tracking parameters

+ * Note these parameters are not fully characterized at this point

+ * Get these default values and modify them as needed for your environment

+ * @param hue tasked color

+ * @param light saturation/luminance

+ */

+TrackingThreshold GetTrackingData(FrcHue hue, FrcLight light)

+{

+	TrackingThreshold trackingData;	

+	

+	//set saturation & luminance	

+	switch (light) {

+		default:

+		case FLUORESCENT:

+			trackingData.saturation.minValue = 100;

+			trackingData.saturation.maxValue = 255;

+			trackingData.luminance.minValue = 40;

+			trackingData.luminance.maxValue = 255;

+			if (hue == GREEN) trackingData.luminance.minValue = 100;

+			if (hue == PINK) trackingData.saturation.minValue = 80;

+			if (hue == PINK) trackingData.luminance.minValue = 60;

+			if (hue == PINK) trackingData.luminance.maxValue = 155;

+			break;

+		case PASSIVE_LIGHT:

+			trackingData.saturation.minValue = 50;

+			trackingData.saturation.maxValue = 255;

+			trackingData.luminance.minValue = 20;

+			trackingData.luminance.maxValue = 255;

+			break;

+		case BRIGHT_LIGHT:

+			trackingData.saturation.minValue = 0;

+			trackingData.saturation.maxValue = 100;

+			trackingData.luminance.minValue = 100;

+			trackingData.luminance.maxValue = 255;

+			break;

+		case ACTIVE_LIGHT:

+			trackingData.saturation.minValue = 0;

+			trackingData.saturation.maxValue = 50;

+			trackingData.luminance.minValue = 150;

+			trackingData.luminance.maxValue = 255;

+			break;

+		case WHITE_LIGHT:

+			trackingData.saturation.minValue = 0;

+			trackingData.saturation.maxValue = 20;

+			trackingData.luminance.minValue = 200;

+			trackingData.luminance.maxValue = 255;

+			break;

+	}

+	

+	//set hue

+	switch (hue){

+	default:

+	case WHITE:

+		strcpy (trackingData.name, "WHITE");

+		trackingData.hue.minValue = 0;

+		trackingData.hue.maxValue = 255;

+		break;

+	case ORANGE:

+		strcpy (trackingData.name, "ORANGE");

+		trackingData.hue.minValue = 5;

+		trackingData.hue.maxValue = 25;

+		break;

+	case YELLOW:

+		strcpy (trackingData.name, "YELLOW");

+		trackingData.hue.minValue = 30;

+		trackingData.hue.maxValue = 50;

+		break;

+	case GREEN:

+		strcpy (trackingData.name, "GREEN");

+		if (light == FLUORESCENT) {

+			trackingData.hue.minValue = 60;

+			trackingData.hue.maxValue = 110;

+		} else {

+			trackingData.hue.minValue = 90;

+			trackingData.hue.maxValue = 125;			

+		}

+		break;

+	case BLUE:

+		strcpy (trackingData.name, "BLUE");

+		trackingData.hue.minValue = 140;

+		trackingData.hue.maxValue = 170;

+		break;

+	case PURPLE:

+		strcpy (trackingData.name, "PURPLE");

+		trackingData.hue.minValue = 180;

+		trackingData.hue.maxValue = 200;

+		break;

+	case PINK:

+		strcpy (trackingData.name, "PINK");

+		trackingData.hue.minValue = 210;

+		trackingData.hue.maxValue = 250;

+		break;

+	case RED:

+		strcpy (trackingData.name, "RED");

+		trackingData.hue.minValue = 240;

+		trackingData.hue.maxValue = 255;

+		break;

+	}

+  return(trackingData);

+}

+

+

+/**

+ * Print particle analysis report

+ * @param myReport Report to print

+ */

+void PrintReport(ParticleAnalysisReport* myReport)

+{

+	dprintf(LOG_INFO, "particle analysis:\n    %s%i  %s%i\n    %s%lf\n    %s%i  %s%i\n    %s%g  %s%g\n    %s%g\n    %s%i  %s%i\n    %s%i  %s%i\n",

+			"imageHeight = ", myReport->imageHeight, 

+			"imageWidth = ", myReport->imageWidth, 

+			"imageTimestamp = ", myReport->imageTimestamp, 

+			"center_mass_x = ", myReport->center_mass_x, 

+			"center_mass_y = ", myReport->center_mass_y, 

+			"center_mass_x_normalized = ", myReport->center_mass_x_normalized, 

+			"center_mass_y_normalized = ", myReport->center_mass_y_normalized, 

+			"particleArea = ", myReport->particleArea, 

+			"boundingRectangleTop = ", myReport->boundingRect.top, 

+			"boundingRectangleLeft = ", myReport->boundingRect.left,

+			"boundingRectangleHeight = ", myReport->boundingRect.height, 

+			"boundingRectangleWidth = ", myReport->boundingRect.width);

+

+	dprintf(LOG_INFO, "quality statistics:  \n    %s%g %s%g \n",

+			"particleToImagePercent = ", myReport->particleToImagePercent, 

+			"particleQuality = ", myReport->particleQuality);

+}

+

+/**

+ * Print color report

+ * @param myReport Report to print

+ */

+void PrintReport(ColorReport* myReport)

+{

+	dprintf(LOG_INFO, "particle ranges for %i particles:     ",

+			"numberParticlesFound = ", myReport->numberParticlesFound);

+	;

+	dprintf(LOG_INFO, "\n    %s%f  %s%f  %s%f\n    %s%f %s%f  %s%f\n    %s%f  %s%f  %s%f\n -------",

+			"particleHueMax = ", myReport->particleHueMax, 

+			"particleHueMin = ", myReport->particleHueMin, 

+			"particleHueMean = ", myReport->particleHueMean,

+			"particleSatMax = ", myReport->particleSatMax, 

+			"particleSatMin = ", myReport->particleSatMin, 

+			"particleSatMean = ", myReport->particleSatMean,

+			"particleLumMax = ", myReport->particleLumMax, 

+			"particleLumMin = ", myReport->particleLumMin, 

+			"particleLumMean = ", myReport->particleLumMean);

+

+}

+

+/**

+ * Print color report

+ * @param myReport Report to print

+ */

+void PrintReport(TrackingThreshold* myReport)

+{

+	dprintf(LOG_INFO, "name of color: %s", myReport->name);

+

+	dprintf(LOG_INFO, "\n    %s%i  %s%i\n    %s%i %s%i\n    %s%i  %s%i\n -------",

+			"hueMin = ", myReport->hue.minValue, 

+			"hueMax = ", myReport->hue.maxValue, 

+			"satMin = ", myReport->saturation.minValue, 

+			"satMax = ", myReport->saturation.maxValue, 

+			"lumMin = ", myReport->luminance.minValue, 

+			"lumMax = ", myReport->luminance.maxValue );

+

+}

+

+

+

diff --git a/azaleasource/WPILibCProgramming/trunk/WPILib/Vision2009/TrackAPI.h b/azaleasource/WPILibCProgramming/trunk/WPILib/Vision2009/TrackAPI.h
new file mode 100644
index 0000000..6431217
--- /dev/null
+++ b/azaleasource/WPILibCProgramming/trunk/WPILib/Vision2009/TrackAPI.h
@@ -0,0 +1,74 @@
+/********************************************************************************

+*  Project   		: FIRST Motor Controller

+*  File Name  		: TrackAPI.h          

+*  Contributors   	: ELF

+*  Creation Date 	: August 12, 2008

+*  Revision History	: Source code & revision history maintained at sourceforge.WPI.edu    

+*  File Description	: Globally defined values for the FIRST Vision API

+*/

+/*----------------------------------------------------------------------------*/

+/*        Copyright (c) FIRST 2008.  All Rights Reserved.                     */

+/*  Open Source Software - may be modified and shared by FRC teams. The code  */

+/*  must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */

+/*----------------------------------------------------------------------------*/

+

+#ifndef __TRACKAPI_H__

+#define __TRACKAPI_H__

+

+#include "VisionAPI.h"

+#include "BaeUtilities.h"

+

+/*  Constants */

+/** image quality requirement: particle must be this % of pixels 

+ * For instance, a 320x240 image has 76800 pixels. With this 

+ * tolerance at .01, the image must be 768 pixels.

+ * Use a percentage instead of a fixed # of pixels so different

+ * image sizes will work the same way */

+#define PARTICLE_TO_IMAGE_PERCENT 0.01

+

+/*  Structures */

+typedef struct TrackingThreshold_struct {

+	char name[64];

+	Range hue;

+	Range saturation;

+	Range luminance;

+} TrackingThreshold;

+		

+/*  Enumerated Types */

+

+/** Predefined hues */

+typedef enum FrcHue_enum { 

+	// Basic colors

+	RED, GREEN, BLUE, YELLOW, ORANGE, PURPLE, WHITE, PINK

+}FrcHue;

+

+/** Predefined saturation / luminance settings */

+typedef enum FrcLight_enum { 

+	PASSIVE_LIGHT, BRIGHT_LIGHT, ACTIVE_LIGHT, WHITE_LIGHT, FLUORESCENT

+}FrcLight;

+	

+/* color tracking support functions */

+TrackingThreshold GetTrackingData(FrcHue hue, FrcLight light);

+

+void PrintReport(ParticleAnalysisReport* myReport);

+void PrintReport(ColorReport* myReport);

+void PrintReport(TrackingThreshold* myReport);

+

+/*  Tracking functions */

+

+/* find a color in current camera image */

+bool InArea(Image* binaryImage, int particleIndex, Rect rect);

+int GetLargestParticle(Image* binaryImage, int* particleNum);

+int GetLargestParticle(Image* binaryImage, int* particleNum, Rect rect);

+int FindColor(FrcHue color, ParticleAnalysisReport* trackReport);

+int FindColor(const Range* hueRange, ParticleAnalysisReport *trackReport);

+int FindColor(const Range* hueRange, int minSaturation, ParticleAnalysisReport *trackReport);

+int FindColor(ColorMode mode, const Range* plane1Range, const Range* plane2Range, 

+		const Range* plane3Range, ParticleAnalysisReport *trackReport);

+int FindColor(ColorMode mode, const Range* plane1Range, const Range* plane2Range, 

+		const Range* plane3Range, ParticleAnalysisReport *trackReport, ColorReport *colorReport);

+int FindColor(ColorMode mode, const Range* plane1Range, const Range* plane2Range, 

+		const Range* plane3Range, ParticleAnalysisReport *trackReport, 

+		ColorReport *colorReport, Rect rect);

+#endif

+

diff --git a/azaleasource/WPILibCProgramming/trunk/WPILib/Vision2009/VisionAPI.cpp b/azaleasource/WPILibCProgramming/trunk/WPILib/Vision2009/VisionAPI.cpp
new file mode 100644
index 0000000..2e89cd0
--- /dev/null
+++ b/azaleasource/WPILibCProgramming/trunk/WPILib/Vision2009/VisionAPI.cpp
@@ -0,0 +1,676 @@
+/********************************************************************************

+*  Project   		: FIRST Motor Controller

+*  File Name  		: VisionAPI.cpp        

+*  Contributors   	: ELF, EMF

+*  Creation Date 	: June 26, 2008

+*  Revision History	: Source code & revision history maintained at sourceforge.WPI.edu   

+*  File Description	: C Routines for FIRST Vision API. Open source API developed 

+*    by BAE Systems to interface with the National Instruments vision C library

+*    in the nivision.out module. The published interface to nivision.out is in

+*    the header file nivision.h and documented in the NIVisionCVI.chm help file.

+*/ 

+/*----------------------------------------------------------------------------*/

+/*        Copyright (c) FIRST 2008.  All Rights Reserved.                     */

+/*  Open Source Software - may be modified and shared by FRC teams. The code  */

+/*  must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */

+/*----------------------------------------------------------------------------*/

+

+#include "stdioLib.h" 

+#include "vxWorks.h" 

+

+#include "BaeUtilities.h"

+#include "FrcError.h"

+#include "VisionAPI.h" 

+

+int VisionAPI_debugFlag = 1;

+#define DPRINTF if(VisionAPI_debugFlag)dprintf

+

+/*   Image Management functions    */

+

+/**

+* @brief Create an image object

+* Supports IMAQ_IMAGE_U8, IMAQ_IMAGE_I16, IMAQ_IMAGE_SGL, IMAQ_IMAGE_COMPLEX, IMAQ_IMAGE_RGB, IMAQ_IMAGE_HSL, IMAQ_IMAGE_RGB_U64          

+* The border size is defaulted to 3 so that convolutional algorithms work at the edges. 

+* When you are finished with the created image, dispose of it by calling frcDispose(). 

+* To get extended error information, call GetLastError().   

+*           

+* @param type Type of image to create

+* @return Image* On success, this function returns the created image. On failure, it returns NULL.

+*/

+Image* frcCreateImage(ImageType type) { return imaqCreateImage(type, DEFAULT_BORDER_SIZE); }

+

+/**

+* @brief Dispose of one object. Supports any object created on the heap.

+* 

+* @param object object to dispose of

+* @return On success: 1. On failure: 0. To get extended error information, call GetLastError().

+*/

+int frcDispose(void* object)  { return imaqDispose(object);	}

+/**

+* @brief Dispose of a list of objects. Supports any object created on the heap.

+* 

+* @param functionName The name of the function

+* @param ... A list of pointers to structures that need to be disposed of. 

+* The last pointer in the list should always be set to NULL.

+* 

+* @return On success: 1. On failure: 0. To get extended error information, call GetLastError().

+*/

+int frcDispose( const char* functionName, ... ) /* Variable argument list */

+{

+    va_list disposalPtrList;   /* Input argument list */

+    void* disposalPtr;         /* For iteration */

+    int success, returnValue = 1;

+    

+    va_start( disposalPtrList, functionName );  /* start of variable list */

+    disposalPtr = va_arg( disposalPtrList, void* );

+    while( disposalPtr != NULL )     {

+    	success = imaqDispose(disposalPtr);

+        if (!success) {returnValue = 0;}

+        disposalPtr = va_arg( disposalPtrList, void* );

+    }

+    return returnValue;

+}

+

+/**

+* @brief Copy an image object. 

+* Supports IMAQ_IMAGE_U8, IMAQ_IMAGE_I16, IMAQ_IMAGE_SGL, IMAQ_IMAGE_RGB, IMAQ_IMAGE_HSL.          

+* 

+* @param dest Copy of image. On failure, dest is NULL. Must have already been created using frcCreateImage().

+* When you are finished with the created image, dispose of it by calling frcDispose().

+* @param source Image to copy      

+* 

+* @return On success: 1. On failure: 0. To get extended error information, call GetLastError().

+*/

+int frcCopyImage(Image* dest, const Image* source) { return imaqDuplicate(dest, source);  }

+

+/**

+* @brief Crop image without changing the scale. 

+* Supports IMAQ_IMAGE_U8, IMAQ_IMAGE_I16, IMAQ_IMAGE_SGL, IMAQ_IMAGE_RGB, IMAQ_IMAGE_HSL.

+* 

+* @param dest Modified image

+* @param source Image to crop

+* @param rect region to process, or IMAQ_NO_RECT

+* 

+* @return On success: 1. On failure: 0. To get extended error information, call GetLastError().

+*/

+int frcCrop(Image* dest, const Image* source, Rect rect)

+{	

+	return imaqScale(dest, source, 1, 1, IMAQ_SCALE_LARGER, rect);

+}

+

+

+/**

+* @brief Scales the entire image larger or smaller. 

+* Supports IMAQ_IMAGE_U8, IMAQ_IMAGE_I16, IMAQ_IMAGE_SGL, IMAQ_IMAGE_RGB, IMAQ_IMAGE_HSL.

+*     

+* @param dest Modified image

+* @param source Image to scale

+* @param xScale the horizontal reduction ratio

+* @param yScale the vertical reduction ratio 

+* @param scaleMode IMAQ_SCALE_LARGER or IMAQ_SCALE_SMALLER  

+* 

+* @return On success: 1. On failure: 0. To get extended error information, call GetLastError().

+*/

+int frcScale(Image* dest, const Image* source, int xScale, int yScale, ScalingMode scaleMode)

+{	

+	Rect rect = IMAQ_NO_RECT;

+	return imaqScale(dest, source, xScale, yScale, scaleMode, rect);	

+}

+  

+/**

+ * @brief Creates image object from the information in a file. The file can be in one of the following formats: 

+ * PNG, JPEG, JPEG2000, TIFF, AIPD, or BMP. 

+ * Supports IMAQ_IMAGE_U8, IMAQ_IMAGE_I16, IMAQ_IMAGE_SGL, IMAQ_IMAGE_COMPLEX, IMAQ_IMAGE_RGB, IMAQ_IMAGE_HSL, IMAQ_IMAGE_RGB_U64.

+ * 

+ * @param image Image read in

+ * @param fileName File to read. Cannot be NULL

+ * 

+ * @return On success: 1. On failure: 0. To get extended error information, call GetLastError().

+ */

+ int frcReadImage(Image* image, const char* fileName)

+ {

+	 return imaqReadFile(image, fileName, NULL, NULL);

+ }

+

+

+ /**

+ * @brief Write image to a file. 

+ * Supports IMAQ_IMAGE_U8, IMAQ_IMAGE_I16, IMAQ_IMAGE_SGL, IMAQ_IMAGE_COMPLEX, IMAQ_IMAGE_RGB, IMAQ_IMAGE_HSL, IMAQ_IMAGE_RGB_U64.

+ * 

+ * The file type is determined by the extension, as follows:

+ *

+ *		Extension 					File Type 

+ *		aipd or .apd 				AIPD 

+ *		.bmp 						BMP 

+ *		.jpg or .jpeg 				JPEG 

+ *		.jp2 						JPEG2000 

+ *		.png 						PNG 

+ *		.tif or .tiff 				TIFF 

+ * 

+ * 

+ *The following are the supported image types for each file type:

+ *

+ *		File Types 					Image Types 

+ *		AIPD 						all image types 

+ *		BMP, JPEG 					8-bit, RGB 

+ *		PNG, TIFF, JPEG2000 		8-bit, 16-bit, RGB, RGBU64 		

+ * 			    

+ * @param image Image to write

+ * @param fileName File to read. Cannot be NULL. The extension determines the file format that is written.

+ * 

+ * @return On success: 1. On failure: 0. To get extended error information, call GetLastError().

+ */

+int frcWriteImage(const Image* image, const char* fileName)

+{	

+	RGBValue* colorTable = NULL;

+	return imaqWriteFile(image, fileName, colorTable);

+}

+

+

+/*  Measure Intensity functions */

+

+/**

+* @brief Measures the pixel intensities in a rectangle of an image. 

+* Outputs intensity based statistics about an image such as Max, Min, Mean and Std Dev of pixel value. 

+* Supports IMAQ_IMAGE_U8, IMAQ_IMAGE_I16, IMAQ_IMAGE_SGL.

+*

+*  Parameter Discussion	: 

+*		Relevant parameters of the HistogramReport include:

+* 			min, max, mean and stdDev      

+*		min/max —Setting both min and max to 0 causes the function to set min to 0 

+* 			and the max to 255 for 8-bit images and to the actual minimum value and

+* 			maximum value of the image for all other image types.

+*		max—Setting both min and max to 0 causes the function to set max to 255 

+* 			for 8-bit images and to the actual maximum value of the image for 

+* 			all other image types.

+*

+* @param image Image whose histogram the function calculates.

+* @param numClasses The number of classes into which the function separates the pixels. 

+* Determines the number of elements in the histogram array returned

+* @param min The minimum pixel value to consider for the histogram. 

+* The function does not count pixels with values less than min.

+* @param max The maximum pixel value to consider for the histogram. 

+* The function does not count pixels with values greater than max.

+* @param rect Region of interest in the image. If not included, the entire image is used. 

+* @return On success, this function returns a report describing the pixel value classification.    

+* When you are finished with the report, dispose of it by calling frcDispose(). 

+* On failure, this function returns NULL. To get extended error information, call GetLastError().            

+* 

+*/

+HistogramReport* frcHistogram(const Image* image, int numClasses, float min, float max)

+{

+	Rect rect = IMAQ_NO_RECT;

+	return frcHistogram(image, numClasses, min, max, rect);		

+}

+HistogramReport* frcHistogram(const Image* image, int numClasses, float min, float max, Rect rect)

+{

+	int success; 

+	int fillValue = 1;

+	

+	/* create the region of interest */

+	ROI* pRoi = imaqCreateROI();

+	success = imaqAddRectContour(pRoi, rect); 

+	if ( !success )	{ GetLastVisionError(); return NULL; }	

+

+	/* make a mask from the ROI */

+	Image* pMask = frcCreateImage(IMAQ_IMAGE_U8);

+	success = imaqROIToMask(pMask, pRoi, fillValue, NULL, NULL);

+	if ( !success )	{ 

+		GetLastVisionError(); 

+		frcDispose(__FUNCTION__, pRoi, NULL); 

+		return NULL; 

+	}	

+	

+	/* get a histogram report */

+	HistogramReport* pHr = NULL;

+	pHr = imaqHistogram(image, numClasses, min, max, pMask); 

+	

+	/* clean up */

+	frcDispose(__FUNCTION__, pRoi, pMask, NULL); 

+	

+	return pHr;

+}

+

+/**

+* @brief Calculates the histogram, or pixel distribution, of a color image. 

+* Supports IMAQ_IMAGE_RGB, IMAQ_IMAGE_HSL.

+*            

+* @param image Image whose histogram the function calculates.

+* @param numClasses The number of classes into which the function separates the pixels. 

+* Determines the number of elements in the histogram array returned

+* @param mode The color space in which to perform the histogram. Possible values include IMAQ_RGB and IMAQ_HSL. 

+* @param mask An optional mask image. This image must be an IMAQ_IMAGE_U8 image. 

+* The function calculates the histogram using only those pixels in the image whose 

+* corresponding pixels in the mask are non-zero. Set this parameter to NULL to calculate 

+* the histogram of the entire image, or use the simplified call.

+* 

+* @return On success, this function returns a report describing the classification  

+* of each plane in a HistogramReport. 

+* When you are finished with the report, dispose of it by calling frcDispose(). 

+* On failure, this function returns NULL.  

+* To get extended error information, call imaqGetLastError(). 

+*/

+ColorHistogramReport* frcColorHistogram(const Image* image, int numClasses, ColorMode mode)

+{	

+	return frcColorHistogram(image, numClasses, mode, NULL);

+}

+

+ColorHistogramReport* frcColorHistogram(const Image* image, int numClasses, ColorMode mode, Image* mask)

+{

+	return imaqColorHistogram2((Image*)image, numClasses, mode, NULL, mask);

+}

+

+

+/**

+* @brief Measures the pixel intensities in a rectangle of an image. 

+* Outputs intensity based statistics about an image such as Max, Min, Mean and Std Dev of pixel value. 

+* Supports IMAQ_IMAGE_U8 (grayscale) IMAQ_IMAGE_RGB (color) IMAQ_IMAGE_HSL (color-HSL).

+* 

+* @param image The image whose pixel value the function queries

+* @param pixel The coordinates of the pixel that the function queries

+* @param value On return, the value of the specified image pixel. This parameter cannot be NULL.

+* This data structure contains either grayscale, RGB, HSL, Complex or RGBU64Value depending on the type of image.

+* @return On success: 1. On failure: 0. To get extended error information, call GetLastError().

+*/

+int frcGetPixelValue(const Image* image, Point pixel, PixelValue* value)

+{	

+	return imaqGetPixel(image, pixel, value);

+}

+

+

+/*   Particle Analysis functions */

+

+/**

+* @brief Filters particles out of an image based on their measurements. 

+* Supports IMAQ_IMAGE_U8, IMAQ_IMAGE_I16, IMAQ_IMAGE_SGL.

+* 

+* @param dest The destination image. If dest is used, it must be the same size as the Source image. It will contain only the filtered particles.

+* @param source The image containing the particles to filter. 

+* @param criteria An array of criteria to apply to the particles in the source image. This array cannot be NULL.

+* See the NIVisionCVI.chm help file for definitions of criteria. 

+* @param criteriaCount The number of elements in the criteria array.

+* @param options Binary filter options, including rejectMatches, rejectBorder, and connectivity8.

+* @param rect Area of image to filter. If omitted, the default is entire image.

+* @param numParticles On return, the number of particles left in the image

+* @return On success: 1. On failure: 0. To get extended error information, call GetLastError().

+*/

+int frcParticleFilter(Image* dest, Image* source, const ParticleFilterCriteria2* criteria, 

+		int criteriaCount, const ParticleFilterOptions* options, int* numParticles)

+{

+	Rect rect = IMAQ_NO_RECT;

+	return frcParticleFilter(dest, source, criteria, criteriaCount, options, rect, numParticles);

+}

+

+int frcParticleFilter(Image* dest, Image* source, const ParticleFilterCriteria2* criteria, 

+		int criteriaCount, const ParticleFilterOptions* options, Rect rect, int* numParticles)

+{

+	ROI* roi = imaqCreateROI();

+	imaqAddRectContour(roi, rect);

+	return imaqParticleFilter3(dest, source, criteria, criteriaCount, options, roi, numParticles);

+}

+

+

+/**

+* @brief Performs morphological transformations on binary images. 

+* Supports IMAQ_IMAGE_U8. 

+*

+* @param dest The destination image. The border size of the destination image is not important.

+* @param source The image on which the function performs the morphological operations. The calculation 

+* modifies the border of the source image. The border must be at least half as large as the larger 

+* dimension  of the structuring element.  The connected source image for a morphological transformation 

+* must have been created with a border capable of supporting the size of the structuring element. 

+* A 3 by 3 structuring element requires a minimal border of 1, a 5 by 5 structuring element requires a minimal border of 2, and so on.

+* @param method The morphological transform to apply. 

+* @param structuringElement The structuring element used in the operation. Omit this parameter if you do not want a custom structuring element. 

+* @return On success: 1. On failure: 0. To get extended error information, call GetLastError(). 

+*/

+int frcMorphology(Image* dest, Image* source, MorphologyMethod method)

+{	

+	return imaqMorphology(dest, source, method, NULL);

+}

+

+int frcMorphology(Image* dest, Image* source, MorphologyMethod method, const StructuringElement* structuringElement)

+{	

+	return imaqMorphology(dest, source, method, structuringElement); 

+}

+

+/**

+* @brief Eliminates particles that touch the border of the image. 

+* Supports IMAQ_IMAGE_U8.

+*

+* @param dest The destination image.

+* @param source The source image. If the image has a border, the function sets all border pixel values to 0.

+* @param connectivity8 specifies the type of connectivity used by the algorithm for particle detection. 

+* The connectivity mode directly determines whether an adjacent pixel belongs to the same particle or a 

+* different particle. Set to TRUE to use connectivity-8 to determine whether particles are touching 

+* Set to FALSE to use connectivity-4 to determine whether particles are touching. 

+* The default setting for the simplified call is TRUE

+* @return On success: 1. On failure: 0. To get extended error information, call GetLastError().

+*/

+int frcRejectBorder(Image* dest, Image* source)

+{	return imaqRejectBorder(dest, source, TRUE); }

+

+int frcRejectBorder(Image* dest, Image* source, int connectivity8)

+{	

+	return imaqRejectBorder(dest, source, connectivity8);

+}

+

+

+/**

+* @brief Counts the number of particles in a binary image. 

+* Supports IMAQ_IMAGE_U8, IMAQ_IMAGE_I16, IMAQ_IMAGE_SGL.

+* @param image binary (thresholded) image 	

+* @param numParticles On return, the number of particles.

+* @return On success: 1. On failure: 0. To get extended error information, call GetLastError().    

+*/

+int frcCountParticles(Image* image, int* numParticles)				

+{	

+	return imaqCountParticles(image, 1, numParticles);

+}

+

+

+/**

+* @brief Conduct measurements for a single particle in an images. 

+* Supports IMAQ_IMAGE_U8, IMAQ_IMAGE_I16, IMAQ_IMAGE_SGL.

+* 

+* @param image image with the particle to analyze. This function modifies the source image. 

+* If you need the original image, create a copy of the image using frcCopy() before using this function.

+* @param particleNumber The number of the particle to get information on

+* @param par on return, a particle analysis report containing information about the particle. This structure must be created by the caller.

+* @return On success: 1. On failure: 0. To get extended error information, call GetLastError().

+*/

+int frcParticleAnalysis(Image* image, int particleNumber, ParticleAnalysisReport* par)				

+{

+	int success = 0;

+

+	/* image information */

+	int height, width;

+	if ( ! imaqGetImageSize(image, &width, &height) ) 	{ return success; }	

+	par->imageWidth = width;	

+	par->imageHeight = height;	

+	par->particleIndex = particleNumber;		

+

+	/* center of mass point of the largest particle	*/

+	double returnDouble;

+	success = imaqMeasureParticle(image, particleNumber, 0, IMAQ_MT_CENTER_OF_MASS_X, &returnDouble);

+	if ( !success )	{ return success; }

+	par->center_mass_x = (int)returnDouble;						// pixel	

+

+	success = imaqMeasureParticle(image, particleNumber, 0, IMAQ_MT_CENTER_OF_MASS_Y, &returnDouble);	

+	if ( !success )	{ return success; }

+	par->center_mass_y = (int)returnDouble;						// pixel		

+	

+	/* particle size statistics */ 

+	success = imaqMeasureParticle(image, particleNumber, 0, IMAQ_MT_AREA, &returnDouble);	

+	if ( !success )	{ return success; }

+	par->particleArea = returnDouble;	

+	

+	success = imaqMeasureParticle(image, particleNumber, 0, IMAQ_MT_BOUNDING_RECT_TOP, &returnDouble);	

+	if ( !success )	{ return success; }

+	par->boundingRect.top = (int)returnDouble;

+	

+	success = imaqMeasureParticle(image, particleNumber, 0, IMAQ_MT_BOUNDING_RECT_LEFT, &returnDouble);	

+	if ( !success )	{ return success; }

+	par->boundingRect.left = (int)returnDouble;

+	

+	success = imaqMeasureParticle(image, particleNumber, 0, IMAQ_MT_BOUNDING_RECT_HEIGHT, &returnDouble);	

+	if ( !success )	{ return success; }

+	par->boundingRect.height = (int)returnDouble;	

+

+	success = imaqMeasureParticle(image, particleNumber, 0, IMAQ_MT_BOUNDING_RECT_WIDTH, &returnDouble);	

+	if ( !success )	{ return success; }

+	par->boundingRect.width = (int)returnDouble;	

+	

+	/* particle quality statistics */ 

+	success = imaqMeasureParticle(image, particleNumber, 0, IMAQ_MT_AREA_BY_IMAGE_AREA, &returnDouble);	

+	if ( !success )	{ return success; }

+	par->particleToImagePercent = returnDouble;

+

+	success = imaqMeasureParticle(image, particleNumber, 0, IMAQ_MT_AREA_BY_PARTICLE_AND_HOLES_AREA, &returnDouble);	

+	if ( !success )	{ return success; }

+	par->particleQuality = returnDouble;

+		

+	/* normalized position (-1 to 1) */

+	par->center_mass_x_normalized = RangeToNormalized(par->center_mass_x, width);

+	par->center_mass_y_normalized = RangeToNormalized(par->center_mass_y, height);	

+	

+	return success;

+}

+

+

+/*   Image Enhancement functions */

+

+/**

+* @brief Improves contrast on a grayscale image. 

+* Supports IMAQ_IMAGE_U8, IMAQ_IMAGE_I16.

+* @param dest The destination image.

+* @param source The image to equalize 

+* @param min the smallest value used for processing. After processing, all pixel values that are less than or equal to the Minimum in the original image are set to 0 for an 8-bit image. In 16-bit and floating-point images, these pixel values are set to the smallest pixel value found in the original image. 

+* @param max the largest value used for processing. After processing, all pixel values that are greater than or equal to the Maximum in the original image are set to 255 for an 8-bit image. In 16-bit and floating-point images, these pixel values are set to the largest pixel value found in the original image. 

+* @param mask an 8-bit image that specifies the region of the small image that will be copied. Only those pixels in the Image Src (Small) image that correspond to an equivalent non-zero pixel in the mask image are copied. All other pixels keep their original values. The entire image is processed if Image Mask is NULL or this parameter is omitted.

+* @return On success: 1. On failure: 0. To get extended error information, call GetLastError().

+*

+*  option defaults:

+*       searchRect = IMAQ_NO_RECT

+* 		minMatchScore = DEFAULT_MINMAX_SCORE (800)  

+*/

+int frcEqualize(Image* dest, const Image* source, float min, float max)

+{	return frcEqualize(dest, source, min, max, NULL);  }

+

+int frcEqualize(Image* dest, const Image* source, float min, float max, const Image* mask)

+{

+	return imaqEqualize(dest, source, min, max, mask);

+}

+

+/**

+* @brief Improves contrast on a color image. 

+* Supports IMAQ_IMAGE_RGB, IMAQ_IMAGE_HSL

+* 

+* option defaults: colorEqualization = TRUE to equalize all three planes of the image         

+* @return On success: 1. On failure: 0. To get extended error information, call GetLastError().    

+* @param dest The destination image.

+* @param source The image to equalize 

+* @param colorEqualization Set this parameter to TRUE to equalize all three planes of the image (the default). Set this parameter to FALSE to equalize only the luminance plane.

+*/

+int frcColorEqualize(Image* dest, const Image* source)

+{

+	return imaqColorEqualize(dest, source, TRUE);

+}

+

+int frcColorEqualize(Image* dest, const Image* source, int colorEqualization)

+{

+	return imaqColorEqualize(dest, source, TRUE);

+}

+

+/*   Image Conversion functions */

+

+/**

+* @brief Automatically thresholds a grayscale image into a binary image for Particle Analysis based on a smart threshold. 

+* Supports IMAQ_IMAGE_RGB, IMAQ_IMAGE_I16

+* @param dest The destination image.

+* @param source The image to threshold 

+* @param windowWidth The width of the rectangular window around the pixel on which the function

+*  performs the local threshold. This number must be at least 3 and cannot be larger than the width of source

+* @param windowHeight The height of the rectangular window around the pixel on which the function 

+* performs the local threshold. This number must be at least 3 and cannot be larger than the height of source

+* @param method Specifies the local thresholding method the function uses. Value can be IMAQ_NIBLACK 

+* (which computes thresholds for each pixel based on its local statistics using the Niblack local thresholding

+* algorithm.), or IMAQ_BACKGROUND_CORRECTION (which does background correction first to eliminate non-uniform 

+* lighting effects, then performs thresholding using the Otsu thresholding algorithm)

+* @param deviationWeight Specifies the k constant used in the Niblack local thresholding algorithm, which 

+* determines the weight applied to the variance calculation. Valid k constants range from 0 to 1. Setting 

+* this value to 0 will increase the performance of the function because the function will not calculate the 

+* variance for any of the pixels. The function ignores this value if method is not set to IMAQ_NIBLACK

+* @param type Specifies the type of objects for which you want to look. Values can be IMAQ_BRIGHT_OBJECTS 

+* or IMAQ_DARK_OBJECTS.

+* @param replaceValue Specifies the replacement value the function uses for the pixels of the kept objects 

+* in the destination image.

+* @return On success: 1. On failure: 0. To get extended error information, call GetLastError().

+*/

+int frcSmartThreshold(Image* dest, const Image* source, 

+		unsigned int windowWidth, unsigned int windowHeight, LocalThresholdMethod method, 

+		double deviationWeight, ObjectType type)

+{

+	float replaceValue = 1.0;

+	return imaqLocalThreshold(dest, source, windowWidth, windowHeight, method, 

+			deviationWeight, type, replaceValue);

+}

+

+int frcSmartThreshold(Image* dest, const Image* source, 

+		unsigned int windowWidth, unsigned int windowHeight, LocalThresholdMethod method, 

+		double deviationWeight, ObjectType type, float replaceValue)

+{

+	return imaqLocalThreshold(dest, source, windowWidth, windowHeight, method, 

+			deviationWeight, type, replaceValue);

+}

+

+/**

+* @brief Converts a grayscale image to a binary image for Particle Analysis based on a fixed threshold. 

+* The function sets pixels values outside of the given range to 0. The function sets pixel values 

+* within the range to a given value or leaves the values unchanged. 

+* Use the simplified call to leave pixel values unchanged.

+* Supports IMAQ_IMAGE_RGB, IMAQ_IMAGE_I16.

+* 

+* @param dest The destination image.

+* @param source The image to threshold 

+* @param rangeMin The lower boundary of the range of pixel values to keep

+* @param rangeMax The upper boundary of the range of pixel values to keep.

+* 

+* @return int - error code: 0 = error. To get extended error information, call GetLastError().

+*/

+int frcSimpleThreshold(Image* dest, const Image* source, float rangeMin, float rangeMax)

+{

+	int newValue = 255;

+	return frcSimpleThreshold(dest, source, rangeMin, rangeMax, newValue);

+}

+

+/**

+* @brief Converts a grayscale image to a binary image for Particle Analysis based on a fixed threshold. 

+* The function sets pixels values outside of the given range to 0. The function sets 

+* pixel values within the range to the given value. 

+* Supports IMAQ_IMAGE_RGB, IMAQ_IMAGE_I16.

+* 

+* @param dest The destination image.

+* @param source The image to threshold 

+* @param rangeMin The lower boundary of the range of pixel values to keep

+* @param rangeMax The upper boundary of the range of pixel values to keep.

+* @param newValue The replacement value for pixels within the range. Use the simplified call to leave the pixel values unchanged 

+* 

+* @return int - error code: 0 = error. To get extended error information, call GetLastError().

+*/

+int frcSimpleThreshold(Image* dest, const Image* source, float rangeMin, float rangeMax, float newValue)

+{

+	int useNewValue = TRUE;

+	return imaqThreshold(dest, source, rangeMin, rangeMax, useNewValue, newValue);

+}

+

+/**

+* @brief Applies a threshold to the Red, Green, and Blue values of a RGB image or the Hue, 

+* Saturation, Luminance values for a HSL image. 

+* Supports IMAQ_IMAGE_RGB, IMAQ_IMAGE_HSL.

+* This simpler version filters based on a hue range in the HSL mode.

+* 

+* @param dest The destination image. This must be a IMAQ_IMAGE_U8 image.

+* @param source The image to threshold 

+* @param mode The color space to perform the threshold in. valid values are: IMAQ_RGB, IMAQ_HSL.

+* @param plane1Range The selection range for the first plane of the image. Set this parameter to NULL to use a selection range from 0 to 255.

+* @param plane2Range The selection range for the second plane of the image. Set this parameter to NULL to use a selection range from 0 to 255.

+* @param plane3Range The selection range for the third plane of the image. Set this parameter to NULL to use a selection range from 0 to 255.

+* 

+* @return On success: 1. On failure: 0. To get extended error information, call GetLastError().

+* */

+int frcColorThreshold(Image* dest, const Image* source, ColorMode mode, 

+		const Range* plane1Range, const Range* plane2Range, const Range* plane3Range)

+{

+	int replaceValue = 1;

+	return imaqColorThreshold(dest, source, replaceValue, mode, plane1Range, plane2Range, plane3Range);

+}

+

+/**

+* @brief Applies a threshold to the Red, Green, and Blue values of a RGB image or the Hue, 

+* Saturation, Luminance values for a HSL image. 

+* Supports IMAQ_IMAGE_RGB, IMAQ_IMAGE_HSL.

+* The simpler version filters based on a hue range in the HSL mode.

+* 

+* @param dest The destination image. This must be a IMAQ_IMAGE_U8 image.

+* @param source The image to threshold 

+* @param replaceValue Value to assign to selected pixels. Defaults to 1 if simplified call is used.

+* @param mode The color space to perform the threshold in. valid values are: IMAQ_RGB, IMAQ_HSL.

+* @param plane1Range The selection range for the first plane of the image. Set this parameter to NULL to use a selection range from 0 to 255.

+* @param plane2Range The selection range for the second plane of the image. Set this parameter to NULL to use a selection range from 0 to 255.

+* @param plane3Range The selection range for the third plane of the image. Set this parameter to NULL to use a selection range from 0 to 255.

+* 

+* @return On success: 1. On failure: 0. To get extended error information, call GetLastError().

+*/

+int frcColorThreshold(Image* dest, const Image* source, int replaceValue, ColorMode mode, 

+		const Range* plane1Range, const Range* plane2Range, const Range* plane3Range)

+{	return imaqColorThreshold(dest, source, replaceValue, mode, plane1Range, plane2Range, plane3Range);}

+

+

+/**

+* @brief A simpler version of ColorThreshold that thresholds hue range in the HSL mode. Supports IMAQ_IMAGE_RGB, IMAQ_IMAGE_HSL.

+* @param dest The destination image.

+* @param source The image to threshold 

+* @param hueRange The selection range for the hue (color). 

+* @param minSaturation The minimum saturation value (1-255).  If not used, DEFAULT_SATURATION_THRESHOLD is the default.

+* 

+* @return On success: 1. On failure: 0. To get extended error information, call GetLastError().

+*/

+int frcHueThreshold(Image* dest, const Image* source, const Range* hueRange)

+{ return frcHueThreshold(dest, source, hueRange, DEFAULT_SATURATION_THRESHOLD); }

+

+int frcHueThreshold(Image* dest, const Image* source, const Range* hueRange, int minSaturation)

+{

+	// assume HSL mode

+	ColorMode mode = IMAQ_HSL;  

+	// Set saturation 100 - 255

+	Range satRange;  satRange.minValue = minSaturation; satRange.maxValue = 255;

+	// Set luminance 100 - 255

+	Range lumRange;  lumRange.minValue = 100; lumRange.maxValue = 255;

+	// Replace pixels with 1 if pass threshold filter

+	int replaceValue = 1;

+	return imaqColorThreshold(dest, source, replaceValue, mode, hueRange, &satRange, &lumRange);

+}

+

+/**

+* @brief Extracts the Red, Green, Blue, or Hue, Saturation or Luminance information from a color image. 

+* Supports IMAQ_IMAGE_RGB, IMAQ_IMAGE_HSL, IMAQ_IMAGE_RGB_U64.

+* 

+* @param image The source image that the function extracts the planes from.

+* @param mode The color space that the function extracts the planes from. Valid values are IMAQ_RGB, IMAQ_HSL, IMAQ_HSV, IMAQ_HSI.

+* @param plane1 On return, the first extracted plane. Set this parameter to NULL if you do not need this information. RGB-Red, HSL/HSV/HSI-Hue.

+* @param plane2 On return, the second extracted plane. Set this parameter to NULL if you do not need this information. RGB-Green, HSL/HSV/HSI-Saturation.

+* @param plane3 On return, the third extracted plane. Set this parameter to NULL if you do not need this information. RGB-Blue, HSL-Luminance, HSV-Value, HSI-Intensity.

+*

+* @return error code: 0 = error. To get extended error information, call GetLastError().

+*/

+int frcExtractColorPlanes(const Image* image, ColorMode mode, 

+		Image* plane1, Image* plane2, Image* plane3)

+{	return imaqExtractColorPlanes(image, mode, plane1, plane2, plane3); }

+

+/**

+* @brief Extracts the Hue information from a color image. Supports IMAQ_IMAGE_RGB, IMAQ_IMAGE_HSL, IMAQ_IMAGE_RGB_U64 

+* 

+* @param image The source image that the function extracts the plane from.

+* @param huePlane On return, the extracted hue plane. 

+* @param minSaturation the minimum saturation level required 0-255 (try 50)  

+*          

+* @return On success: 1. On failure: 0. To get extended error information, call GetLastError().     

+*/

+int frcExtractHuePlane(const Image* image, Image* huePlane)

+{

+	return frcExtractHuePlane(image, huePlane, DEFAULT_SATURATION_THRESHOLD);

+}

+

+int frcExtractHuePlane(const Image* image, Image* huePlane, int minSaturation)

+{

+	return frcExtractColorPlanes(image, IMAQ_HSL, huePlane, NULL, NULL);

+}

+

+

+

+

+

+

+

+

diff --git a/azaleasource/WPILibCProgramming/trunk/WPILib/Vision2009/VisionAPI.h b/azaleasource/WPILibCProgramming/trunk/WPILib/Vision2009/VisionAPI.h
new file mode 100644
index 0000000..5b9628e
--- /dev/null
+++ b/azaleasource/WPILibCProgramming/trunk/WPILib/Vision2009/VisionAPI.h
@@ -0,0 +1,163 @@
+/********************************************************************************

+*  Project   		: FIRST Motor Controller

+*  File Name  		: VisionAPI.h          

+*  Contributors   	: ELF, JDG, ARK, EMF

+*  Creation Date 	: June 22, 2008

+*  Revision History	: Source code & revision history maintained at sourceforge.WPI.edu    

+*  File Description	: Globally defined values for the FIRST Vision API

+* 

+*  API: Because nivision.h uses C++ style comments, any file including this

+*  must be a .cpp (not .c).

+*/

+/*----------------------------------------------------------------------------*/

+/*        Copyright (c) FIRST 2008.  All Rights Reserved.                     */

+/*  Open Source Software - may be modified and shared by FRC teams. The code  */

+/*  must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */

+/*----------------------------------------------------------------------------*/

+

+#ifndef __VISIONAPI_H__

+#define __VISIONAPI_H__

+

+#include "nivision.h" 

+

+/*   Constants */

+

+#define DEFAULT_BORDER_SIZE				3		//VisionAPI.frcCreateImage

+#define DEFAULT_SATURATION_THRESHOLD	40		//TrackAPI.FindColor

+

+/*   Forward Declare Data Structures */

+typedef struct FindEdgeOptions_struct FindEdgeOptions;

+typedef struct CircularEdgeReport_struct CircularEdgeReport;

+

+/*   Data Structures */

+

+/**  frcParticleAnalysis returns this structure */

+typedef struct ParticleAnalysisReport_struct {

+	int 	imageHeight;

+	int 	imageWidth;

+	double 	imageTimestamp;				

+	int		particleIndex;				// the particle index analyzed

+	/* X-coordinate of the point representing the average position of the 

+	 * total particle mass, assuming every point in the particle has a constant density */

+	int 	center_mass_x;  			// MeasurementType: IMAQ_MT_CENTER_OF_MASS_X 

+	/* Y-coordinate of the point representing the average position of the 

+	 * total particle mass, assuming every point in the particle has a constant density */

+	int 	center_mass_y;  			// MeasurementType: IMAQ_MT_CENTER_OF_MASS_Y 

+	double 	center_mass_x_normalized;  	//Center of mass x value normalized to -1.0 to +1.0 range

+	double 	center_mass_y_normalized;  	//Center of mass y value normalized to -1.0 to +1.0 range

+	/* Area of the particle */

+	double 	particleArea;				// MeasurementType: IMAQ_MT_AREA

+	/* Bounding Rectangle */

+	Rect 	boundingRect;				// left/top/width/height

+	/* Percentage of the particle Area covering the Image Area. */

+	double 	particleToImagePercent;		// MeasurementType: IMAQ_MT_AREA_BY_IMAGE_AREA

+	/* Percentage of the particle Area in relation to its Particle and Holes Area */

+	double 	particleQuality;			// MeasurementType: IMAQ_MT_AREA_BY_PARTICLE_AND_HOLES_AREA

+} ParticleAnalysisReport;

+

+/** Tracking functions return this structure */

+typedef struct ColorReport_struct {

+	int		numberParticlesFound;				// Number of particles found for this color

+	int 	largestParticleNumber;				// The particle index of the largest particle

+	/* Color information */

+	float 	particleHueMax;				// HistogramReport: hue max

+	float 	particleHueMin;				// HistogramReport: hue max

+	float 	particleHueMean;			// HistogramReport: hue mean

+	float 	particleSatMax;				// HistogramReport: saturation max

+	float 	particleSatMin;				// HistogramReport: saturation max

+	float 	particleSatMean;			// HistogramReport: saturation mean

+	float 	particleLumMax;				// HistogramReport: luminance max

+	float 	particleLumMin;				// HistogramReport: luminance  max

+	float 	particleLumMean;			// HistogramReport: luminance mean

+} ColorReport;

+

+

+/*   Image Management functions */

+

+/* Create: calls imaqCreateImage. Border size is set to some default value */

+Image* frcCreateImage( ImageType type );

+

+/* Dispose: calls imaqDispose */

+int frcDispose( void* object );

+int frcDispose( const char* filename, ... ) ;

+

+/* Copy: calls imaqDuplicateImage */

+int frcCopyImage( Image* dest, const Image* source );

+

+/* Image Extraction: Crop: calls imaqScale */

+int frcCrop( Image* dest, const Image* source, Rect rect );

+

+/* Image Extraction: Scale: calls imaqScale.  Scales entire image */

+int frcScale(Image* dest, const Image* source, int xScale, int yScale, ScalingMode scaleMode );

+

+/* Read Image : calls imaqReadFile */

+int frcReadImage( Image* image, const char* fileName );

+/* Write Image : calls imaqWriteFile */

+int frcWriteImage( const Image* image, const char* fileName);

+

+/*   Measure Intensity functions */

+

+/* Histogram: calls imaqHistogram */

+HistogramReport* frcHistogram( const Image* image, int numClasses, float min, float max, Rect rect );

+/* Color Histogram: calls imaqColorHistogram2 */

+ColorHistogramReport* frcColorHistogram(const Image* image, int numClasses, ColorMode mode, Image* mask);

+

+/* Get Pixel Value: calls imaqGetPixel */

+int frcGetPixelValue( const Image* image, Point pixel, PixelValue* value );

+

+/*   Particle Analysis functions */

+

+/* Particle Filter: calls imaqParticleFilter3 */

+int frcParticleFilter(Image* dest, Image* source, const ParticleFilterCriteria2* criteria, 

+		int criteriaCount, const ParticleFilterOptions* options, Rect rect, int* numParticles);

+int frcParticleFilter(Image* dest, Image* source, const ParticleFilterCriteria2* criteria, 

+		int criteriaCount, const ParticleFilterOptions* options, int* numParticles);

+/* Morphology: calls imaqMorphology */

+int frcMorphology(Image* dest, Image* source, MorphologyMethod method);

+int frcMorphology(Image* dest, Image* source, MorphologyMethod method, const StructuringElement* structuringElement);

+/* Reject Border: calls imaqRejectBorder */

+int frcRejectBorder(Image* dest, Image* source);

+int frcRejectBorder(Image* dest, Image* source, int connectivity8);

+/* Count Particles: calls imaqCountParticles */

+int frcCountParticles(Image* image, int* numParticles);

+/* Particle Analysis Report: calls imaqMeasureParticle */

+int frcParticleAnalysis(Image* image, int particleNumber, ParticleAnalysisReport* par);

+

+/*   Image Enhancement functions */

+

+/* Equalize: calls imaqEqualize */

+int frcEqualize(Image* dest, const Image* source, float min, float max);

+int frcEqualize(Image* dest, const Image* source, float min, float max, const Image* mask);

+

+/* Color Equalize: calls imaqColorEqualize */

+int frcColorEqualize(Image* dest, const Image* source);

+int frcColorEqualize(Image* dest, const Image* source, int colorEqualization);

+

+/*   Image Thresholding & Conversion functions */

+

+/* Smart Threshold: calls imaqLocalThreshold */

+int frcSmartThreshold(Image* dest, const Image* source, unsigned int windowWidth, unsigned int windowHeight, 

+		LocalThresholdMethod method, double deviationWeight, ObjectType type);

+int frcSmartThreshold(Image* dest, const Image* source, unsigned int windowWidth, unsigned int windowHeight, 

+		LocalThresholdMethod method, double deviationWeight, ObjectType type, float replaceValue);

+

+/* Simple Threshold: calls imaqThreshold */

+int frcSimpleThreshold(Image* dest, const Image* source, float rangeMin, float rangeMax, float newValue);

+int frcSimpleThreshold(Image* dest, const Image* source, float rangeMin, float rangeMax);

+

+/* Color/Hue Threshold: calls imaqColorThreshold */

+int frcColorThreshold(Image* dest, const Image* source, ColorMode mode, 

+		const Range* plane1Range, const Range* plane2Range, const Range* plane3Range);

+int frcColorThreshold(Image* dest, const Image* source, int replaceValue, ColorMode mode, 

+		const Range* plane1Range, const Range* plane2Range, const Range* plane3Range);

+int frcHueThreshold(Image* dest, const Image* source, const Range* hueRange);

+int frcHueThreshold(Image* dest, const Image* source, const Range* hueRange, int minSaturation);

+

+/* Extract ColorHue Plane: calls imaqExtractColorPlanes */

+int frcExtractColorPlanes(const Image* image, ColorMode mode, Image* plane1, Image* plane2, Image* plane3);

+int frcExtractHuePlane(const Image* image, Image* huePlane);

+int frcExtractHuePlane(const Image* image, Image* huePlane, int minSaturation);

+

+#endif

+

+