⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 transserverdlg.cpp

📁 《医学图象的远程传输系统》
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// TransServerDlg.cpp : implementation file
//

#include "stdafx.h"
#include "TransServer.h"
#include "TransServerDlg.h"

#include "ChannelDlg.h"
#include "OptionDlg.h"
#include "AboutDlg.h"

#include "..\ImgSample\ImgSample.h"		//image sample system
#include "..\ImgCompress\ImgCompress.h"	//image compress system
#include "..\Enroll\EnrollInterface.h"	//database system

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

CTransServerDlg* g_Dlg;//used for thread function
volatile int g_SendWaitCount[4]={0,0,0,0};//how many sockets should wait for sent

//convert image into small size, and in the same time change the
//brightness of the image.
//still have problems for image which width not equal 4 times.
//2002.05.30
inline void Bmp2Thumb(BYTE* pDib,BYTE* pThumb,const int nWidth,const int nHeight,const int nBrightness){
    int Width=((int)(nWidth+3)/4)*4;
	for (int j=0;j<(int)(nHeight/2);j++){
		for (int i=0;i<(int)(Width/2);i++){
#define COLORCHECK(x) (x)<0?0:((x)>255?255:(x))
			pThumb[(j*Width/2+i)*3]=COLORCHECK(pDib[(j*Width*2+i*2)*3]+nBrightness);
			pThumb[(j*Width/2+i)*3+1]=COLORCHECK(pDib[(j*Width*2+i*2)*3+1]+nBrightness);
			pThumb[(j*Width/2+i)*3+2]=COLORCHECK(pDib[(j*Width*2+i*2)*3+2]+nBrightness);
#undef COLORCHECK
		}
	}
}

//******************************************
//the thread for sampling image and send it through network
//2002.05.18
UINT SampleThread(LPVOID lpParam){
	int channel=(int)lpParam;
	ASSERT(channel>=0 && channel<4);
    while (TRUE){
		if (!g_Dlg->m_CanSample[channel]){
			Sleep(200);
			continue;
		}
		DWORD dwStartTime=GetTickCount();
		//***************************************
		//get the sample image and display it
		if (!ISGetImg(channel,g_Dlg->m_pDib[channel])){
			g_Dlg->AddLog(ISGetLastError(channel));
			g_Dlg->DrawImg(channel,FALSE);
			continue;
		}
		BITMAPINFOHEADER* bmih=(BITMAPINFOHEADER*)(g_Dlg->m_pDib[channel]+sizeof(BITMAPFILEHEADER));
		Bmp2Thumb(g_Dlg->m_pDib[channel]+sizeof(BITMAPINFOHEADER)+sizeof(BITMAPFILEHEADER),
			g_Dlg->m_pThumb[channel],bmih->biWidth,bmih->biHeight,g_Dlg->m_Slider[channel]-50);
		g_Dlg->m_bmInfo[channel].bmiHeader.biWidth=bmih->biWidth/2;
		g_Dlg->m_bmInfo[channel].bmiHeader.biHeight=bmih->biHeight/2;
		//m_CanSample[channel] may changed during we sample the image,
		//if so, we should clear the rect.
		g_Dlg->DrawImg(channel,g_Dlg->m_CanSample[channel]);
		//***************************************
		//compress the image
		if (!ICCompress(channel,&g_Dlg->m_jcprops[channel],
            g_Dlg->m_pDib[channel],&(g_Dlg->m_JpegBuffer[channel]),
            &(g_Dlg->m_JpegSize[channel]),g_Dlg->m_CompressQuality)){
			g_Dlg->AddLog(ICGetLastError(channel));
			continue;
		}
		//***************************************
		//save the jpeg image into database if needed
		if (g_Dlg->m_ChannelToSave==channel){
			if (ENAddImage(g_Dlg->m_PatientID,g_Dlg->m_JpegBuffer[channel],g_Dlg->m_JpegSize[channel])<0){//return -1 when failed
				g_Dlg->AddLog("Error to save image into database!");
			}
		}
		//***************************************
		//send the image to all clients
		g_SendWaitCount[channel]=0;
		for (POSITION pos=g_Dlg->m_ConnectionList[channel].GetHeadPosition();pos!=NULL;){
			CONNECTION* conn=(CONNECTION*)g_Dlg->m_ConnectionList[channel].GetNext(pos);
			if (conn->Channel==channel){
				::InterlockedIncrement((long*)&g_SendWaitCount[channel]);
				conn->BeginSendEvent.SetEvent(); 
			}
		}//for
		while (g_SendWaitCount[channel]>0){//wait for all send threads to end
			Sleep(100);
		}
		//***************************************
		//delay
		DWORD dwEndTime=GetTickCount();
		if ((dwEndTime-dwStartTime)<g_Dlg->m_SampleFrequency){
			Sleep(g_Dlg->m_SampleFrequency-(dwEndTime-dwStartTime));
		}
		//***************************************
        //calculate the total time in this sample
        for (int i=0;i<2;i++){
            g_Dlg->m_TotalTime[channel][i+1]=g_Dlg->m_TotalTime[channel][i];
        }
		g_Dlg->m_TotalTime[channel][0]=GetTickCount()-dwStartTime;
	}//while TRUE
    return TRUE;
}

