#include "common_api.h" #include "SeqImages.h" SeqImages::SeqImages() { m_Count = 0; m_nWidth = 0; m_nHeight = 0; } SeqImages::~SeqImages() { CloseCircle(); } bool SeqImages::CreateCircle(DWORD size, DWORD count) { return true; } void SeqImages::CloseCircle() { ClearImage(); } unsigned short * SeqImages::TransBmp2Raw(unsigned char* pBuff, DWORD width, DWORD height) { const DWORD na = 0x0000FFFF; const DWORD nb = 0x00FFFFFF; COLORREF *pRGBBuff = (COLORREF*)pBuff; unsigned short* pRaw = new unsigned short[width * height]; if (!pRaw) { return nullptr; // 内存分配失败处理 } for (DWORD i = 0; i < height; i++) { for (DWORD j = 0; j < width; j++) { DWORD index = i * width + j; DWORD color = pRGBBuff[index] & nb; double rawcolor = static_cast(color) * na / nb; pRaw[index] = static_cast(rawcolor); } } return pRaw; } unsigned char* SeqImages::LoadBmp(const char *szFilename, DWORD &width, DWORD &height) { BITMAPFILEHEADER bmpFileHeader; BITMAPINFOHEADER bmpInfo; unsigned char* pBuff = NULL; unsigned char* p32BitmapBuff = NULL; size_t returnedLenth = 0; FILE* fp = fopen(szFilename, "rb"); if (!fp) { // 错误处理:无法打开文件 return nullptr; } returnedLenth = fread(&bmpFileHeader, 1, sizeof(BITMAPFILEHEADER), fp); if (returnedLenth != sizeof(BITMAPFILEHEADER)) { // 错误处理:文件头读取错误 fclose(fp); return nullptr; } if (bmpFileHeader.bfType != 0x4D42) // 'BM'的十六进制表示 { // 错误处理:不是BMP文件 fclose(fp); return nullptr; } returnedLenth = fread(&bmpInfo, 1, sizeof(BITMAPINFOHEADER), fp); if (returnedLenth != sizeof(BITMAPINFOHEADER)) { // 错误处理:信息头读取错误 fclose(fp); return nullptr; } if (bmpInfo.biBitCount != 24 || bmpInfo.biCompression != 0) { // 错误处理:不支持的BMP格式 fclose(fp); return nullptr; } DWORD buffsize = bmpInfo.biWidth * abs(bmpInfo.biHeight) * (bmpInfo.biBitCount / 8); //fix bmpInfo.biSizeImage = buffsize; pBuff = new BYTE[bmpInfo.biSizeImage]; if (!pBuff) { fclose(fp); return nullptr; } width = bmpInfo.biWidth; height = bmpInfo.biHeight; DWORD RealWidth = bmpInfo.biSizeImage / height; fseek(fp, bmpFileHeader.bfOffBits, SEEK_SET); // 读取像素数据 returnedLenth = fread(pBuff, 1, bmpInfo.biSizeImage, fp); if (returnedLenth != bmpInfo.biSizeImage) { // 错误处理:像素数据读取错误 fclose(fp); delete[] pBuff; return nullptr; } fclose(fp); p32BitmapBuff = new BYTE[width * height * (BITSPERPIXEL / 8)]; if (!p32BitmapBuff) { delete[] pBuff; return nullptr; } memset(p32BitmapBuff, 0, width * height * (BITSPERPIXEL / 8)); // 转换24位BMP到32位RGB格式 for (DWORD i = 0; i < height; i++) { // 处理BMP可能的上下颠倒(高度为负时) DWORD rowIndex = (bmpInfo.biHeight > 0) ? (height - 1 - i) : i; for (DWORD j = 0; j < width; j++) { // 计算源数据索引(BMP存储格式为BGR) size_t srcIndex = rowIndex * RealWidth + j * 3; // 计算目标数据索引 size_t dstIndex = (i * width + j) * 4; // BGR转RGB并填充到32位缓冲区(忽略Alpha通道) p32BitmapBuff[dstIndex + 2] = pBuff[srcIndex]; // B -> R p32BitmapBuff[dstIndex + 1] = pBuff[srcIndex + 1]; // G -> G p32BitmapBuff[dstIndex] = pBuff[srcIndex + 2]; // R -> B // Alpha通道设为0(不透明) p32BitmapBuff[dstIndex + 3] = 0xFF; } } // 清理临时缓冲区 delete[] pBuff; return p32BitmapBuff; } PWORD LoadRaw(const char *szFilename, DWORD &width, DWORD &height) { FILE* fp = fopen(szFilename, "rb"); if (!fp) { printf("Unable to open raw file: %s\n", szFilename); return NULL; } struct stat fileInfo; if (stat(szFilename, &fileInfo) != 0) { fclose(fp); printf("Failed to get file info for: %s\n", szFilename); return NULL; } off_t fileSize = fileInfo.st_size; // 检查文件大小是否匹配 size_t expectedSize = width * height * sizeof(unsigned short); if (fileSize != expectedSize) { fclose(fp); printf("File size mismatch for %s: expected %zu, got %lld\n", szFilename, expectedSize, (long long)fileSize); return NULL; } // 分配缓冲区 PWORD pBuff = new unsigned short[width * height]; if (!pBuff) { fclose(fp); printf("Memory allocation failed for raw file\n"); return NULL; } // 读取文件内容(替代ReadFile) size_t returnedLenth = fread(pBuff, sizeof(unsigned short), width * height, fp); if (returnedLenth != width * height) { fclose(fp); delete[] pBuff; printf("Failed to read complete raw data from %s\n", szFilename); return NULL; } // 关闭文件(替代CloseHandle) fclose(fp); return pBuff; } // 辅助函数:判断路径是否为目录 bool PathIsDirectory(const char* pszPath) { struct stat st; if (stat(pszPath, &st) != 0) { return false; } return S_ISDIR(st.st_mode); } // 辅助函数:获取文件名(假设已有实现) std::string GetFileName(const std::string& strPath) { size_t pos = strPath.find_last_of("/\\"); if (pos == std::string::npos) { return strPath; } return strPath.substr(pos + 1); } bool SeqImages::LoadRawFromDirectory(const char *pszDirName,DWORD dx,DWORD dy) { bool ret = false; std::string Path = pszDirName; if (!PathIsDirectory(Path.c_str())) { return ret; } std::vector filelist; // 查找目录下的所有文件 if (!FindSubFiles(Path, filelist) || filelist.empty()) { return ret; } for (DWORD i = 0; i < filelist.size(); i++) { std::string Ext = GetFileName(filelist[i]); makeLowerStr(Ext); if (Ext == "raw") { //printf("Load raw file, path: %s \n", filelist[i].c_str()); //for test PWORD pRaw = LoadRaw(filelist[i].c_str(), dx, dy); if (pRaw) { //got raw data m_nWidth = dx; m_nHeight = dy; m_pSmCircleBuff.push_back(pRaw); ++m_Count; printf("Push raw(%ld %ld), id: %ld, path: %s \n", dx, dy, m_Count, filelist[i].c_str()); } } } if (m_Count > 0) { ret = true; } m_Count = 0; return ret; } bool SeqImages::LoadBmpFromDirectory(const char *pszDirName) { bool ret = false; string Path = pszDirName; if (!PathIsDirectory(Path.c_str())) { return ret; } vector filelist; //start here if (FindSubFiles(Path, filelist) == false || filelist.size() == 0) { return ret; } for (DWORD i = 0; i < filelist.size(); i++) { string Ext = GetFileName(filelist[i]); makeLowerStr(Ext); if (Ext.find("bmp") != string::npos) { DWORD width = 0, height = 0; unsigned char* pBmp = LoadBmp(filelist[i].c_str(), width, height); if (pBmp) { unsigned short* pRaw = TransBmp2Raw(pBmp, width, height); if (pRaw) { //got raw data m_nWidth = width; m_nHeight = height; m_pSmCircleBuff.push_back(pRaw); ++m_Count; printf("Push bmp(%ld %ld), id: %ld, path: %s \n", width, height, m_Count, filelist[i].c_str()); } delete[]pBmp; } } } if (m_Count > 0) { ret = true; } m_Count = 0; return ret; } void SeqImages::PushMemImage(unsigned short* pRaw, int nW, int nH, int nBits) { m_pSmCircleBuff.push_back(pRaw); m_nWidth = nW; m_nHeight = nH; printf("Push Dcm data(%d %d), id: %d\n", nW, nH,nBits); } bool SeqImages::LoadPath(const char *pPath, DWORD dwImgX, DWORD dwImgY) { bool ret = LoadBmpFromDirectory(pPath); //if (ret) { if (dwImgX != 0 && dwImgY != 0) { return LoadRawFromDirectory(pPath, dwImgX, dwImgY); } return LoadRawFromDirectory(pPath,3000,3000); } return ret; } unsigned short * SeqImages::GetImage() { return m_pSmCircleBuff[m_Count]; } int SeqImages::GetNext() { if (m_pSmCircleBuff.size() > 0) { m_Count++; if (m_Count == m_pSmCircleBuff.size()) { m_Count = 0; } return m_Count; } return 0; } /*** * 重置图像ID,新一轮采集时可以重新从第一张图像开始给上层传图 ***/ bool SeqImages::ResetImageID() { if (m_pSmCircleBuff.size() > 0) { m_Count = 0; printf("Reset mem ID, Current ID: %ld", m_Count); return true; } return false; } /*** ** 说明:清空当前共享内存中的图片 ***/ bool SeqImages::ClearImage() { if (m_pSmCircleBuff.size() > 0) { for (int i = 0; i < m_pSmCircleBuff.size(); i++) { delete m_pSmCircleBuff[i]; } m_pSmCircleBuff.clear(); } return true; } DWORD SeqImages::GetCurrentFrameID() { return m_Count; } int SeqImages::GetTotalFrameNumber() { return (int)m_pSmCircleBuff.size(); }