www.pudn.com > speakfs72.zip > FACE.C, change:2002-01-05,size:12716b


/* 
 
				Show Your Face 
				 
*/ 
 
#include "netfone.h" 
 
char faceFileName[MAX_PATH] = "";		// Face image file name 
int faceShow = TRUE;					// Show faces ? 
 
HFILE faceFile = HFILE_ERROR; 			// Face image file handle 
 
//	CLOSEFACEFILE  --  Close face file (if open) 
 
void closeFaceFile(void) 
{ 
	if (faceFile != HFILE_ERROR) { 
		_lclose(faceFile); 
		faceFile = HFILE_ERROR; 
	}  
} 
 
/*	OPENFACEFILE  --  Open face file and validate it's 
					  in a compatible format.  */ 
 
int openFaceFile(HWND hwnd) 
{ 
	closeFaceFile(); 
	if (faceFileName[0] != 0) { 
		faceFile = _lopen(faceFileName, OF_READ); 
		if (faceFile == HFILE_ERROR) { 
	        MsgBox(hwnd, MB_ICONSTOP | MB_OK, Format(65), (LPSTR) faceFileName); 
		} else { 
    		BITMAPFILEHEADER bfh; 
    		BITMAPINFOHEADER bmi; 
 
			_lread(faceFile, &bfh, sizeof bfh); 
			if (_fstrncmp((char *) &bfh, "GIF87a", 6) == 0 || 
				_fstrncmp((char *) &bfh, "GIF89a", 6) == 0) { 
				return TRUE; 
			} 
			if (_fstrncmp((char *) &bfh, "BM", 2) == 0) {  
    			_lread(faceFile, &bmi, sizeof(BITMAPINFOHEADER)); 
    			if (bmi.biBitCount == 8 && bmi.biCompression == BI_RGB && 
    				bmi.biClrUsed <= 256 && bmi.biPlanes == 1) { 
    				return TRUE; 
    			} 
    		} 
    		MsgBox(hwnd, MB_ICONSTOP | MB_OK, Format(66), (LPSTR) faceFileName); 
    		closeFaceFile(); 
		} 
		return FALSE;	 
	} 
	return TRUE; 
} 
 
/*	PROCESSFACEREQUEST  --  Process a face request packet and place 
							the reply in the same packet.  */ 
							 
void processFaceRequest(soundbuf *d) 
{ 
	long l; 
 
	// Request for face data 
 
	if (faceFile != HFILE_ERROR) { 
		_llseek(faceFile, d->buffer.buffer_len, 0); 
		*((long *) d->buffer.buffer_val) = htonl(d->buffer.buffer_len); 
		l = _lread(faceFile, d->buffer.buffer_val + sizeof(long), 
				512 - (sizeof(long) + (sizeof(soundbuf) - BUFL))); 
		d->compression = fProtocol | fFaceData | faceReply; 
		l += sizeof(long); 
	} else { 
		// No face file.  Shut down requestor. 
		d->compression = fProtocol | fFaceData | faceLess; 
		l = 0; 
	} 
#ifdef TRACE_FACE	 
	{ 
		char s[132]; 
		 
		wsprintf(s, "Face data request for %ld, returned %ld\r\n", 
			ntohl(*((long *) d->buffer.buffer_val)), l); 
		OutputDebugString(s);  
	} 
#endif	 
	d->buffer.buffer_len = l; 
}							 
 
//	FACEDLGPROC  --  Face dialogue procedure 
 
