SeqImages.cpp 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  1. #include "common_api.h"
  2. #include "SeqImages.h"
  3. SeqImages::SeqImages()
  4. {
  5. m_Count = 0;
  6. m_nWidth = 0;
  7. m_nHeight = 0;
  8. }
  9. SeqImages::~SeqImages()
  10. {
  11. CloseCircle();
  12. }
  13. bool SeqImages::CreateCircle(DWORD size, DWORD count)
  14. {
  15. return true;
  16. }
  17. void SeqImages::CloseCircle()
  18. {
  19. ClearImage();
  20. }
  21. unsigned short * SeqImages::TransBmp2Raw(unsigned char* pBuff, DWORD width, DWORD height)
  22. {
  23. const DWORD na = 0x0000FFFF;
  24. const DWORD nb = 0x00FFFFFF;
  25. COLORREF *pRGBBuff = (COLORREF*)pBuff;
  26. unsigned short* pRaw = new unsigned short[width * height];
  27. if (!pRaw) {
  28. return nullptr; // 内存分配失败处理
  29. }
  30. for (DWORD i = 0; i < height; i++)
  31. {
  32. for (DWORD j = 0; j < width; j++)
  33. {
  34. DWORD index = i * width + j;
  35. DWORD color = pRGBBuff[index] & nb;
  36. double rawcolor = static_cast<double>(color) * na / nb;
  37. pRaw[index] = static_cast<unsigned short>(rawcolor);
  38. }
  39. }
  40. return pRaw;
  41. }
  42. unsigned char* SeqImages::LoadBmp(const char *szFilename, DWORD &width, DWORD &height)
  43. {
  44. BITMAPFILEHEADER bmpFileHeader;
  45. BITMAPINFOHEADER bmpInfo;
  46. unsigned char* pBuff = NULL;
  47. unsigned char* p32BitmapBuff = NULL;
  48. size_t returnedLenth = 0;
  49. FILE* fp = fopen(szFilename, "rb");
  50. if (!fp)
  51. {
  52. // 错误处理:无法打开文件
  53. return nullptr;
  54. }
  55. returnedLenth = fread(&bmpFileHeader, 1, sizeof(BITMAPFILEHEADER), fp);
  56. if (returnedLenth != sizeof(BITMAPFILEHEADER))
  57. {
  58. // 错误处理:文件头读取错误
  59. fclose(fp);
  60. return nullptr;
  61. }
  62. if (bmpFileHeader.bfType != 0x4D42) // 'BM'的十六进制表示
  63. {
  64. // 错误处理:不是BMP文件
  65. fclose(fp);
  66. return nullptr;
  67. }
  68. returnedLenth = fread(&bmpInfo, 1, sizeof(BITMAPINFOHEADER), fp);
  69. if (returnedLenth != sizeof(BITMAPINFOHEADER))
  70. {
  71. // 错误处理:信息头读取错误
  72. fclose(fp);
  73. return nullptr;
  74. }
  75. if (bmpInfo.biBitCount != 24 || bmpInfo.biCompression != 0)
  76. {
  77. // 错误处理:不支持的BMP格式
  78. fclose(fp);
  79. return nullptr;
  80. }
  81. DWORD buffsize = bmpInfo.biWidth * abs(bmpInfo.biHeight) * (bmpInfo.biBitCount / 8);
  82. //fix
  83. bmpInfo.biSizeImage = buffsize;
  84. pBuff = new BYTE[bmpInfo.biSizeImage];
  85. if (!pBuff)
  86. {
  87. fclose(fp);
  88. return nullptr;
  89. }
  90. width = bmpInfo.biWidth;
  91. height = bmpInfo.biHeight;
  92. DWORD RealWidth = bmpInfo.biSizeImage / height;
  93. fseek(fp, bmpFileHeader.bfOffBits, SEEK_SET);
  94. // 读取像素数据
  95. returnedLenth = fread(pBuff, 1, bmpInfo.biSizeImage, fp);
  96. if (returnedLenth != bmpInfo.biSizeImage)
  97. {
  98. // 错误处理:像素数据读取错误
  99. fclose(fp);
  100. delete[] pBuff;
  101. return nullptr;
  102. }
  103. fclose(fp);
  104. p32BitmapBuff = new BYTE[width * height * (BITSPERPIXEL / 8)];
  105. if (!p32BitmapBuff)
  106. {
  107. delete[] pBuff;
  108. return nullptr;
  109. }
  110. memset(p32BitmapBuff, 0, width * height * (BITSPERPIXEL / 8));
  111. // 转换24位BMP到32位RGB格式
  112. for (DWORD i = 0; i < height; i++)
  113. {
  114. // 处理BMP可能的上下颠倒(高度为负时)
  115. DWORD rowIndex = (bmpInfo.biHeight > 0) ? (height - 1 - i) : i;
  116. for (DWORD j = 0; j < width; j++)
  117. {
  118. // 计算源数据索引(BMP存储格式为BGR)
  119. size_t srcIndex = rowIndex * RealWidth + j * 3;
  120. // 计算目标数据索引
  121. size_t dstIndex = (i * width + j) * 4;
  122. // BGR转RGB并填充到32位缓冲区(忽略Alpha通道)
  123. p32BitmapBuff[dstIndex + 2] = pBuff[srcIndex]; // B -> R
  124. p32BitmapBuff[dstIndex + 1] = pBuff[srcIndex + 1]; // G -> G
  125. p32BitmapBuff[dstIndex] = pBuff[srcIndex + 2]; // R -> B
  126. // Alpha通道设为0(不透明)
  127. p32BitmapBuff[dstIndex + 3] = 0xFF;
  128. }
  129. }
  130. // 清理临时缓冲区
  131. delete[] pBuff;
  132. return p32BitmapBuff;
  133. }
  134. PWORD LoadRaw(const char *szFilename, DWORD &width, DWORD &height)
  135. {
  136. FILE* fp = fopen(szFilename, "rb");
  137. if (!fp)
  138. {
  139. printf("Unable to open raw file: %s\n", szFilename);
  140. return NULL;
  141. }
  142. struct stat fileInfo;
  143. if (stat(szFilename, &fileInfo) != 0)
  144. {
  145. fclose(fp);
  146. printf("Failed to get file info for: %s\n", szFilename);
  147. return NULL;
  148. }
  149. off_t fileSize = fileInfo.st_size;
  150. // 检查文件大小是否匹配
  151. size_t expectedSize = width * height * sizeof(unsigned short);
  152. if (fileSize != expectedSize)
  153. {
  154. fclose(fp);
  155. printf("File size mismatch for %s: expected %zu, got %lld\n",
  156. szFilename, expectedSize, (long long)fileSize);
  157. return NULL;
  158. }
  159. // 分配缓冲区
  160. PWORD pBuff = new unsigned short[width * height];
  161. if (!pBuff)
  162. {
  163. fclose(fp);
  164. printf("Memory allocation failed for raw file\n");
  165. return NULL;
  166. }
  167. // 读取文件内容(替代ReadFile)
  168. size_t returnedLenth = fread(pBuff, sizeof(unsigned short), width * height, fp);
  169. if (returnedLenth != width * height)
  170. {
  171. fclose(fp);
  172. delete[] pBuff;
  173. printf("Failed to read complete raw data from %s\n", szFilename);
  174. return NULL;
  175. }
  176. // 关闭文件(替代CloseHandle)
  177. fclose(fp);
  178. return pBuff;
  179. }
  180. // 辅助函数:判断路径是否为目录
  181. bool PathIsDirectory(const char* pszPath) {
  182. struct stat st;
  183. if (stat(pszPath, &st) != 0) {
  184. return false;
  185. }
  186. return S_ISDIR(st.st_mode);
  187. }
  188. // 辅助函数:获取文件名(假设已有实现)
  189. std::string GetFileName(const std::string& strPath) {
  190. size_t pos = strPath.find_last_of("/\\");
  191. if (pos == std::string::npos) {
  192. return strPath;
  193. }
  194. return strPath.substr(pos + 1);
  195. }
  196. bool SeqImages::LoadRawFromDirectory(const char *pszDirName,DWORD dx,DWORD dy)
  197. {
  198. bool ret = false;
  199. std::string Path = pszDirName;
  200. if (!PathIsDirectory(Path.c_str())) {
  201. return ret;
  202. }
  203. std::vector<std::string> filelist;
  204. // 查找目录下的所有文件
  205. if (!FindSubFiles(Path, filelist) || filelist.empty()) {
  206. return ret;
  207. }
  208. for (DWORD i = 0; i < filelist.size(); i++)
  209. {
  210. std::string Ext = GetFileName(filelist[i]);
  211. makeLowerStr(Ext);
  212. if (Ext == "raw")
  213. {
  214. //printf("Load raw file, path: %s \n", filelist[i].c_str()); //for test
  215. PWORD pRaw = LoadRaw(filelist[i].c_str(), dx, dy);
  216. if (pRaw)
  217. {
  218. //got raw data
  219. m_nWidth = dx;
  220. m_nHeight = dy;
  221. m_pSmCircleBuff.push_back(pRaw);
  222. ++m_Count;
  223. printf("Push raw(%ld %ld), id: %ld, path: %s \n", dx, dy, m_Count, filelist[i].c_str());
  224. }
  225. }
  226. }
  227. if (m_Count > 0)
  228. {
  229. ret = true;
  230. }
  231. m_Count = 0;
  232. return ret;
  233. }
  234. bool SeqImages::LoadBmpFromDirectory(const char *pszDirName)
  235. {
  236. bool ret = false;
  237. string Path = pszDirName;
  238. if (!PathIsDirectory(Path.c_str()))
  239. {
  240. return ret;
  241. }
  242. vector<string> filelist;
  243. //start here
  244. if (FindSubFiles(Path, filelist) == false || filelist.size() == 0)
  245. {
  246. return ret;
  247. }
  248. for (DWORD i = 0; i < filelist.size(); i++)
  249. {
  250. string Ext = GetFileName(filelist[i]);
  251. makeLowerStr(Ext);
  252. if (Ext.find("bmp") != string::npos)
  253. {
  254. DWORD width = 0, height = 0;
  255. unsigned char* pBmp = LoadBmp(filelist[i].c_str(), width, height);
  256. if (pBmp)
  257. {
  258. unsigned short* pRaw = TransBmp2Raw(pBmp, width, height);
  259. if (pRaw)
  260. {
  261. //got raw data
  262. m_nWidth = width;
  263. m_nHeight = height;
  264. m_pSmCircleBuff.push_back(pRaw);
  265. ++m_Count;
  266. printf("Push bmp(%ld %ld), id: %ld, path: %s \n", width, height, m_Count, filelist[i].c_str());
  267. }
  268. delete[]pBmp;
  269. }
  270. }
  271. }
  272. if (m_Count > 0)
  273. {
  274. ret = true;
  275. }
  276. m_Count = 0;
  277. return ret;
  278. }
  279. void SeqImages::PushMemImage(unsigned short* pRaw, int nW, int nH, int nBits)
  280. {
  281. m_pSmCircleBuff.push_back(pRaw);
  282. m_nWidth = nW;
  283. m_nHeight = nH;
  284. printf("Push Dcm data(%d %d), id: %d\n", nW, nH,nBits);
  285. }
  286. bool SeqImages::LoadPath(const char *pPath, DWORD dwImgX, DWORD dwImgY)
  287. {
  288. bool ret = LoadBmpFromDirectory(pPath);
  289. //if (ret)
  290. {
  291. if (dwImgX != 0 && dwImgY != 0)
  292. {
  293. return LoadRawFromDirectory(pPath, dwImgX, dwImgY);
  294. }
  295. return LoadRawFromDirectory(pPath,3000,3000);
  296. }
  297. return ret;
  298. }
  299. unsigned short * SeqImages::GetImage()
  300. {
  301. return m_pSmCircleBuff[m_Count];
  302. }
  303. int SeqImages::GetNext()
  304. {
  305. if (m_pSmCircleBuff.size() > 0)
  306. {
  307. m_Count++;
  308. if (m_Count == m_pSmCircleBuff.size())
  309. {
  310. m_Count = 0;
  311. }
  312. return m_Count;
  313. }
  314. return 0;
  315. }
  316. /***
  317. * 重置图像ID,新一轮采集时可以重新从第一张图像开始给上层传图
  318. ***/
  319. bool SeqImages::ResetImageID()
  320. {
  321. if (m_pSmCircleBuff.size() > 0)
  322. {
  323. m_Count = 0;
  324. printf("Reset mem ID, Current ID: %ld", m_Count);
  325. return true;
  326. }
  327. return false;
  328. }
  329. /***
  330. ** 说明:清空当前共享内存中的图片
  331. ***/
  332. bool SeqImages::ClearImage()
  333. {
  334. if (m_pSmCircleBuff.size() > 0)
  335. {
  336. for (int i = 0; i < m_pSmCircleBuff.size(); i++)
  337. {
  338. delete m_pSmCircleBuff[i];
  339. }
  340. m_pSmCircleBuff.clear();
  341. }
  342. return true;
  343. }
  344. DWORD SeqImages::GetCurrentFrameID()
  345. {
  346. return m_Count;
  347. }
  348. int SeqImages::GetTotalFrameNumber()
  349. {
  350. return (int)m_pSmCircleBuff.size();
  351. }