//******************************************
//the thread for a perpous socket, every stream socket will have it's own
//thread. it will be blocked until there had data to send to unblock it, 
//use the BeginSendEvent.SetEvent() to unblock it.
//2002.05.18
UINT SendThread(LPVOID pParam){
	CONNECTION* conn=(CONNECTION*)pParam;
	while(TRUE){
		::WaitForSingleObject(conn->BeginSendEvent,INFINITE);
		//****************************************
		//send the jpeg buffer
		int nIndex=0;
		int nJpegSize=g_Dlg->m_JpegSize[conn->Channel];
		STREAM_DATA JpegData;
		while (nJpegSize>0){
			JpegData.nIndex=nIndex;
			if (nJpegSize>PackageSize){//this is the first or the other package
				JpegData.bEnd=FALSE;
				JpegData.nSize=PackageSize;
			}
			else{//this is the last package
				JpegData.bEnd=TRUE;
				JpegData.nSize=nJpegSize;
			}
			CopyMemory(&JpegData.Buffer,g_Dlg->m_JpegBuffer[conn->Channel]+PackageSize*nIndex,JpegData.nSize);
			for(int i=0;i<SEND_RETRY;i++){//try n times for send data
				conn->pSocket->m_bSent=FALSE;
				if (conn->pSocket->Send(&JpegData,sizeof(STREAM_DATA))!=sizeof(STREAM_DATA)){
					CString sResult;
					sResult.Format("Socket [%d] sent size not correct on channel %d .",conn->pSocket,conn->Channel);
					g_Dlg->AddLog(sResult);
					g_Dlg->RemoveConnection(conn->Channel,conn);
					::InterlockedDecrement((long*)&g_SendWaitCount[conn->Channel]);
					return FALSE;//exit thread
				}
				DWORD TimeNow=GetTickCount();
				while(GetTickCount()-TimeNow<5000 && !(conn->pSocket->m_bSent)){
					//!!!!
				}
				if (conn->pSocket->m_bSent){
					break;//for
				}
				else{
					CString sResult;
					sResult.Format("Socket [%d] timeout %d when send package #%d .",conn->pSocket,i,nIndex);
					g_Dlg->AddLog(sResult);
				}
			}//for
			nIndex++;
			nJpegSize-=PackageSize;
		}//while nJpegSize
		::InterlockedDecrement((long*)&g_SendWaitCount[conn->Channel]);
	}//while TRUE
	return TRUE;
}

/////////////////////////////////////////////////////////////////////////////
// CTransServerDlg dialog

CTransServerDlg::CTransServerDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CTransServerDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CTransServerDlg)
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
	g_Dlg=this;	
	m_ChannelToSave=-1;//means no channel should be save to database
	m_Slider[0]=m_Slider[1]=m_Slider[2]=m_Slider[3]=50;
	char AppPath[MAX_PATH];
	if (GetModuleFileName(AfxGetInstanceHandle(),AppPath,MAX_PATH)){
		strcat(AppPath,".ini");
		m_SampleFrequency=GetPrivateProfileInt("General","SampleFrequency",
			200,AppPath);
        m_CompressQuality=GetPrivateProfileInt("General","CompressQuality",
            50,AppPath);
	}
	else{
		m_SampleFrequency=200;//the default value of Sample Frequency
        m_CompressQuality=50;//the default value of compress quality
	}
}


void CTransServerDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CTransServerDlg)
	DDX_Control(pDX, IDC_EDIT_LOG, m_EditLog);
	//}}AFX_DATA_MAP
	DDX_Slider(pDX, IDC_SLIDER1, m_Slider[0]);
	DDX_Slider(pDX, IDC_SLIDER2, m_Slider[1]);
	DDX_Slider(pDX, IDC_SLIDER3, m_Slider[2]);
	DDX_Slider(pDX, IDC_SLIDER4, m_Slider[3]);
	DDX_Control(pDX, IDC_BTN_SAMPLE1, m_Sample[0]);
	DDX_Control(pDX, IDC_BTN_SAMPLE2, m_Sample[1]);
	DDX_Control(pDX, IDC_BTN_SAMPLE3, m_Sample[2]);
	DDX_Control(pDX, IDC_BTN_SAMPLE4, m_Sample[3]);
	DDX_Control(pDX, IDC_BTN_SAMPLE5, m_Sample[4]);
	DDX_Control(pDX, IDC_BTN_SAMPLE6, m_Sample[5]);
	DDX_Control(pDX, IDC_BTN_SAMPLE7, m_Sample[6]);
	DDX_Control(pDX, IDC_BTN_SAMPLE8, m_Sample[7]);
	DDX_Control(pDX, IDC_BUTTON8, m_Button[0]);
	DDX_Control(pDX, IDC_BUTTON7, m_Button[1]);
	DDX_Control(pDX, IDC_BUTTON6, m_Button[2]);
	DDX_Control(pDX, IDC_BUTTON5, m_Button[3]);
	DDX_Control(pDX, IDC_BUTTON4, m_Button[4]);
	DDX_Control(pDX, IDC_BUTTON3, m_Button[5]);
	DDX_Control(pDX, IDC_BUTTON2, m_Button[6]);
	DDX_Control(pDX, IDC_BUTTON1, m_Button[7]);
}