BOOL CALLBACK faceDlgProc(HWND hwnd, UINT nMessage, 
							WPARAM wParam, LPARAM lParam) 
{ 
	switch (nMessage) { 
    	case WM_INITDIALOG: 
			SetDlgItemText(hwnd, IDC_FA_FILENAME, faceFileName); 
			CheckDlgButton(hwnd, IDC_FA_SHOW, faceShow);  
	    	return TRUE; 
	    	 
	    case WM_CLOSE: 
	    	DestroyWindow(hwnd); 
	    	return TRUE; 
 
        case WM_COMMAND: 
        	switch ((short) WM_COMMAND_ID(wParam)) { 
        		case IDC_FA_CLEAR: 
        			SetDlgItemText(hwnd, IDC_FA_FILENAME, ""); 
        			break; 
        	 
                case IDC_FA_BROWSE: 
			     	{ 
			     		OPENFILENAME ofn; 
			     		char szString[MAX_PATH]; 
			 
			            memset(&ofn, 0, sizeof(ofn)); 
						ofn.lStructSize = sizeof(OPENFILENAME); 
						ofn.hwndOwner = hwnd; 
						ofn.lpstrFilter = rfilter(IDS_T_FACE_FILE_FILTER); 
						ofn.lpstrCustomFilter = NULL; 
						strcpy(szString, faceFileName); 
						ofn.lpstrFile = (LPSTR) szString; 
						ofn.nMaxFile = sizeof(szString); 
						ofn.lpstrInitialDir = NULL; 
						ofn.lpstrTitle = rstring(IDS_T_FACE_OPEN_TITLE); 
						ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_SHOWHELP; 
						fileHelpKey = rstring(IDS_HELP_FACE); 
						if (GetOpenFileName((LPOPENFILENAME) &ofn)) { 
							SetDlgItemText(hwnd, IDC_FA_FILENAME, szString); 
						} 
					} 
					break; 
        	 
		    	case IDOK: 
		    		{ 
		    			char sff[MAX_PATH]; 
		    			 
		    			_fstrcpy(sff, faceFileName); 
			    		GetDlgItemText(hwnd, IDC_FA_FILENAME, 
			                				faceFileName, sizeof faceFileName); 
			            if (!openFaceFile(hwnd)) { 
			            	/*	Don't let user exit until a valid (or no) 
			            		face file is specified.  */ 
			            	_fstrcpy(faceFileName, sff); 
			            	break; 
			            } 
			    		faceShow = IsDlgButtonChecked(hwnd, IDC_FA_SHOW); 
		                EndDialog(hwnd, TRUE); 
		            } 
                    break; 
 
                case IDCANCEL: 
                    EndDialog(hwnd, FALSE); 
                    break; 
		        	 
                case ID_HELP: 
                	WinHelp(hwndMDIFrame, rstring(IDS_HELPFILE), HELP_KEY, 
                				((DWORD) (Lrstring(IDS_HELP_FACE)))); 
                	holped = TRUE; 
                	break; 
		    } 
        	return FALSE; 
        	 
        default: 
        	if (nMessage == fileOpenHelpButton && fileHelpKey != NULL) { 
            	WinHelp(hwndMDIFrame, rstring(IDS_HELPFILE), HELP_KEY, 
            				((DWORD) (LPSTR) fileHelpKey)); 
            	holped = TRUE; 
        	} 
        	break;	    	 
    } 
    return FALSE; 
} 
 
//	FACEDIALOGUE  --  Face configuration dialogue 
 
int faceDialogue(HWND hWndParent) 
{ 
    int result; 
 
    result = DialogBox(hInst, MAKEINTRESOURCE(IDD_FACE), hWndParent, faceDlgProc); 
    return result; 
} 
 
/*	PROCESSFACEDATA  --  Process a buffer-full of face image data 
						 received for a connection.  */ 
						  
void processFaceData(HWND hwnd, LPCLIENT_DATA c, soundbuf *d) 
{ 
	if (d->compression & faceReply) { 
 
		// Face data packet received from remote server 
		 
		if (d->buffer.buffer_len > sizeof(long)) { 
			long lp =  ntohl(*((long *) d->buffer.buffer_val)); 
			BITMAPFILEHEADER FAR *bfh; 
 
			if (lp == c->face_address) { 
				if (lp == 0) { 
					 
					if (c->face_bmp != NULL) { 
						GlobalFreePtr(c->face_bmp); 
					} 
					c->face_bmp = NULL; 
					bfh = (BITMAPFILEHEADER *) (d->buffer.buffer_val + sizeof(long)); 
					if (_fstrncmp((LPSTR) &bfh->bfType, "GIF87a", 6) == 0 || 
						_fstrncmp((LPSTR) &bfh->bfType, "GIF89a", 6) == 0) { 
						/* GIF files don't tell us up-front how long they're 
						   going to be.  We initially allocate a 16K block (big 
						   enough to hold the majority of face GIFs), then expand 
						   it in increments of 16K if more data than that arrives. */ 
						    
						c->face_file_length = 16384L; 
						c->face_is_gif = TRUE;						 
					} else { 
						if (_fstrncmp((LPSTR) &bfh->bfType, "BM", 2) != 0) { 
#ifdef TRACE_FACE 
							char s[132]; 
								 
		                    wsprintf(s, "Face image is not a Windows bitmap or GIF file\r\n"); 
							OutputDebugString(s); 
#endif 
						} 
						if ((DWORD) (d->buffer.buffer_len - sizeof(long)) > bfh->bfSize) { 
#ifdef TRACE_FACE 
							char s[132]; 
								 
		                    wsprintf(s, "Bogus size %ld in face bitmap\r\n", bfh->bfSize); 
							OutputDebugString(s); 
#endif 
							c->face_stat = FSabandoned; 
							return; 
						} 
						c->face_file_length = bfh->bfSize; 
						c->face_is_gif = FALSE;  
					} 
					c->face_bmp = GlobalAllocPtr(GPTR, c->face_file_length); 
					if (c->face_bmp == NULL) {  
#ifdef TRACE_FACE 
						char s[132]; 
							 
	                    wsprintf(s, "Cannot allocate %ld bytes for face bitmap\r\n", c->face_file_length); 
						OutputDebugString(s); 
#endif 
						c->face_stat = FSabandoned; 
						return;						 
					} 
#ifdef TRACE_FACE 
					{ 
						char s[132]; 
							 
	                    wsprintf(s, "Receiving %ld byte face bitmap\r\n", c->face_file_length); 
						OutputDebugString(s); 
					}	 
#endif 
					_fmemcpy(c->face_bmp, d->buffer.buffer_val + sizeof(long), 
						(int) d->buffer.buffer_len - sizeof(long)); 
					c->face_address += d->buffer.buffer_len - sizeof(long); 
					c->face_stat = FSreply; 
					c->face_retry = 0;					 
	                return; 
				} 
				bfh = (BITMAPFILEHEADER FAR *) c->face_bmp; 
				 
				if ((c->face_address + (d->buffer.buffer_len - sizeof(long))) > 
					(unsigned long) (c->face_file_length)) { 
					if (c->face_is_gif) { 
#ifdef TRACE_FACE 
						char s[132]; 
									 
	                    wsprintf(s, "Expanding GIF buffer to %ld bytes.\r\n", 
	                    	c->face_file_length + 16384L); 
						OutputDebugString(s); 
#endif						 
						c->face_bmp = GlobalReAllocPtr(c->face_bmp, c->face_file_length + 
							16384L, 0); 
						if (c->face_bmp == NULL) { 
							//	Couldn't expand face bitmap buffer 
							c->face_stat = FSabandoned; 
#ifdef TRACE_FACE 
							{ 
								char s[132]; 
										 
								wsprintf(s, "Out of memory trying to expand GIF buffer to %ld bytes.\r\n", 
		                    		c->face_file_length); 
								OutputDebugString(s); 
							} 
#endif 
							return; 
						} 
						c->face_file_length += 16384L;  
					} else { 
#ifdef TRACE_FACE 
						char s[132]; 
								 
	                    wsprintf(s, "Address %ld plus buffer length %ld overflows %ld byte bitmap\r\n", 
	                    	c->face_address, d->buffer.buffer_len - sizeof(long), bfh->bfSize); 
						OutputDebugString(s); 
#endif 
						GlobalFreePtr(c->face_bmp); 
						c->face_bmp = NULL; 
						c->face_stat = FSabandoned; 
						return; 
					}						 
				}  
#ifdef TRACE_FACE 
				{ 	char s[132]; 
					 
                    wsprintf(s, "Storing %ld bytes at %ld in face bitmap\r\n", 
						d->buffer.buffer_len - sizeof(long), lp); 
					OutputDebugString(s); 
				} 
#endif 
				_fmemcpy(c->face_bmp + c->face_address, 
					d->buffer.buffer_val + sizeof(long), 
					(int) (d->buffer.buffer_len - sizeof(long))); 
				c->face_address += d->buffer.buffer_len - sizeof(long); 
				/* Timeout will make next request after the 
				   configured interval. */ 
				c->face_stat = FSreply; 
				c->face_retry = 0; 
			} else { 
#ifdef TRACE_FACE 
				{	char s[132]; 
					 
                    wsprintf(s, "Discarded %ld bytes for %ld in face bitmap, expected data for %ld\r\n", 
						d->buffer.buffer_len - sizeof(long), 
						lp, c->face_address); 
					OutputDebugString(s); 
				} 
#endif					 
			} 
		} else { 
			BITMAPINFOHEADER FAR *bmi; 
			int bx, by; 
		    RECT cr, wr; 
 
#ifdef TRACE_FACE 
			{	char s[132]; 
					 
                wsprintf(s, "Face bitmap complete\r\n"); 
				OutputDebugString(s); 
			} 
#endif 
 
			/*	If the file we received is in GIF format, convert it 
				to a BMP file. */ 
				 
			if (c->face_is_gif && (c->face_bmp != NULL)) { 
				LPBYTE cbmp = GIFtoBMP((LPBYTE) c->face_bmp, 1); 
				 
				GlobalFreePtr(c->face_bmp); 
				if (cbmp != NULL) { 
					c->face_bmp = (LPSTR) cbmp; 
				} else { 
					c->face_bmp = NULL; 
					c->face_stat = FSabandoned; 
					return; 
				} 
			} 
 
      /* Oops, Mr. Walker forgot to check for NULL face pointer here.  Thank God for 
         debuggers. :)  -BCW 03/22/1998 */ 
      if(c->face_bmp == NULL) 
      { 
#ifdef TRACE_FACE 
				OutputDebugString("Face bitmap: NULL pointer, discarded.\r\n");				 
#endif 
				c->face_stat = FSabandoned; 
				return; 
      } 
 
      /*	Now let's perform some rudimentary verification 
				of the format of this bitmap and ditch it if it's 
				bogus.  */ 
				 
            bmi = (BITMAPINFOHEADER FAR *) (c->face_bmp + sizeof(BITMAPFILEHEADER)); 
            if (bmi->biPlanes != 1 || bmi->biBitCount != 8 || 
            	bmi->biCompression != BI_RGB || bmi->biClrUsed > 256) { 
#ifdef TRACE_FACE 
				OutputDebugString("Face bitmap: invalid format, discarded.\r\n");				 
#endif 
				GlobalFreePtr(c->face_bmp); 
				c->face_bmp = NULL; 
				c->face_stat = FSabandoned; 
				return; 
	        } 
             
			c->face_stat = FScomplete; 
			 
			//	Resize window so that client area fits bitmap 
            			 
		    GetWindowRect(hwnd, &wr); 
		    GetClientRect(hwnd, &cr); 
                         
			bx = (int) bmi->biWidth; 
			by = (int) bmi->biHeight; 
			if (bx != cr.right || by != cr.bottom) { 
				int bw = bx + ((wr.right - wr.left) - cr.right), 
					bh = by + ((wr.bottom - wr.top) - cr.bottom); 
            					 
				SetWindowPos(hwnd, HWND_TOP, 
					0, 0, bw, bh, SWP_NOMOVE | SWP_NOZORDER);	 
		    	GetClientRect(hwnd, &cr); 
#ifdef TRACE_FACE  
				{	char s[132]; 
							 
					wsprintf(s, "Resizing connection window to %dx%d (W=%dx%d)\r\n", 
						bx, by, bw, bh);	 
					OutputDebugString("Resizing connection window.\r\n"); 
				} 
#endif												    	 
			} 
			InvalidateRect(hwnd, NULL, FALSE); 
		}		 
	} else if (d->compression & faceLess) { 
		if (c->face_bmp != NULL) { 
			GlobalFreePtr(c->face_bmp); 
			c->face_bmp = NULL; 
		}		 
		c->face_stat = FSabandoned; 
#ifdef TRACE_FACE 
		{	char s[MAX_HOST + 80]; 
					 
            wsprintf(s, "No face image available from %s\r\n", c->szHost); 
			OutputDebugString(s); 
		} 
#endif					 
	} 
}