SVG5/commondata.cpp
2025-10-12 13:55:56 +09:00

2290 lines
60 KiB
C++

#include "commondata.h"
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <QDir>
#include <QDirIterator>
#include <QStorageInfo>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlRecord>
#include "mainwindow.h"
#include <jpeglib.h> //-ljpeg
CommonData::CommonData()
{
m_bUseWebDisplay = true;
//m_pDatabase = new SDatabase("CommonData");
//m_pDatabase->OpenDatabase("/home/birdhead/test.db");
m_pLogFile = NULL;
if(m_pLogFile==NULL)
{
QDir dirLog("/home/birdhead/Log");
if(dirLog.exists()==false)
{
QDir().mkdir("/home/birdhead/Log");
}
QString strLogFile = QString("/home/birdhead/Log/%1.log").arg(QDateTime::currentDateTime().toString("yyyyMMdd_HHmmss"));
m_pLogFile = new QFile(strLogFile);
m_pLogFile->open(QFile::ReadWrite | QFile::Unbuffered);
}
/*
#ifdef _SAVE_LOG
QDir().mkdir("Log");
QString strLogFile = QString("Log/%1.log").arg(QDateTime::currentDateTime().toString("yyyyMMdd_HHmmss"));
m_pLogFile = new QFile(strLogFile);
m_pLogFile->open(QFile::ReadWrite | QFile::Unbuffered);
#endif
*/
m_bConnectHDMI = false;
#ifdef _4K
m_nVideoWidth = 3840;
m_nVideoHeight = 2160;
#else
m_nVideoWidth = 1920;
m_nVideoHeight = 1080;
#endif
m_pBitmapData = new uint8_t[m_nVideoWidth*m_nVideoHeight*3+1000];
m_nGPIO_Buzzer = 0;
m_nVideoMode = 0;
m_nCropMode = 0;
m_nUseFixWidthLevel = 0;
m_nUseLogLevel = 0;
m_nUseUSBBackup = 0;
m_nScreenSaverTime = 0;
m_pSambaClient = NULL;
m_bAutoExitCaptureSendDICOM = false;
m_bAutoCaptureSendDICOM = false;
m_bAutoVideoCapture = false;
m_bAutoLogin = false;
m_bActiveDetect = false;
m_bAutoCloseSendFinish = false;
m_nGPIO_HandSwitch = 0;
m_nSearchItemHistoryStudyIndex = -1;
m_bIsCapturing = false;
m_strImageExtension = "jpg";
//m_strImageExtension = "bmp";
m_pDCMWorklist = new SDCMWorklist;
m_pListHistorySearch = new vector<HISTORY_STUDY*>;
m_pListHistoryImage = new vector<ImageSelect*>;
m_pWorklistData = new vector<WorklistResponseData>;
m_pDCMDumpList = new vector<CSDCM*>;
m_pFindSCUDataCallback = new SDCMFindSCUDataCallback(m_pDCMWorklist->GetExtractMode(), m_pDCMWorklist->GetCancelAfterNResponses());
m_pFindSCUDataCallback->SetWorklistData(m_pWorklistData);
m_pFindSCUDataCallback->SetWorklistDump(m_pDCMDumpList);
m_pCurrentWorklist = NULL;
m_pRTSPThread = NULL;
m_pListCaptureImage = new vector<CAPTURE_IMAGE*>;
m_pImageCapture = new RGB_Data[m_nVideoWidth*m_nVideoHeight];
memset(m_pImageCapture, 0, sizeof(RGB_Data)*m_nVideoWidth*m_nVideoHeight);
m_strStorageDirectory = "/home/birdhead/test_save";
m_pCurrentHistoryStudy = NULL;
m_bVideoEncoding = false;
m_pWorklistTableHeader = new STableHeader;
m_pHistoryTableHeader = new STableHeader;
QDate dt = QDate::currentDate();
SetDateSearchWorklistStart(dt);
SetDateSearchWorklistEnd(dt);
SetDateSearchHistoryStart(dt);
SetDateSearchHistoryEnd(dt);
InitWorklistIndex();
InitHistoryIndex();
InitSetting();
//m_pWorklistTableHeader->UpdateTableHeaderInfo(m_MapWorklistIndex);
#ifdef _XAVIER_NX
//m_nGPIO_Buzzer = open("/sys/class/gpio/gpio393/value", O_WRONLY);
m_strGPIOBeep = "/sys/class/gpio/gpio393/value";
m_strGPIOHandSwitch = "/sys/class/gpio/gpio271/value";
#endif
#ifdef _JETSON_TX2_NX
m_strGPIOBeep = "/sys/class/gpio/gpio269/value";
m_strGPIOHandSwitch = "/sys/class/gpio/gpio341/value";
#endif
if(m_strGPIOBeep.size()>0)
{
m_nGPIO_Buzzer = open(m_strGPIOBeep.toUtf8(), O_WRONLY);
if(m_nGPIO_Buzzer==-1)
{
}
}
ComputeStorageSize();
}
CommonData::~CommonData()
{
SAFE_ARRAY_DELETE(m_pBitmapData);
SAFE_ARRAY_DELETE(m_pImageCapture);
//SAFE_DELETE(m_pDatabase);
SAFE_DELETE(m_pWorklistTableHeader);
SAFE_DELETE(m_pHistoryTableHeader);
ClearHistorySearchResult();
SAFE_DELETE(m_pListHistorySearch);
ClearHistoryImage();
SAFE_DELETE(m_pListHistoryImage);
ClearCaptureImage();
SAFE_DELETE(m_pListCaptureImage);
SAFE_DELETE(m_pFindSCUDataCallback);
SAFE_DELETE(m_pDCMWorklist);
SAFE_DELETE(m_pWorklistData);
SAFE_DELETE(m_pDCMDumpList);
if(m_nGPIO_Buzzer>0)
{
close(m_nGPIO_Buzzer);
}
if(m_pLogFile!=NULL)
{
m_pLogFile->flush();
m_pLogFile->close();
SAFE_DELETE(m_pLogFile);
}
STableHeader::ClearMapData();
}
QDate CommonData::GetDateSearchWorklistStart()
{
return m_SearchDateWorklist.m_DateStart;
}
QDate CommonData::GetDateSearchWorklistEnd()
{
return m_SearchDateWorklist.m_DateEnd;
}
void CommonData::SetDateSearchWorklistStart(QDate date)
{
m_SearchDateWorklist.m_DateStart = date;
}
void CommonData::SetDateSearchWorklistEnd(QDate date)
{
m_SearchDateWorklist.m_DateEnd = date;
}
QString CommonData::GetStorageDirectory()
{
return m_strStorageDirectory;
}
QDate CommonData::GetDateSearchHistoryStart()
{
return m_SearchDateHistory.m_DateStart;
}
QDate CommonData::GetDateSearchHistoryEnd()
{
return m_SearchDateHistory.m_DateEnd;
}
void CommonData::SetDateSearchHistoryStart(QDate date)
{
m_SearchDateHistory.m_DateStart = date;
}
void CommonData::SetDateSearchHistoryEnd(QDate date)
{
m_SearchDateHistory.m_DateEnd = date;
}
SEARCH_ITEM* CommonData::GetSearchItemWorklist()
{
return &m_SearchItemWorklist;
}
SDCMFindSCUDataCallback* CommonData::GetFindSCUDataCallback()
{
return m_pFindSCUDataCallback;
}
vector<WorklistResponseData>* CommonData::GetWorklistData()
{
m_LockWorklistData.lock();
return m_pWorklistData;
}
void CommonData::ReleaseWorklistData()
{
m_LockWorklistData.unlock();
}
vector<CSDCM*>* CommonData::GetWorklistDump()
{
return m_pDCMDumpList;
}
void CommonData::SetRTSPThread(QRTSPThread* pThread)
{
m_pRTSPThread = pThread;
}
QRTSPThread* CommonData::GetThreadRTSP()
{
return m_pRTSPThread;
}
void CommonData::SetThreadCaptureImage(SThreadImageSave* pThread)
{
m_pThreadCaptureImage = pThread;
}
void CommonData::SetThreadSendDICOM(SThreadSendDICOM* pThread)
{
m_pThreadSendDICOM = pThread;
}
void CommonData::SetThreadWorklistSearch(SThreadWorklistSearch* pThread)
{
m_pThreadWorklistSearch = pThread;
}
SThreadImageSave* CommonData::GetThreadCaptureImage()
{
return m_pThreadCaptureImage;
}
SThreadSendDICOM* CommonData::GetThreadSendDICOM()
{
return m_pThreadSendDICOM;
}
SThreadWorklistSearch* CommonData::GetThreadWorklistSearch()
{
return m_pThreadWorklistSearch;
}
void CommonData::AddCaptureImageWithHistory()
{
int i=0;
ClearCaptureImage();
int nImages = m_pListHistoryImage->size();
QImage* pImageTmp = NULL;
m_LockAddHistory.lock();
for(i=0 ; i<nImages ; i++)
{
ImageSelect* pImageHistory = (*m_pListHistoryImage)[nImages-1-i];
QString strDate = pImageHistory->m_strDate;
QString strTime = pImageHistory->m_strTime;
int nWidth = pImageHistory->GetWidth();
int nHeight = pImageHistory->GetHeight();
QImage::Format fmt = (QImage::Format)pImageHistory->GetFormat();
int nType = pImageHistory->m_nType;
QString strFilename = pImageHistory->m_strFile;
bool bDelete = pImageHistory->m_bDelete;
QString strTimeFormat = "yyyyMMdd HHmmss";
QString strDateTime = QString("%1 %2").arg(strDate).arg(strTime);
QDateTime dtCapture = QDateTime::fromString(strDateTime, strTimeFormat);
CAPTURE_IMAGE* pImageNew = new CAPTURE_IMAGE;
pImageNew->m_nAcquisitionNumber = pImageHistory->m_nImageNumber;
pImageNew->m_bDelete = pImageHistory->m_bDelete;
pImageNew->m_bSend = pImageHistory->m_bSend;
pImageNew->m_bBackup = true;
pImageNew->m_pImageSmall = new QImage(nWidth/4, nHeight/4, fmt);
if(pImageTmp==NULL)
{
pImageTmp = new QImage(nWidth, nHeight, fmt);
}
else
{
if(pImageTmp->width()!=nWidth || pImageTmp->height()!=nHeight || pImageTmp->format()!=fmt)
{
SAFE_DELETE(pImageTmp);
pImageTmp = new QImage(nWidth, nHeight, fmt);
}
}
{
uint8_t* pImageData = pImageTmp->bits();
memcpy(pImageData, pImageHistory->m_pImageData, nWidth*nHeight*3);
//
QImage imgSmall = pImageTmp->scaled(nWidth/4, nHeight/4);
*pImageNew->m_pImageSmall = imgSmall.copy();
SAFE_ARRAY_DELETE(pImageNew->m_pImageCaptureRaw);
SAFE_ARRAY_DELETE(pImageNew->m_pImageCaptureColor);
imgSmall.detach();
}
bool bTest = true;
if(bTest==true)
{
//CAPTURE_IMAGE* pImageNew = AddCaptureImage(pImageOri->bits(), nWidth, nHeight, pImageHistory->m_nType);
pImageNew->m_DateTime = dtCapture;//QDateTime::currentDateTime();
pImageNew->m_nType = (DISPLAY_TYPE)nType;
pImageNew->m_strImageFilename = strFilename;
if(pImageNew->m_nType==DISPLAY_VIDEO)
{
pImageNew->m_strVideoFilename = strFilename;
pImageNew->m_strVideoFilename.replace(".bmp", MOVIE_FILE_EXTENSION);
pImageNew->m_strVideoFilename.replace(".jpg", MOVIE_FILE_EXTENSION);
pImageNew->m_strVideoFilename.replace(".png", MOVIE_FILE_EXTENSION);
}
pImageNew->m_bCheck = true;
pImageNew->m_nType = (DISPLAY_TYPE)nType;
pImageNew->m_bDelete = bDelete;
pImageNew->m_bSaveFile = true;
pImageNew->m_nIndex = i;
m_LockAddCapture.lock();
m_pListCaptureImage->push_back(pImageNew);
m_LockAddCapture.unlock();
}
}
SAFE_DELETE(pImageTmp);
m_LockAddHistory.unlock();
ClearHistoryImage();
}
vector<CAPTURE_IMAGE*>* CommonData::GetListCaptureImage()
{
m_LockAddCapture.lock();
return m_pListCaptureImage;
}
void CommonData::ReleaseListCaptureImage()
{
m_LockAddCapture.unlock();
}
void CommonData::ClearCaptureImage()
{
m_LockAddCapture.lock();
{
int i=0;
for(i=0 ; i<m_pListCaptureImage->size() ; i++)
{
CAPTURE_IMAGE* pCaptureImage = (*m_pListCaptureImage)[i];
if(pCaptureImage!=NULL)
{
if(pCaptureImage->m_pImage!=NULL)
{
//pCaptureImage->m_pImage->detach();
}
if(pCaptureImage->m_pImageSmall!=NULL)
{
//pCaptureImage->m_pImageSmall->detach();
}
SAFE_DELETE(pCaptureImage->m_pImage);
SAFE_DELETE(pCaptureImage->m_pImageSmall);
SAFE_ARRAY_DELETE(pCaptureImage->m_pImageCaptureRaw);
SAFE_ARRAY_DELETE(pCaptureImage->m_pImageCaptureColor);
SAFE_ARRAY_DELETE(pCaptureImage->m_pImageData);
SAFE_DELETE(pCaptureImage);
}
}
m_pListCaptureImage->clear();
//SAFE_DELETE(m_pListCaptureImage);
//m_pListCaptureImage = new vector<CAPTURE_IMAGE*>;
}
m_LockAddCapture.unlock();
}
CAPTURE_IMAGE* CommonData::AddCaptureImage(uint8_t* pData, int nWidth, int nHeight, int nCaptureType)
{
CAPTURE_IMAGE* pCaptureImage = NULL;
m_LockAddCapture.lock();
{
pCaptureImage = new CAPTURE_IMAGE;
pCaptureImage->m_DateTime = QDateTime::currentDateTime();
pCaptureImage->m_nType = (DISPLAY_TYPE)nCaptureType;
if(nWidth>0 && nHeight>0 && pData!=NULL)
{
pCaptureImage->m_pImageCaptureRaw = NULL;
pCaptureImage->m_pImageCaptureRaw = new uint8_t[nWidth*nHeight*2];
memset(pCaptureImage->m_pImageCaptureRaw, 0, sizeof(uint8_t)*nWidth*nHeight*2);
memcpy(pCaptureImage->m_pImageCaptureRaw, pData, sizeof(uint8_t)*nWidth*nHeight*2);
}
else
{
pCaptureImage->m_pImageCaptureRaw = NULL;
if(nWidth>0 && nHeight>0)
{
pCaptureImage->m_pImageCaptureRaw = new uint8_t[nWidth*nHeight*2];
memset(pCaptureImage->m_pImageCaptureRaw, 0, sizeof(uint8_t)*nWidth*nHeight*2);
}
}
{
m_pListCaptureImage->push_back(pCaptureImage);
}
}
m_LockAddCapture.unlock();
return pCaptureImage;
}
uint8_t* CommonData::ConvertColor(uint8_t* pData, int nWidth, int nHeight)
{
int i=0;
int j=0;
for(i=0 ; i<nHeight ; i++)
{
int nIndex = 0;
for(j=0 ; j<nWidth/2 ; j++)
{
//UYVY
float fU = (float)pData[i*m_nVideoWidth*2+j*4+0] / 255.0f;
float fY1 = (float)pData[i*m_nVideoWidth*2+j*4+1] / 255.0f;
float fV = (float)pData[i*m_nVideoWidth*2+j*4+2] / 255.0f;
float fY2 = (float)pData[i*m_nVideoWidth*2+j*4+3] / 255.0f;
float fR = 0;
float fG = 0;
float fB = 0;
fY1=1.1643*(fY1-0.0625);
fY2=1.1643*(fY2-0.0625);
fU=fU-0.5;
fV=fV-0.5;
fR = CLAMP(fY1+1.5958*fV, 0.0, 1.0);
fG = CLAMP(fY1-0.39173*fU-0.81290*fV, 0.0, 1.0);
fB = CLAMP(fY1+2.017*fU, 0.0, 1.0);
m_pImageCapture[i*nWidth+nIndex].r = fR*255;
m_pImageCapture[i*nWidth+nIndex].g = fG*255;
m_pImageCapture[i*nWidth+nIndex].b = fB*255;
nIndex++;
fR = CLAMP(fY2+1.5958*fV, 0.0, 1.0);
fG = CLAMP(fY2-0.39173*fU-0.81290*fV, 0.0, 1.0);
fB = CLAMP(fY2+2.017*fU, 0.0, 1.0);
m_pImageCapture[i*nWidth+nIndex].r = fR*255;
m_pImageCapture[i*nWidth+nIndex].g = fG*255;
m_pImageCapture[i*nWidth+nIndex].b = fB*255;
nIndex++;
}
}
return (uint8_t*)m_pImageCapture;
}
void CommonData::ConvertColor2(uint8_t* pSrcData, uint8_t* pDestData, int nOffsetX, int nOffsetY, int nWidth, int nHeight)
{
int i=0;
int j=0;
RGB_Data* pColorData = (RGB_Data*)pDestData;
for(i=0 ; i<nHeight ; i++)
{
int nIndex = 0;
for(j=0 ; j<nWidth/2 ; j++)
{
//UYVY
float fU = (float)pSrcData[(i+nOffsetY)*m_nVideoWidth*2+(nOffsetX*2+j*4+0)] / 255.0f;
float fY1 = (float)pSrcData[(i+nOffsetY)*m_nVideoWidth*2+(nOffsetX*2+j*4+1)] / 255.0f;
float fV = (float)pSrcData[(i+nOffsetY)*m_nVideoWidth*2+(nOffsetX*2+j*4+2)] / 255.0f;
float fY2 = (float)pSrcData[(i+nOffsetY)*m_nVideoWidth*2+(nOffsetX*2+j*4+3)] / 255.0f;
float fR = 0;
float fG = 0;
float fB = 0;
fY1=1.1643*(fY1-0.0625);
fY2=1.1643*(fY2-0.0625);
fU=fU-0.5;
fV=fV-0.5;
fR = CLAMP(fY1+1.5958*fV, 0.0, 1.0);
fG = CLAMP(fY1-0.39173*fU-0.81290*fV, 0.0, 1.0);
fB = CLAMP(fY1+2.017*fU, 0.0, 1.0);
pColorData[i*nWidth+nIndex].r = fR*255;
pColorData[i*nWidth+nIndex].g = fG*255;
pColorData[i*nWidth+nIndex].b = fB*255;
nIndex++;
fR = CLAMP(fY2+1.5958*fV, 0.0, 1.0);
fG = CLAMP(fY2-0.39173*fU-0.81290*fV, 0.0, 1.0);
fB = CLAMP(fY2+2.017*fU, 0.0, 1.0);
pColorData[i*nWidth+nIndex].r = fR*255;
pColorData[i*nWidth+nIndex].g = fG*255;
pColorData[i*nWidth+nIndex].b = fB*255;
nIndex++;
}
}
}
QString CommonData::GetNewFilename(int nType)
{
QString strFile;
QDateTime dt = QDateTime::currentDateTime();
int nYear = dt.date().year();
int nMonth = dt.date().month();
int nDay = dt.date().day();
int nMaxIndex = 0;
QString strStorageDirectory = "/data";
QString strDirectoryImage;
QString strImageExtention;
ACQUISITION_INFO* pAcquisitionInfo = GetAcquisitionInfo();
if(nType==DISPLAY_IMAGE)
{
strDirectoryImage = QString("%1/image").arg(strStorageDirectory);
strImageExtention = m_strImageExtension;
nMaxIndex = (++pAcquisitionInfo->m_nAcquisitionImageMax);
}
else if(nType==DISPLAY_VIDEO)
{
strDirectoryImage = QString("%1/video").arg(strStorageDirectory);
strImageExtention = "mp4";
nMaxIndex = (++pAcquisitionInfo->m_nAcquisitionVideoMax);
}
SDATA_PATIENT* pPatientInfo = pAcquisitionInfo->GetPatientInfo();
QString strPatientID = pPatientInfo->strPatientID;
ReleaseAcquisitionInfo();
//QString strStorageDirectory = pMainWindow->GetStorageDirectory();
QString strDirectoryDate = QString("%1/%2%3%4").arg(strDirectoryImage).arg(QString::number(nYear).rightJustified(4, '0')).arg(QString::number(nMonth).rightJustified(2, '0'))
.arg(QString::number(nDay).rightJustified(2, '0'));
if(strPatientID.size()<1)
{
strPatientID = "unknown";
}
QString strDirectoryPatient = QString("%1/%2").arg(strDirectoryDate).arg(strPatientID);
uint captureTime = dt.toMSecsSinceEpoch();
QDir().mkdir(strDirectoryImage);
QDir().mkdir(strDirectoryDate);
QDir().mkdir(strDirectoryPatient);
vector<CAPTURE_IMAGE*>::iterator it;
strFile = QString("%1/%2_%3.%4").arg(strDirectoryPatient).arg(QString::number(nMaxIndex)).arg(QString::number(captureTime)).arg(strImageExtention);
m_LockAddCapture.lock();
int nCheckCount = -1;
for(it=m_pListCaptureImage->begin() ; it!=m_pListCaptureImage->end() ; ++it)
{
CAPTURE_IMAGE* pCheckImage = *it;
if(pCheckImage->m_strImageFilename==strFile)
{
nCheckCount++;
strFile = QString("%1/%2_%3_%4.%5").arg(strDirectoryPatient).arg(QString::number(nMaxIndex)).arg(QString::number(captureTime)).arg(QString::number(nCheckCount)).arg(strImageExtention);
}
}
m_LockAddCapture.unlock();
return strFile;
}
bool CommonData::ConvertCaptureImage(CAPTURE_IMAGE* pCaptureImage, int nWidth, int nHeight)
{
int i=0;
int j=0;
pCaptureImage->m_bSaveFile = false;
if(pCaptureImage->m_pImageCaptureRaw==NULL)
{
pCaptureImage->m_pImageCaptureRaw = new uint8_t[m_nVideoWidth*m_nVideoHeight*2];
}
uint8_t* pData = pCaptureImage->m_pImageCaptureRaw;
memset(m_pImageCapture, 0, sizeof(RGB_Data)*m_nVideoWidth*m_nVideoHeight);
for(i=0 ; i<nHeight ; i++)
{
int nIndex = 0;
for(j=0 ; j<nWidth/2 ; j++)
{
//UYVY
float fU = (float)pData[i*nWidth*2+j*4+0] / 255.0f;
float fY1 = (float)pData[i*nWidth*2+j*4+1] / 255.0f;
float fV = (float)pData[i*nWidth*2+j*4+2] / 255.0f;
float fY2 = (float)pData[i*nWidth*2+j*4+3] / 255.0f;
/*
//YUY2
float fY1 = (float)pData[i*nWidth*2+j*4+0] / 255.0f;
float fU = (float)pData[i*nWidth*2+j*4+1] / 255.0f;
float fY2 = (float)pData[i*nWidth*2+j*4+2] / 255.0f;
float fV = (float)pData[i*nWidth*2+j*4+3] / 255.0f;
*/
float fR = 0;
float fG = 0;
float fB = 0;
fY1=1.1643*(fY1-0.0625);
fY2=1.1643*(fY2-0.0625);
fU=fU-0.5;
fV=fV-0.5;
fR = CLAMP(fY1+1.5958*fV, 0.0, 1.0);
fG = CLAMP(fY1-0.39173*fU-0.81290*fV, 0.0, 1.0);
fB = CLAMP(fY1+2.017*fU, 0.0, 1.0);
m_pImageCapture[i*nWidth+nIndex].b = fR*255;
m_pImageCapture[i*nWidth+nIndex].g = fG*255;
m_pImageCapture[i*nWidth+nIndex].r = fB*255;
nIndex++;
fR = CLAMP(fY2+1.5958*fV, 0.0, 1.0);
fG = CLAMP(fY2-0.39173*fU-0.81290*fV, 0.0, 1.0);
fB = CLAMP(fY2+2.017*fU, 0.0, 1.0);
m_pImageCapture[i*nWidth+nIndex].b = fR*255;
m_pImageCapture[i*nWidth+nIndex].g = fG*255;
m_pImageCapture[i*nWidth+nIndex].r = fB*255;
nIndex++;
}
}
SAFE_ARRAY_DELETE(pCaptureImage->m_pImageCaptureRaw);
SAFE_ARRAY_DELETE(pCaptureImage->m_pImageCaptureColor);
QString strFile = GetNewFilename(DISPLAY_IMAGE);
pCaptureImage->m_bCheck = true;
pCaptureImage->m_strImageFilename = strFile;
ACQUISITION_INFO* pAcquisitionInfo = GetAcquisitionInfo();
{
if(pCaptureImage->m_nType==DISPLAY_VIDEO)
{
QString strVideo = pCaptureImage->m_strVideoFilename;
QString strImageExtention = m_strImageExtension;
if(strVideo.size()==0)
{
strVideo = GetNewFilename(DISPLAY_VIDEO);
pCaptureImage->m_strVideoFilename = strVideo;
}
strFile = strVideo.replace("mp4", strImageExtention);
pCaptureImage->m_strImageFilename = strFile;
pCaptureImage->m_nAcquisitionNumber = pAcquisitionInfo->m_nAcquisitionVideoMax;
}
else
{
pCaptureImage->m_nAcquisitionNumber = pAcquisitionInfo->m_nAcquisitionImageMax;
}
}
ReleaseAcquisitionInfo();
bool bCreateBitmapFile = false;
for(i=0 ; i<10 && bCreateBitmapFile==false ; i++)
{
if(m_strImageExtension=="bmp")
{
bCreateBitmapFile = WriteBitmapFile(pCaptureImage->m_strImageFilename, (uint8_t*)m_pImageCapture, nWidth, nHeight);
}
else if(m_strImageExtension=="jpg")
{
bCreateBitmapFile = WriteJPEG(pCaptureImage->m_strImageFilename, (uint8_t*)m_pImageCapture, nWidth, nHeight, 100);
}
if(bCreateBitmapFile==false)
{
usleep(1000*10);
}
}
//bCreateBitmapFile = false;
if(bCreateBitmapFile==false)
{
MainWindow* pMainWindow = MainWindow::GetMainWindow();
pMainWindow->SetDisplayError(0x04);
return false;
}
pCaptureImage->m_bSaveFile = true;
pCaptureImage->m_pImage = new QImage(pCaptureImage->m_strImageFilename);
if(m_nCropMode==true)
{
int nSaveWidth = 1376;
int nSaveHeight = 992;
*pCaptureImage->m_pImage = pCaptureImage->m_pImage->copy(QRect(242, 5, nSaveWidth, nSaveHeight));
pCaptureImage->m_pImageSmall = new QImage(nSaveWidth/4, nSaveHeight/4, pCaptureImage->m_pImage->format());
*pCaptureImage->m_pImageSmall = pCaptureImage->m_pImage->scaled(pCaptureImage->m_pImage->width()/4, pCaptureImage->m_pImage->height()/4, Qt::IgnoreAspectRatio, Qt::SmoothTransformation).copy();
}
else
{
QImage image = pCaptureImage->m_pImage->scaled(nWidth/4, nHeight/4, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
pCaptureImage->m_pImageSmall = new QImage(nWidth/4, nHeight/4, image.format());
*pCaptureImage->m_pImageSmall = image.copy();
}
pAcquisitionInfo = GetAcquisitionInfo();
if(pAcquisitionInfo->GetPatientInfo()->strPatientID.length() > 0 &&
pAcquisitionInfo->GetPatientInfo()->strPatientName.length() >0)
{
pAcquisitionInfo->m_strImageFilename = pCaptureImage->m_strImageFilename;
pAcquisitionInfo->m_strVideoFilename = pCaptureImage->m_strVideoFilename;
// 1. 이 로직 블록에서만 사용할 DB 인스턴스를 지역 변수로 생성
SUTIL::SDatabase db("ConvertCaptureImage_Connection");
if (db.OpenDatabase("/home/birdhead/test.db") == 0) // 0이 성공
{
// 2. 지역 인스턴스 'db'를 사용하여 함수 호출
if(pCaptureImage->m_nType==DISPLAY_IMAGE)
{
db.InsertImage(pAcquisitionInfo);
}
else if(pCaptureImage->m_nType==DISPLAY_VIDEO)
{
db.InsertVideo(pAcquisitionInfo);
}
}
else
{
qWarning() << "DB open failed in ConvertCaptureImage";
}
// 이 블록이 끝나면 'db' 객체는 자동으로 소멸되어 커넥션이 정리됩니다.
}
ReleaseAcquisitionInfo();
usleep(100);
return true;
}
void CommonData::ConvertCaptureImageRGBA(CAPTURE_IMAGE* pCaptureImage, int nWidth, int nHeight)
{
//uint8_t* pData = pCaptureImage->m_pImageCaptureRaw;
//int nYear = pCaptureImage->m_DateTime.date().year();
//int nMonth = pCaptureImage->m_DateTime.date().month();
//int nDay = pCaptureImage->m_DateTime.date().day();
//int nHour = pCaptureImage->m_DateTime.time().hour();
//int nMinute = pCaptureImage->m_DateTime.time().minute();
//int nSec = pCaptureImage->m_DateTime.time().second();
//QString strStorageDirectory = GetStorageDirectory();
//QString strDirectoryImage = QString("%1").arg(strStorageDirectory);
//QString strPatientID = "123";
QString strImageExtention = m_strImageExtension;
pCaptureImage->m_pImage = new QImage((uchar*)pCaptureImage->m_pImageCaptureRaw, nWidth, nHeight, QImage::Format_RGB32);
*pCaptureImage->m_pImage = pCaptureImage->m_pImage->convertToFormat(QImage::Format_RGB888);
*pCaptureImage->m_pImage = pCaptureImage->m_pImage->rgbSwapped();
//QString strFile = QString("%1/%2%3%4.%5").arg(strDirectoryImage).arg(QString::number(nHour).rightJustified(2, '0')).arg(QString::number(nMinute).rightJustified(2, '0')).arg(QString::number(nSec).rightJustified(2, '0')).arg(strImageExtention);
QString strFile = GetNewFilename(DISPLAY_IMAGE);
{
/*
vector<CAPTURE_IMAGE*>::iterator it;
int nCheckCount = -1;
for(it=m_pListCaptureImage->begin() ; it!=m_pListCaptureImage->end() ; ++it)
{
CAPTURE_IMAGE* pCheckImage = *it;
if(pCheckImage->m_strImageFilename==strFile)
{
nCheckCount++;
strFile = QString("%1/%2%3%4_%5.%6").arg(strDirectoryImage).arg(QString::number(nHour).rightJustified(2, '0')).arg(QString::number(nMinute).rightJustified(2, '0')).arg(QString::number(nSec).rightJustified(2, '0')).arg(QString::number(nCheckCount)).arg(strImageExtention);
}
}
*/
}
pCaptureImage->m_strImageFilename = strFile;
if(pCaptureImage->m_nType==DISPLAY_VIDEO)
{
QString strVideo = strFile;
strVideo = strVideo.replace(strImageExtention, "mp4");
pCaptureImage->m_strVideoFilename = strVideo;
}
pCaptureImage->m_bSaveFile = false;
m_pThreadCaptureImage->AddCaptureSaveToFile(pCaptureImage);
QImage image = pCaptureImage->m_pImage->scaled(nWidth/4, nHeight/4, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
pCaptureImage->m_pImageSmall = new QImage(nWidth/4, nHeight/4, image.format());
*pCaptureImage->m_pImageSmall = image;
SAFE_ARRAY_DELETE(pCaptureImage->m_pImageCaptureRaw);
// 1. Mutex를 사용하는 Get/Release 함수로 안전하게 공유 데이터에 접근
ACQUISITION_INFO* pAcquisitionInfo = GetAcquisitionInfo();
if(pAcquisitionInfo->GetPatientInfo()->strPatientID.length() > 0 &&
pAcquisitionInfo->GetPatientInfo()->strPatientName.length() >0)
{
pAcquisitionInfo->m_strImageFilename = pCaptureImage->m_strImageFilename;
pAcquisitionInfo->m_strVideoFilename = pCaptureImage->m_strVideoFilename;
// 2. 지역 DB 인스턴스 생성 및 사용
SUTIL::SDatabase db("ConvertRGBA_Connection");
if (db.OpenDatabase("/home/birdhead/test.db") == 0) // 0이 성공
{
if(pCaptureImage->m_nType==DISPLAY_IMAGE)
{
db.InsertImage(pAcquisitionInfo);
}
else if(pCaptureImage->m_nType==DISPLAY_VIDEO)
{
db.InsertVideo(pAcquisitionInfo);
}
}
else
{
qWarning() << "DB open failed in ConvertCaptureImageRGBA";
}
}
ReleaseAcquisitionInfo(); // 3. 접근이 끝난 후 반드시 Release 호출
usleep(10*1000);
}
/*
SDatabase* CommonData::GetDatabase()
{
m_LockDatabase.lock();
return m_pDatabase;
}
void CommonData::ReleaseDatabase()
{
m_LockDatabase.unlock();
}
*/
ACQUISITION_INFO* CommonData::GetAcquisitionInfo()
{
m_LockAcquisitionInfo.lock();
return &m_AcquisitionInfo;
}
void CommonData::ReleaseAcquisitionInfo()
{
m_LockAcquisitionInfo.unlock();
}
vector<ImageSelect*>* CommonData::GetListHistoryImage()
{
m_LockAddHistory.lock();
return m_pListHistoryImage;
}
void CommonData::ReleaseListHistoryImage()
{
m_LockAddHistory.unlock();
}
void CommonData::ClearHistoryImage()
{
m_LockAddHistory.lock();
int i=0;
for(i=0 ; i<m_pListHistoryImage->size() ; i++)
{
ImageSelect* pHistoryImage = (*m_pListHistoryImage)[i];
if(pHistoryImage!=NULL)
{
SAFE_ARRAY_DELETE(pHistoryImage->m_pImageData);
}
SAFE_DELETE(pHistoryImage);
}
m_pListHistoryImage->clear();
SAFE_DELETE(m_pListHistoryImage);
m_pListHistoryImage = new vector<ImageSelect*>;
m_LockAddHistory.unlock();
}
vector<HISTORY_STUDY*>* CommonData::GetHistorySearchResult()
{
return m_pListHistorySearch;
}
void CommonData::ClearHistorySearchResult()
{
m_LockCurrentHistoryStudy.lock();
int i=0;
for(i=0 ; i<m_pListHistorySearch->size() ; i++)
{
HISTORY_STUDY* pHistoryStudy = (*m_pListHistorySearch)[i];
SAFE_DELETE(pHistoryStudy);
}
m_pListHistorySearch->clear();
m_pCurrentHistoryStudy = NULL;
m_LockCurrentHistoryStudy.unlock();
}
HISTORY_STUDY* CommonData::GetCurrentHistoryStudy()
{
m_LockCurrentHistoryStudy.lock();
return m_pCurrentHistoryStudy;
}
void CommonData::ReleaseCurrentHistoryStudy()
{
m_LockCurrentHistoryStudy.unlock();
}
void CommonData::SetCurrentHistoryStudy(int nIndex)
{
m_LockCurrentHistoryStudy.lock();
if(nIndex < m_pListHistorySearch->size())
{
m_pCurrentHistoryStudy = (*m_pListHistorySearch)[nIndex];
}
else
{
m_pCurrentHistoryStudy = NULL;
}
m_LockCurrentHistoryStudy.unlock();
}
bool CommonData::IsEncodingVideo()
{
return m_bVideoEncoding;
}
void CommonData::SetEncodingVideo(bool bEncoding)
{
m_bVideoEncoding = bEncoding;
}
STableHeader* CommonData::GetWorklistTableHeader()
{
return m_pWorklistTableHeader;
}
STableHeader* CommonData::GetHistoryTableHeader()
{
return m_pHistoryTableHeader;
}
void CommonData::Exit()
{
if(m_pRTSPThread!=NULL)
{
m_pRTSPThread->ChangeState(1000);
while(m_pRTSPThread->isRunning()==true)
{
usleep(10*1000);
}
m_pRTSPThread->stop();
}
if(m_pThreadCaptureImage!=NULL)
{
m_pThreadCaptureImage->ChangeState(1000);
while(m_pThreadCaptureImage->isRunning()==true)
{
usleep(10*1000);
}
}
}
int CommonData::GetDisplayType()
{
return m_nDisplayType;
}
void CommonData::SetDisplayType(int nType)
{
m_nDisplayType = nType;
}
SDCMWorklist* CommonData::GetWorklistClass()
{
return m_pDCMWorklist;
}
#define pp pair<int, int>
bool cmp(const pp& a, const pp& b)
{
//if(a.second==b.second) return a.first < b.first;
//return a.second < b.second;
return a.first > b.first;
}
void CommonData::InitWorklistIndex()
{
// 1. 함수 내에서 사용할 지역 DB 인스턴스 생성
SUTIL::SDatabase db("InitWorklist_Connection");
if (db.OpenDatabase("/home/birdhead/test.db") != 0) {
qWarning() << "DB Open Failed in InitWorklistIndex";
return;
}
// 2. 지역 인스턴스 'db'를 통해 함수 호출
QList<QStringList> result = db.QueryWorklistTableHeader();
m_pWorklistTableHeader->SetDataWorklist(result);
}
void CommonData::UpdateWorklistIndex()
{
// 1. 지역 DB 인스턴스 생성
SUTIL::SDatabase db("UpdateWorklist_Connection");
if (db.OpenDatabase("/home/birdhead/test.db") != 0) return;
// 2. 여러 UPDATE 작업을 하나의 트랜잭션으로 묶어 원자성을 보장
if (!db.BeginTransaction()) {
qWarning() << "Failed to begin transaction in UpdateWorklistIndex";
return;
}
bool bSuccess = true;
QString query = "UPDATE WorklistTableHeader SET DisplayIndex = ?, Visible = ? WHERE DefaultIndex = ?;";
vector<TableHeader*>* pListActivate = m_pWorklistTableHeader->GetListActive();
for(size_t i = 0; i < pListActivate->size() && bSuccess; ++i)
{
TableHeader* pHeader = (*pListActivate)[i];
pHeader->m_nIndex = i;
// 3. 파라미터 바인딩으로 안전하게 쿼리 실행
bSuccess = db.ExecuteNonQuery(query, {pHeader->m_nIndex, 1, pHeader->m_nIndexDefault});
}
vector<TableHeader*>* pListInactivate = m_pWorklistTableHeader->GetListInactive();
size_t nIndexOffset = pListActivate->size();
for(size_t i = 0; i < pListInactivate->size() && bSuccess; ++i)
{
TableHeader* pHeader = (*pListInactivate)[i];
pHeader->m_nIndex = nIndexOffset + i;
bSuccess = db.ExecuteNonQuery(query, {pHeader->m_nIndex, 0, pHeader->m_nIndexDefault});
}
// 4. 모든 작업이 성공했을 때만 Commit, 하나라도 실패하면 Rollback
if (bSuccess) {
db.Commit();
} else {
qWarning() << "UpdateWorklistIndex failed, rolling back transaction.";
db.Rollback();
}
}
void CommonData::InitHistoryIndex()
{
// 1. 함수 내에서 사용할 지역 DB 인스턴스 생성
SUTIL::SDatabase db("InitHistory_Connection");
if (db.OpenDatabase("/home/birdhead/test.db") != 0) {
qWarning() << "DB Open Failed in InitHistoryIndex";
return;
}
// 2. 지역 인스턴스 'db'를 통해 함수 호출
QList<QStringList> result = db.QueryHistoryTableHeader();
m_pHistoryTableHeader->SetDataHistory(result);
}
void CommonData::UpdateHistoryIndex()
{
// 1. 지역 DB 인스턴스 생성
SUTIL::SDatabase db("UpdateHistory_Connection");
if (db.OpenDatabase("/home/birdhead/test.db") != 0) return;
// 2. 트랜잭션 시작
if (!db.BeginTransaction()) {
qWarning() << "Failed to begin transaction in UpdateHistoryIndex";
return;
}
bool bSuccess = true;
QString query = "UPDATE HistoryTableHeader SET DisplayIndex = ?, Visible = ? WHERE DefaultIndex = ?;";
vector<TableHeader*>* pListActivate = m_pHistoryTableHeader->GetListActive();
for (size_t i = 0; i < pListActivate->size() && bSuccess; ++i)
{
TableHeader* pHeader = (*pListActivate)[i];
pHeader->m_nIndex = i;
// 3. 파라미터 바인딩으로 안전하게 쿼리 실행
bSuccess = db.ExecuteNonQuery(query, {pHeader->m_nIndex, 1, pHeader->m_nIndexDefault});
}
vector<TableHeader*>* pListInactivate = m_pHistoryTableHeader->GetListInactive();
size_t nIndexOffset = pListActivate->size();
for (size_t i = 0; i < pListInactivate->size() && bSuccess; ++i)
{
TableHeader* pHeader = (*pListInactivate)[i];
pHeader->m_nIndex = nIndexOffset + i;
bSuccess = db.ExecuteNonQuery(query, {pHeader->m_nIndex, 0, pHeader->m_nIndexDefault});
}
// 4. 성공/실패에 따른 Commit 또는 Rollback
if (bSuccess) {
db.Commit();
} else {
qWarning() << "UpdateHistoryIndex failed, rolling back transaction.";
db.Rollback();
}
}
SDCM_SERVER_INFO* CommonData::GetServerWorklistInfo()
{
m_LockServerWorklistInfo.lock();
return &m_ServerWorklistInfo;
}
void CommonData::ReleaseServerWorklistInfo()
{
m_LockServerWorklistInfo.unlock();
}
SDCM_SERVER_INFO* CommonData::GetServerStorageInfo()
{
m_LockServerStorageInfo.lock();
return &m_ServerStorageInfo;
}
void CommonData::ReleaseServerStorageInfo()
{
m_LockServerStorageInfo.unlock();
}
void CommonData::UpdateSetting()
{
SUTIL::SDatabase db("UpdateSetting_Connection");
if (db.OpenDatabase("/home/birdhead/test.db") != 0) return;
QString query = "UPDATE ConnectionInfo SET WorklistServerIP=?, WorklistPort=?, WorklistServerTitle=?, WorklistClientTitle=?, "
"StorageServerIP=?, StoragePort=?, StorageServerTitle=?, StorageClientTitle=?, Modality=?, "
"HospitalName=?, StationName=?, EnableLog=?, LocalImageFolder=?, LocalLogFolder=?, LocalHistoryFolder=? "
"WHERE ID=1";
QVariantList params;
params << m_ServerWorklistInfo.m_strServer_IP << m_ServerWorklistInfo.m_nServer_Port << m_ServerWorklistInfo.m_strServer_AETitle
<< m_ServerWorklistInfo.m_strClient_AETitle << m_ServerStorageInfo.m_strServer_IP << m_ServerStorageInfo.m_nServer_Port
<< m_ServerStorageInfo.m_strServer_AETitle << m_ServerStorageInfo.m_strClient_AETitle << m_strModality
<< m_strInstitutionName << m_strStationName << (m_bEnableLog ? "Enabled" : "Disabled")
<< m_strLocalImageFolder << m_strLogFolder << m_strLocalHistoryFolder;
db.ExecuteNonQuery(query, params);
}
void CommonData::UpdateAdvancedSetting()
{
SUTIL::SDatabase db("UpdateAdvancedSetting_Connection");
if (db.OpenDatabase("/home/birdhead/test.db") != 0) return;
QString query = "UPDATE AdvancedSetting SET EnableNetworkShare=?, NetworkShareIP=?, NetworkShareFolder=?, NetworkShareID=?, NetworkSharePassword=?, "
"NetworkSMBVersion=?, NetworkAutoSend=?, AutoExitCaptureSendDICOM=?, AutoCaptureSendDICOM=?, AutoVideoCapture=?, "
"DICOMCharacterSet=?, AutoCloseSendFinish=?, AutoLogin=?, DICOMCompress=?, VideoMode=?, CropMode=?, "
"UseFixWidthLevel=?, UseLogLevel=?, ScreenSaverTime=?, USBBackup=? WHERE ID=1";
QVariantList params;
params << (m_NetworkShareInfo.m_bEnable ? "Enabled" : "Disabled")
<< m_NetworkShareInfo.m_strIP << m_NetworkShareInfo.m_strShareFolder << m_NetworkShareInfo.m_strID
<< m_NetworkShareInfo.m_strPassword << m_NetworkShareInfo.m_strVersion
<< (m_NetworkShareInfo.m_bAutoSend ? "Enabled" : "Disabled")
<< m_bAutoExitCaptureSendDICOM << m_bAutoCaptureSendDICOM << m_bAutoVideoCapture
<< m_strDICOMCharacterSet << m_bAutoCloseSendFinish << m_bAutoLogin << m_nTransferSyntax
<< m_nVideoMode << m_nCropMode << m_nUseFixWidthLevel << m_nUseLogLevel
<< m_nScreenSaverTime << m_nUseUSBBackup;
db.ExecuteNonQuery(query, params);
if(m_nUseLogLevel==0)
{
if(m_pLogFile!=NULL)
{
m_pLogFile->flush();
m_pLogFile->close();
SAFE_DELETE(m_pLogFile);
}
}
}
void CommonData::InitSetting()
{
SUTIL::SDatabase db("InitSetting_Connection");
if (db.OpenDatabase("/home/birdhead/test.db") != 0) {
qWarning() << "Database connection failed for InitSetting.";
return;
}
// QSqlQuery를 직접 사용하여 컬럼 이름으로 안전하게 파싱
QSqlDatabase qdb = QSqlDatabase::database(db.connectionName()); // 내부 QSqlDatabase 객체 가져오기
QSqlQuery query(qdb);
// 1. ConnectionInfo 테이블 조회
if (query.exec("SELECT * FROM ConnectionInfo WHERE ID = 1") && query.next()) {
QSqlRecord rec = query.record();
m_ServerWorklistInfo.m_strServer_IP = rec.value("WorklistServerIP").toString();
m_ServerWorklistInfo.m_nServer_Port = rec.value("WorklistPort").toInt();
m_ServerWorklistInfo.m_strServer_AETitle = rec.value("WorklistServerTitle").toString();
m_ServerWorklistInfo.m_strClient_AETitle = rec.value("WorklistClientTitle").toString();
m_ServerStorageInfo.m_strServer_IP = rec.value("StorageServerIP").toString();
m_ServerStorageInfo.m_nServer_Port = rec.value("StoragePort").toInt();
m_ServerStorageInfo.m_strServer_AETitle = rec.value("StorageServerTitle").toString();
m_ServerStorageInfo.m_strClient_AETitle = rec.value("StorageClientTitle").toString();
m_strModality = rec.value("Modality").toString();
m_strInstitutionName = rec.value("HospitalName").toString();
m_strStationName = rec.value("StationName").toString();
m_bEnableLog = (rec.value("EnableLog").toString() == "Enabled");
m_strLocalImageFolder = rec.value("LocalImageFolder").toString();
m_strLogFolder = rec.value("LocalLogFolder").toString();
m_strLocalHistoryFolder = rec.value("LocalHistoryFolder").toString();
}
// 2. AdvancedSetting 테이블 조회
if (query.exec("SELECT * FROM AdvancedSetting WHERE ID = 1") && query.next()) {
QSqlRecord rec = query.record();
m_NetworkShareInfo.m_bEnable = (rec.value("EnableNetworkShare").toString() == "Enabled");
m_NetworkShareInfo.m_strIP = rec.value("NetworkShareIP").toString();
m_NetworkShareInfo.m_strShareFolder = rec.value("NetworkShareFolder").toString();
m_NetworkShareInfo.m_strID = rec.value("NetworkShareID").toString();
m_NetworkShareInfo.m_strPassword = rec.value("NetworkSharePassword").toString();
m_NetworkShareInfo.m_strVersion = rec.value("NetworkSMBVersion").toString();
m_NetworkShareInfo.m_bAutoSend = (rec.value("NetworkAutoSend").toString() == "Enabled");
m_bAutoExitCaptureSendDICOM = rec.value("AutoExitCaptureSendDICOM").toBool();
m_bAutoCaptureSendDICOM = rec.value("AutoCaptureSendDICOM").toBool();
m_bAutoVideoCapture = rec.value("AutoVideoCapture").toBool();
m_strDICOMCharacterSet = rec.value("DICOMCharacterSet").toString();
m_bAutoCloseSendFinish = rec.value("AutoCloseSendFinish").toBool();
m_bAutoLogin = rec.value("AutoLogin").toBool();
m_nTransferSyntax = rec.value("DICOMCompress").toInt();
m_nVideoMode = rec.value("VideoMode").toInt();
m_nCropMode = rec.value("CropMode").toInt();
m_nUseFixWidthLevel = rec.value("UseFixWidthLevel").toInt();
m_nUseLogLevel = rec.value("UseLogLevel").toInt();
m_nScreenSaverTime = rec.value("ScreenSaverTime").toInt();
m_nUseUSBBackup = rec.value("USBBackup").toInt();
}
SetVideoMode(m_nVideoMode);
SetCropMode(m_nCropMode);
SetUseFixWidthLevel(m_nUseFixWidthLevel);
SetLogLevel(m_nUseLogLevel);
SetScreenSaverTime(m_nScreenSaverTime);
SetUseUSBBackup(m_nUseUSBBackup);
if(m_nUseLogLevel>0)
{
if(m_pLogFile==NULL)
{
QDir().mkdir("Log");
QString strLogFile = QString("Log/%1.log").arg(QDateTime::currentDateTime().toString("yyyyMMdd_HHmmss"));
m_pLogFile = new QFile(strLogFile);
m_pLogFile->open(QFile::ReadWrite | QFile::Unbuffered);
}
}
//test code
//m_bAutoExitCaptureSendDICOM = true;
//m_bAutoVideoCapture = true;
m_pDCMWorklist->SetWorklistInfo(m_ServerWorklistInfo.m_strServer_IP, QString::number(m_ServerWorklistInfo.m_nServer_Port), m_ServerWorklistInfo.m_strServer_AETitle, m_ServerWorklistInfo.m_strClient_AETitle);
}
QString CommonData::GetModality()
{
return m_strModality;
}
QString CommonData::GetInstitutionName()
{
return m_strInstitutionName;
}
QString CommonData::GetStationName()
{
return m_strStationName;
}
int CommonData::GetTransferSyntax()
{
return m_nTransferSyntax;
}
void CommonData::SetModality(QString strModality)
{
m_strModality = strModality;
}
void CommonData::SetInstitutionName(QString strInstitutionName)
{
m_strInstitutionName = strInstitutionName;
}
void CommonData::SetStationName(QString strStationName)
{
m_strStationName = strStationName;
}
void CommonData::SetTransferSyntax(int nTransferSyntax)
{
m_nTransferSyntax = nTransferSyntax;
}
bool CommonData::GetEnableLog()
{
return m_bEnableLog;
}
QString CommonData::GetLocalImageFolder()
{
return m_strLocalImageFolder;
}
QString CommonData::GetLogFolder()
{
return m_strLogFolder;
}
QString CommonData::GetLocalHistoryFolder()
{
return m_strLocalHistoryFolder;
}
void CommonData::SetEnableLog(int bEnable)
{
m_bEnableLog = bEnable;
}
void CommonData::SetLocalImageFolder(QString strLocalImageFolder)
{
m_strLocalImageFolder = strLocalImageFolder;
}
void CommonData::SetLogFolder(QString strLogFolder)
{
m_strLogFolder = strLogFolder;
}
void CommonData::SetLocalHistoryFolder(QString strLocalHistoryFolder)
{
m_strLocalHistoryFolder = strLocalHistoryFolder;
}
void CommonData::Beep(bool bSound)
{
if(m_nGPIO_Buzzer<=0)
{
return;
}
if(bSound==true)
{
m_bIsCapturing = true;
if(write(m_nGPIO_Buzzer, "1", 1) != 1)
{
}
}
else
{
m_bIsCapturing = false;
if(write(m_nGPIO_Buzzer, "0", 1) != 1)
{
}
}
}
int CommonData::GetHandSwitchValue()
{
char cRead = 0;
int nReadCount = 0;
if(m_nGPIO_HandSwitch>0)
{
nReadCount = read(m_nGPIO_HandSwitch, &cRead, sizeof(char));
}
if(nReadCount==0)
{
close(m_nGPIO_HandSwitch);
//m_nGPIO_HandSwitch = open("/sys/class/gpio/gpio271/value", O_RDONLY);
m_nGPIO_HandSwitch = open(m_strGPIOHandSwitch.toUtf8(), O_RDONLY);
}
if(m_nGPIO_HandSwitch==-1)
{
qDebug() << "271 Open Failed";
}
else
{
//qDebug() << "271 Open success";
nReadCount = read(m_nGPIO_HandSwitch, &cRead, sizeof(char));
if(nReadCount>0)
{
//qDebug() << cRead;
if(cRead=='1')
{
return 1;
}
return 0;
}
//close(m_nGPIO_HandSwitch);
}
//m_nGPIO_HandSwitch = 0;
return -1;
}
bool CommonData::IsCapturing()
{
return m_bIsCapturing;
}
WorklistResponseData CommonData::GetCurrentHistoryWorklistData()
{
WorklistResponseData rd;
//rd.m_Patient = m_pCurrentHistoryStudy->pStrPatientName->toStdString().c_str();
rd.m_Patient.strPatientID = m_pCurrentHistoryStudy->pStrPatientID->toStdString().c_str();
rd.m_Patient.strPatientName = m_pCurrentHistoryStudy->pStrPatientName->toStdString().c_str();
rd.m_Patient.strPatientWeight = m_pCurrentHistoryStudy->pStrPatientWeight->toStdString().c_str();
rd.m_Patient.strPatientSex = m_pCurrentHistoryStudy->pStrPatientSex->toStdString().c_str();
rd.m_Patient.strPatientBirthDate = m_pCurrentHistoryStudy->pStrPatientBirthDate->toStdString().c_str();
rd.m_Study.strStudyInstanceUID = m_pCurrentHistoryStudy->pStrStudyInstanceUID->toStdString().c_str();
rd.m_Study.strStudyDescription = m_pCurrentHistoryStudy->pStrStudyDescription->toStdString().c_str();
rd.m_Study.strStudyDate = m_pCurrentHistoryStudy->pStrStudyDate->toStdString().c_str();
rd.m_Study.strStudyTime = m_pCurrentHistoryStudy->pStrStudyTime->toStdString().c_str();
rd.m_ScheduledData.strScheduledCodeValue = m_pCurrentHistoryStudy->pStrStudyCodeValue->toStdString().c_str();
rd.m_Study.strReferringPhysiciansName = m_pCurrentHistoryStudy->pStrReferringPhysiciansName->toStdString().c_str();
rd.m_Study.strAccessionNumber = m_pCurrentHistoryStudy->pStrAccessionNumber->toStdString().c_str();
rd.m_Series.strSeriesInstanceUID = m_pCurrentHistoryStudy->pStrSeriesInstanceUID->toStdString().c_str();
rd.m_Series.strSeriesDescription = m_pCurrentHistoryStudy->pStrSeriesDescription->toStdString().c_str();
rd.m_Series.strModality = m_pCurrentHistoryStudy->pStrModality->toStdString().c_str();
rd.m_Series.strSeriesDate = m_pCurrentHistoryStudy->pStrSeriesDate->toStdString().c_str();
rd.m_Series.strSeriesTime = m_pCurrentHistoryStudy->pStrSeriesTime->toStdString().c_str();
//rd.m_Series.strBodyPartExamined;
rd.m_Series.strOperatorsName = m_pCurrentHistoryStudy->pStrOperatorsName->toStdString().c_str();
return rd;
}
WorklistResponseData CommonData::GetCurrentWorklistData()
{
WorklistResponseData rd;
m_LockAcquisitionInfo.lock();
rd.m_Patient = *m_AcquisitionInfo.GetPatientInfo();
rd.m_Study = *m_AcquisitionInfo.GetStudyInfo();
rd.m_Series = *m_AcquisitionInfo.GetSeriesInfo();
rd.m_Image = *m_AcquisitionInfo.GetImageInfo();
rd.m_ScheduledData = *m_AcquisitionInfo.GetScheduledDataInfo();
return rd;
}
void CommonData::ReleaseCurrentWorklistData()
{
m_LockAcquisitionInfo.unlock();
}
qint64 CommonData::ComputeStorageSize()
{
m_nStorageFreeSize = 0;
m_nStorageSize = 0;
foreach (const QStorageInfo &storage, QStorageInfo::mountedVolumes()) {
QString strRootPath = storage.rootPath();
qDebug() << strRootPath;
if(strRootPath=="/data")
{
if (storage.isReadOnly())
qDebug() << "isReadOnly:" << storage.isReadOnly();
qDebug() << "name:" << storage.name();
qDebug() << "fileSystemType:" << storage.fileSystemType();
qDebug() << "size:" << storage.bytesTotal()/1000/1000 << "MB";
qDebug() << "availableSize:" << storage.bytesAvailable()/1000/1000 << "MB";
m_nStorageFreeSize = storage.bytesAvailable();
m_nStorageSize = storage.bytesTotal();
}
}
return m_nStorageSize;
QString strDirectory = "/data";
QFileInfo pathInfo(strDirectory);
if(pathInfo.isDir()==false)
{
return 0;
}
QDirIterator it(strDirectory, QDirIterator::Subdirectories);
qint64 total = 0;
while(it.hasNext()==true)
{
it.next();
QFileInfo fi = it.fileInfo();
if(fi.isFile()==true && fi.isSymLink()==false && fi.isAbsolute()==true)
{
total += fi.size();
}
}
qDebug() << "/data size: " << total;
m_nStorageSize = total;
return total;
}
int CommonData::GetStorageSize()
{
return (int)(m_nStorageSize/(1000*1000));
}
int CommonData::GetStorageFreeSize()
{
return (int)(m_nStorageFreeSize/(1000*1000));
}
vector<QString>* CommonData::GetExportList()
{
return &m_ListExport;
}
QString* CommonData::GetExternalDiskPath()
{
return &m_strExternalDiskPath;
}
QString* CommonData::GetImageExtension()
{
return &m_strImageExtension;
}
void CommonData::SetSearchItemHistory(SEARCH_ITEM si)
{
m_SearchItemHistory = si;
}
void CommonData::SetHistorySearchStudyIndex(int nStudyIndex)
{
m_nSearchItemHistoryStudyIndex = nStudyIndex;
}
SEARCH_ITEM* CommonData::GetSearchItemHistory()
{
return &m_SearchItemHistory;
}
int CommonData::GetHistorySearchStudyIndex()
{
return m_nSearchItemHistoryStudyIndex;
}
void CommonData::ClearHistorySearchItem()
{
m_SearchItemHistory.Clear();
}
void CommonData::ClearHistorySearchStudyIndex()
{
m_nSearchItemHistoryStudyIndex = -1;
}
bool CommonData::IsAutoCloseSendFinish()
{
return m_bAutoCloseSendFinish;
}
bool CommonData::IsAutoLogin()
{
return m_bAutoLogin;
}
void CommonData::SetAutoLogin(bool bEnable)
{
m_bAutoLogin = bEnable;
}
QString CommonData::GetBeepGPIONumber()
{
return m_strGPIOBeep;
}
QString CommonData::GetHandswitchGPIONumber()
{
return m_strGPIOHandSwitch;
}
bool CommonData::IsActiveDetect()
{
return m_bActiveDetect;
}
void CommonData::SetActiveDetect(bool bActive)
{
m_bActiveDetect = bActive;
}
void CommonData::SetUseNetworkBackupVideo(bool bUse)
{
m_NetworkShareInfo.m_bEnable = bUse;
}
bool CommonData::IsUseNetworkBackupVideo()
{
return m_NetworkShareInfo.m_bEnable;
}
NetworkShareInfo* CommonData::GetNetworkShareInfo()
{
return &m_NetworkShareInfo;
}
bool CommonData::IsAutoExitCaptureSendDICOM()
{
return m_bAutoExitCaptureSendDICOM;
}
bool CommonData::IsAutoCaptureSendDICOM()
{
return m_bAutoCaptureSendDICOM;
}
bool CommonData::IsAutoVideoCapture()
{
return m_bAutoVideoCapture;
}
void CommonData::SetAutoExitCaptureSendDICOM(bool bEnable)
{
m_bAutoExitCaptureSendDICOM = bEnable;
}
void CommonData::SetAutoCaptureSendDICOM(bool bEnable)
{
m_bAutoCaptureSendDICOM = bEnable;
}
void CommonData::SetAutoVideoCapture(bool bEnable)
{
m_bAutoVideoCapture = bEnable;
}
SambaClient* CommonData::GetSambaClient()
{
return m_pSambaClient;
}
void CommonData::CreateSambaClient()
{
m_pSambaClient = new SambaClient;
}
QString CommonData::GetDICOMCharacterSet()
{
return m_strDICOMCharacterSet;
}
void CommonData::SetDICOMCharacterSet(QString strCharacterSet)
{
m_strDICOMCharacterSet = strCharacterSet;
}
void CommonData::SetAutoCloseSendComplete(bool bEnable)
{
m_bAutoCloseSendFinish = bEnable;
}
void CommonData::WriteLog(QString strLog)
{
if(m_nUseLogLevel>0)
{
m_LockLog.lock();
m_ListLog.push_back(strLog);
m_LockLog.unlock();
}
}
void CommonData::WriteLogFile(QString strLog)
{
m_LockLog.lock();
if(m_pLogFile!=NULL)
{
if(m_pLogFile->exists()==true)
{
m_pLogFile->write(strLog.toStdString().c_str());
fsync(m_pLogFile->handle());
}
}
m_LockLog.unlock();
}
QStringList* CommonData::GetListLog()
{
m_LockLog.lock();
return &m_ListLog;
}
void CommonData::ReleaseListLog()
{
m_LockLog.unlock();
}
void CommonData::SetVideoMode(int nMode)
{
nMode = 0;
m_nVideoMode = nMode;
if(m_nVideoMode==0)
{
#ifdef _4K
m_nVideoWidth = 3840;
m_nVideoHeight = 2160;
#else
m_nVideoWidth = 1920;
m_nVideoHeight = 1080;
#endif
}
else if(m_nVideoMode==1)
{
m_nVideoWidth = 1280;
m_nVideoHeight = 720;
}
}
int CommonData::GetVideoMode()
{
return m_nVideoMode;
}
void CommonData::SetCropMode(int bCropMode)
{
m_nCropMode = bCropMode;
}
int CommonData::GetCropMode()
{
return m_nCropMode;
}
void CommonData::SetUseFixWidthLevel(int bFixWidthLevel)
{
m_nUseFixWidthLevel = bFixWidthLevel;
}
int CommonData::GetUseFixWidthLevel()
{
return m_nUseFixWidthLevel;
}
void CommonData::SetLogLevel(int nLevel)
{
m_nUseLogLevel = nLevel;
}
int CommonData::GetLogLevel()
{
return m_nUseLogLevel;
}
void CommonData::SetUseUSBBackup(int nUseUSBBackup)
{
m_nUseUSBBackup = nUseUSBBackup;
}
int CommonData::IsUseUSBBackup()
{
return m_nUseUSBBackup;
}
int CommonData::GetVideoWidth()
{
return m_nVideoWidth;
}
int CommonData::GetVideoHeight()
{
return m_nVideoHeight;
}
void CommonData::MakeBitmapHeader(int nWidth, int nHeight)
{
memset(m_pBitmapData, 0, m_nVideoWidth*m_nVideoHeight*3+1000);
int nSizeBitmapHeader = sizeof(BITMAPFILEHADER);
int nSizeBitmapInfoHeader = sizeof(BITMAPINFOHEADER);
memset(&m_bf, 0, sizeof(&m_bf));
m_bf.bfType = 0x4d42;
m_bf.bfOffBits = nSizeBitmapHeader + nSizeBitmapInfoHeader;
m_bf.bfSize = m_bf.bfOffBits + nWidth*nHeight*3;
m_bf.bfReserved1 = 0;
m_bf.bfReserved2 = 0;
memcpy(&m_pBitmapData[0], &m_bf, nSizeBitmapHeader);
memset(&m_bi, 0, sizeof(&m_bi));
m_bi.biSize = sizeof(BITMAPINFOHEADER);
m_bi.biWidth = nWidth;
m_bi.biHeight = -1* nHeight;
m_bi.biPlanes = 1;
m_bi.biBitCount = 24;
m_bi.biCompression = 0;//BI_RGB;
m_bi.biSizeImage = nWidth*nHeight*3;
m_bi.biXPelsPerMeter = 2835;
m_bi.biYPelsPerMeter = 2835;
m_bi.biClrUsed = 0;
m_bi.biClrImportant = 0;
memcpy(&m_pBitmapData[nSizeBitmapHeader], &m_bi, nSizeBitmapInfoHeader);
}
bool CommonData::WriteBitmapFile(QString strFile, QImage* pImage)
{
int nWidth = pImage->width();
int nHeight = pImage->height();
MakeBitmapHeader(nWidth, nHeight);
//QImage tmpImage = pImage->rgbSwapped();
//memcpy(&m_pBitmapData[m_bf.bfOffBits], tmpImage.bits(), nWidth*nHeight*3);
memcpy(&m_pBitmapData[m_bf.bfOffBits], pImage->bits(), nWidth*nHeight*3);
QFile t2(strFile);
if(t2.exists()==true)
{
t2.remove();
}
t2.open(QFile::ReadWrite);
t2.write((const char*)m_pBitmapData, m_bf.bfSize);
t2.flush();
fsync(t2.handle());
t2.close();
bool bCreate = false;
QFile fileBitmap(strFile);
if(fileBitmap.exists()==true)
{
int nFileSize = fileBitmap.size();
if(nFileSize>850 && nFileSize<7230854)
{
bCreate = true;
}
fileBitmap.close();
}
if(bCreate==false)
{
}
return bCreate;
}
bool CommonData::WriteJPEG(QString strFile, uint8_t* pData, int nWidth, int nHeight, int nQualilty)
{
#ifdef _PC
QImage imageWrite(pData, nWidth, nHeight, QImage::Format_RGB888);
imageWrite.save(strFile, "jpg", nQualilty);
#else
QImage imageWrite(pData, nWidth, nHeight, QImage::Format_BGR888);
imageWrite.save(strFile, "jpg", nQualilty);
#endif
return true;
/*
FILE* outfile = fopen(strFile.toStdString().c_str(), "wb");
if(outfile == NULL) return false;
jpeg_compress_struct cinfo;
jpeg_error_mgr jerr;
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
jpeg_stdio_dest(&cinfo, outfile);
cinfo.image_width = nWidth;
cinfo.image_height = nHeight;
cinfo.input_components = 3;
cinfo.in_color_space = JCS_EXT_BGR;
jpeg_set_defaults(&cinfo);
//set the quality [0..100]
jpeg_set_quality(&cinfo, nQualilty, true);
jpeg_start_compress(&cinfo, true);
JSAMPROW row_pointer;
while (cinfo.next_scanline < cinfo.image_height)
{
row_pointer = (JSAMPROW) pData[cinfo.next_scanline*nWidth];
jpeg_write_scanlines(&cinfo, &row_pointer, 1);
}
jpeg_finish_compress(&cinfo);
fclose(outfile);
*/
}
bool CommonData::WriteBitmapFile(QString strFile, uint8_t* pData, int nWidth, int nHeight)
{
MakeBitmapHeader(nWidth, nHeight);
memcpy(&m_pBitmapData[m_bf.bfOffBits], pData, nWidth*nHeight*3);
QFile t2(strFile);
if(t2.exists()==true)
{
t2.remove();
}
t2.open(QFile::ReadWrite);
t2.write((const char*)m_pBitmapData, m_bf.bfSize);
t2.flush();
fsync(t2.handle());
t2.close();
bool bCreate = false;
QFile fileBitmap(strFile);
if(fileBitmap.exists()==true)
{
int nFileSize = fileBitmap.size();
if(nFileSize>850 && nFileSize<7230854)
{
bCreate = true;
}
fileBitmap.close();
}
return bCreate;
}
void CommonData::SetScreenSaverTime(int nMinutes)
{
m_nScreenSaverTime = nMinutes;
}
int CommonData::GetScreenSaverTime()
{
return m_nScreenSaverTime;
}
void CommonData::SetConnectHDMI(bool bConnect)
{
m_bConnectHDMI = bConnect;
}
bool CommonData::IsConnectHDMI()
{
return m_bConnectHDMI;
}
void CommonData::GetSearchDateStartEnd(int nSearchDurationType, QDate& nDateStart, QDate& nDateEnd)
{
QDate nDateCurrent = QDate::currentDate();
switch(nSearchDurationType)
{
case SEARCH_TODAY: //Today
nDateStart = nDateCurrent;
nDateEnd = nDateCurrent;
break;
case SEARCH_3DAY:
nDateEnd = nDateCurrent;
nDateStart = nDateEnd.addDays(-2);
break;
case SEARCH_WEEK:
nDateEnd = nDateCurrent;
nDateStart = nDateEnd.addDays(-6);
break;
case SEARCH_2WEEK:
nDateEnd = nDateCurrent;
nDateStart = nDateEnd.addDays(-13);
break;
case SEARCH_3WEEK:
nDateEnd = nDateCurrent;
nDateStart = nDateEnd.addDays(-20);
break;
case SEARCH_1MONTH:
nDateEnd = nDateCurrent;
nDateStart = nDateCurrent.addMonths(-1);
nDateStart = nDateStart.addDays(1);
break;
case SEARCH_2MONTH:
nDateEnd = nDateCurrent;
nDateStart = nDateCurrent.addMonths(-2);
nDateStart = nDateStart.addDays(1);
break;
case SEARCH_USER_DEFINED:
break;
default:
break;
}
}
void CommonData::RestartNetworkManager()
{
WRITE_FUNCTION_LOG();
QProcess process1;
QProcess process2;
process1.setStandardOutputProcess(&process2);
process1.start("echo 1");
#ifdef _PC
process2.start("sudo systemctl restart NetworkManager");
#else
process2.start("sudo -S systemctl restart NetworkManager");
#endif
process2.setProcessChannelMode(QProcess::ForwardedChannels);
// Wait for it to start
if(!process1.waitForStarted())
return;
bool retval = false;
QByteArray buffer;
// To be fair: you only need to wait here for a bit with shutdown,
// but I will still leave the rest here for a generic solution
while ((retval = process2.waitForFinished()))
{
buffer.append(process2.readAll());
}
process1.terminate();
process2.terminate();
process1.waitForFinished(100);
process2.waitForFinished(100);
process1.deleteLater();
process2.deleteLater();
buffer.clear();
}
void CommonData::SetUseWebDisplay(bool bUse)
{
m_bUseWebDisplay = bUse;
}
bool CommonData::IsUseWebDisplay()
{
return m_bUseWebDisplay;
}
/*
void CommonData::ReOpenDatabase()
{
m_pDatabase->CloseDatabase();
m_pDatabase->OpenDatabase("/home/birdhead/test.db", false);
}
*/