BEGIN_MESSAGE_MAP(CTransServerDlg, CDialog)
	//{{AFX_MSG_MAP(CTransServerDlg)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_WM_HSCROLL()
	ON_BN_CLICKED(IDC_BTN_SAMPLE1, OnBtnSample1)
	ON_BN_CLICKED(IDC_BTN_SAMPLE2, OnBtnSample2)
	ON_BN_CLICKED(IDC_BTN_SAMPLE3, OnBtnSample3)
	ON_BN_CLICKED(IDC_BTN_SAMPLE4, OnBtnSample4)
	ON_BN_CLICKED(IDC_BTN_SAMPLE5, OnBtnSample5)
	ON_BN_CLICKED(IDC_BTN_SAMPLE6, OnBtnSample6)
	ON_BN_CLICKED(IDC_BTN_SAMPLE7, OnBtnSample7)
	ON_BN_CLICKED(IDC_BTN_SAMPLE8, OnBtnSample8)
	ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
	ON_BN_CLICKED(IDC_BUTTON2, OnButton2)
	ON_BN_CLICKED(IDC_BUTTON3, OnButton3)
	ON_BN_CLICKED(IDC_BUTTON4, OnButton4)
	ON_BN_CLICKED(IDC_BUTTON5, OnButton5)
	ON_BN_CLICKED(IDC_BUTTON6, OnButton6)
	ON_BN_CLICKED(IDC_BUTTON7, OnButton7)
	ON_BN_CLICKED(IDC_BUTTON8, OnButton8)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CTransServerDlg message handlers

BOOL CTransServerDlg::OnInitDialog()
{
#ifdef _DEBUG
	CString Title;
	GetWindowText(Title);
	SetWindowText(Title+"<< Debug >>");
#endif

	CDialog::OnInitDialog();

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon

	m_Button[0].SetIcon(IDI_BTN2,IDI_BTN1);
	m_Button[1].SetIcon(IDI_BTN2,IDI_BTN1);
	m_Button[2].SetIcon(IDI_BTN2,IDI_BTN1);
	m_Button[3].SetIcon(IDI_BTN2,IDI_BTN1);
	m_Button[4].SetIcon(IDI_BTN2,IDI_BTN1);
	m_Button[5].SetIcon(IDI_BTN2,IDI_BTN1);
	m_Button[6].SetIcon(IDI_BTN2,IDI_BTN1);
	m_Button[7].SetIcon(IDI_BTN2,IDI_BTN1);

	m_Sample[0].SetIcon(IDR_STARTSAMPLE,IDR_STARTSAMPLE2);
	m_Sample[1].SetIcon(IDR_STOPSAMPLE,IDR_STOPSAMPLE2);
	m_Sample[2].SetIcon(IDR_STARTSAMPLE,IDR_STARTSAMPLE2);
	m_Sample[3].SetIcon(IDR_STOPSAMPLE,IDR_STOPSAMPLE2);
	m_Sample[4].SetIcon(IDR_STARTSAMPLE,IDR_STARTSAMPLE2);
	m_Sample[5].SetIcon(IDR_STOPSAMPLE,IDR_STOPSAMPLE2);
	m_Sample[6].SetIcon(IDR_STARTSAMPLE,IDR_STARTSAMPLE2);
	m_Sample[7].SetIcon(IDR_STOPSAMPLE,IDR_STOPSAMPLE2);

	for (int i=0;i<4;i++){
		m_bmInfo[i].bmiHeader.biBitCount=24;
		m_bmInfo[i].bmiHeader.biClrImportant=0;
		m_bmInfo[i].bmiHeader.biClrUsed=0;
		m_bmInfo[i].bmiHeader.biCompression=BI_RGB;
		m_bmInfo[i].bmiHeader.biHeight=0;
		m_bmInfo[i].bmiHeader.biPlanes=1;
		m_bmInfo[i].bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
		m_bmInfo[i].bmiHeader.biSizeImage=0;
		m_bmInfo[i].bmiHeader.biWidth=0;
		m_bmInfo[i].bmiHeader.biXPelsPerMeter=1;
		m_bmInfo[i].bmiHeader.biYPelsPerMeter=1;
		//******************************************
		//initialize jpeg compress system
		if (!ICInit(i,&m_jcprops[i])){
			AddLog(ICGetLastError(i));
		}
		//******************************************
		//allocate memory for image
		m_pDib[i]=(BYTE*)::GlobalAlloc(GMEM_FIXED,MAX_BMP_SIZE);
		if (!m_pDib[i]){
			AddLog("Error to allocate memory for dib!");
		}
		m_pThumb[i]=(BYTE*)::GlobalAlloc(GMEM_FIXED,MAX_BMP_SIZE/4);
		if (!m_pThumb[i]){
			AddLog("Error to allocate memory for thumb!");
		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -