PcxLoad.cpp
上传用户:yatsl7111
上传日期:2007-01-08
资源大小:1433k
文件大小:25k
源码类别:

图形图象

开发平台:

Visual C++

  1. #include "stdafx.h"
  2. #include "PcxDeclare.h"
  3. #include "PcxModule.h"
  4. #include "FuncFromYz.h"
  5. #include "PcxError.h"
  6. #include "PcxPalette.h"
  7. #define PCX_BUF_MAX 124
  8. #define DIBSCANLINE_WIDTHBYTES(bits)    (((bits)+31)/32*4)
  9. EXERESULT api_Isee_Check_Command_Load(INFOSTR *pInfo)
  10. {
  11. // 检验入口参数是否符合接口定义
  12. ASSERT(pInfo->result == ER_EMPTY);
  13. ASSERT(::strlen(pInfo->filename));
  14. // 此时,该文件必需是一个已存在的、有效的PCX文件,并且数据包中
  15. // 含有该文件的信息(imginfo结构中)
  16. ASSERT(pInfo->state == PKST_PASSINFO);
  17. ASSERT(pInfo->imginfo.imgformat == IMF_PCX);
  18. ASSERT(pInfo->pImgInfo == NULL);
  19. // 必需设置标准图像格式信息
  20. ASSERT(pInfo->sDIBInfo.bmi.biSize == sizeof(BITMAPINFOHEADER));
  21. ASSERT(pInfo->pLineAddr != NULL);
  22. ASSERT(pInfo->_pbdata != NULL);
  23. return ER_SUCCESS;
  24. };
  25. EXERESULT Isee_Api_Access_Progress(INFOSTR *pInfo, int MaxPreg, int CurrentPreg)
  26. {
  27. if (pInfo->fpProgress)
  28. {
  29. if ((*pInfo->fpProgress)(MaxPreg, CurrentPreg))
  30. { // 如果进度函数返回1,则说明用户想中断操作,返回。
  31. pInfo->result = ER_USERBREAK;
  32. return ER_USERBREAK;
  33. }
  34. }
  35. return ER_SUCCESS;
  36. };
  37. void Pcx_Access_Progress(INFOSTR *pInfo, int MaxPreg = 0, int CurrentPreg = 0)
  38. {
  39. if (pInfo->fpProgress)
  40. {
  41. if ((*pInfo->fpProgress)(100, 6))
  42. { // 如果进度函数返回1,则说明用户想中断操作,返回(throw)。
  43. pInfo->result = ER_USERBREAK;//仅此函数更改返回值
  44. ApiThrowMyExce(ENO_USERBREAK);//throw 跳到 catch
  45. }
  46. }
  47. }
  48. BOOL Success(int tag_param)
  49. {
  50. return (tag_param == ER_SUCCESS);
  51. };
  52. EXERESULT Pcx_Load_sub_1(INFOSTR * pInfo, LPCSTR lpData, int iDataSize);
  53. EXERESULT Pcx_Load_sub_4(INFOSTR * pInfo, LPCSTR lpData, int iDataSize);
  54. EXERESULT Pcx_Load_sub_8(INFOSTR * pInfo, LPCSTR lpData, int iDataSize);
  55. EXERESULT Pcx_Load_sub_24(INFOSTR * pInfo, LPCSTR lpData, int iDataSize);
  56. void PcxFitPinfo(INFOSTR * pInfo)
  57. {
  58. HGLOBAL p = (HGLOBAL)pInfo->pImgInfo;
  59. // ::GlobalUnlock(p);
  60. if(p == NULL)return;
  61. ::GlobalFree(p);
  62. pInfo->pImgInfo = NULL;
  63. }
  64. void Pcx_Load_From_File(INFOSTR * pInfo)
  65. {
  66. EXERESULT rt = ER_SUCCESS;//希望能顺利执行!^_^
  67. rt = api_Isee_Check_Command_Load(pInfo);
  68. if(! Success(rt))
  69. {
  70. pInfo->result = rt;
  71. return;
  72. }
  73. unsigned long bitcount = 0;
  74. ENUM_EXCE_NO no = ENO_OK;
  75. HANDLE hf = NULL;
  76. DWORD filesize = 0;
  77. HANDLE hMapping = NULL;
  78. LPSTR lpData = NULL;
  79. const char * pcStrFileName = pInfo->filename;
  80. rt = Isee_Api_Access_Progress(pInfo,100,100);//rt 已设
  81. filesize = (DWORD)pInfo->imginfo.filesize;
  82. try
  83. {
  84. hf = CreateFile(pcStrFileName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
  85. if( hf == INVALID_HANDLE_VALUE)
  86. {
  87. rt = ER_FILERWERR;
  88. ApiThrowMyExce(ENO_CREATE_FILE_EX);
  89. }
  90. hMapping = CreateFileMapping(hf,NULL,PAGE_READONLY,0,filesize,NULL);
  91. if(hMapping == NULL)
  92. {
  93. rt = ER_MEMORYERR;
  94. ApiThrowMyExce(ENO_CREATE_MAP_EX);
  95. }
  96. lpData = (LPSTR)MapViewOfFile(hMapping,FILE_MAP_READ,0,0,0);
  97. if(lpData == NULL)
  98. {
  99. rt = ER_MEMORYERR;
  100. ApiThrowMyExce(ENO_MAP_VIEW_EX);
  101. }
  102. PcxDoWithPalette(pInfo, lpData,filesize);
  103. bitcount = pInfo->imginfo.bitcount;
  104. switch(bitcount)
  105. {
  106. case 1:
  107. rt = Pcx_Load_sub_1(pInfo, lpData, filesize);
  108. break;
  109. case 4:
  110. rt = Pcx_Load_sub_4(pInfo, lpData, filesize);
  111. break;
  112. case 8:
  113. rt = Pcx_Load_sub_8(pInfo, lpData, filesize);
  114. break;
  115. case 24:
  116. rt = Pcx_Load_sub_24(pInfo, lpData, filesize);
  117. break;
  118. }
  119. }
  120. catch(CMyException myExce)
  121. {
  122. no = myExce.GetNo();
  123. CString str;
  124. }
  125. switch(no)
  126. {
  127. default:
  128. case ENO_OK:
  129. case ENO_USERBREAK:
  130. //rt 已设
  131. rt = pInfo->result;
  132. UnmapViewOfFile(lpData);
  133. case ENO_MAP_VIEW_EX:
  134. CloseHandle(hMapping);
  135. case ENO_CREATE_MAP_EX:
  136. CloseHandle(hf);
  137. case ENO_CREATE_FILE_EX:
  138. rt = ER_FILERWERR;
  139. }
  140. Isee_Api_Access_Progress(pInfo,100,100);//rt 已设
  141. //***************************
  142. PcxFitPinfo(pInfo);
  143. pInfo->state = PKST_INFOANDBITS;
  144. pInfo->modify = 0;
  145. pInfo->result = ER_SUCCESS;
  146. //不允许中断
  147. return;
  148. };
  149. EXERESULT Pcx_Load_sub_4(INFOSTR * pInfo, LPCSTR lpData, int iDataSize)
  150. {
  151. const PCXFILEHEADER *const pcxFileHead=(const PCXFILEHEADER *) lpData;//文件头
  152. LPCSTR const pImage = lpData + sizeof(PCXFILEHEADER);//图像数据、读取起点
  153. const struct PcxPalette * const lpPalette = (struct PcxPalette * )pcxFileHead->byPalette;//调色板
  154. //from yz
  155. DWORD imgheight = pInfo->imginfo.height; // 图像的高度
  156. DWORD imgwidth  = pInfo->imginfo.width; // 图像的宽度
  157. DWORD dwDestFormat = _get_desformat(pInfo);//目标格式
  158. DWORD dwPcxOneScanLineSize  = pcxFileHead->wLineBytes;// 每一扫描行的宽度(in byte)
  159. DWORD dwPcxLineSizeCount = pcxFileHead->wLineBytes * pcxFileHead->byPlanes;
  160. DWORD dwImageHeightCount, dwImageWidthCount;//用于计数
  161. //
  162. char * const pScanLineBuf = (char *)new char[dwPcxLineSizeCount + 16];//16 for 安全
  163. //解压缓冲区
  164. if(pScanLineBuf == NULL)
  165. ApiMyThrowMem();
  166. WORD * pLineDest = NULL;//目标行首地址、
  167. WORD * pLineSource = NULL;//源行首地址、
  168. pLineSource = (WORD *)pScanLineBuf;//源....
  169. // WORD * pPixDest = NULL;//目标地址、(目标地址分别定义)
  170. BYTE ch1,ch2;
  171. char * pScan = NULL;////解压指针
  172. DWORD ScanLinePoint = 0;//解压计数
  173. // 以各种格式的调色板数据
  174. //..放在循环外、以空间换取时间
  175. WORD descol555[16];
  176. WORD descol565[16];
  177. DWORD descol888[16];
  178. WORD * pDesPixAddr555 = NULL;
  179. WORD * pDesPixAddr565 = NULL;
  180. BYTE * pDesPixAddr24 = NULL;
  181. DWORD * pDesPixAddr888 = NULL;
  182. int i;
  183. switch(dwDestFormat) // 标准图像格式(目标格式)
  184. {
  185. case DF_16_555:
  186. {
  187. for (i=0;i<16;i++) // 初始化色素颜色数据
  188. descol555[i] = _cnv_rgb_to_555(lpPalette[i].byRed, lpPalette[i].byGreen, lpPalette[i].byBlue);
  189. }
  190. break;
  191. case DF_16_565:
  192. {
  193. for (i=0;i<16;i++) // 初始化色素颜色数据
  194. descol565[i] = _cnv_rgb_to_565(lpPalette[i].byRed, lpPalette[i].byGreen, lpPalette[i].byBlue);
  195. }
  196. break;
  197. case DF_32:
  198. {
  199. for (i=0;i<16;i++) // 初始化色素颜色数据
  200. descol888[i] = _cnv_rgb_to_888(lpPalette[i].byRed, lpPalette[i].byGreen, lpPalette[i].byBlue);
  201. }
  202. break;
  203. default:
  204. break;
  205. }
  206. // int i, j;//, isou;
  207. // DWORD dwPCXLineSizeCount;
  208. //char * pSrc = ;
  209. char k;//解压计数
  210. // char *lpPlane0,*lpPlane1,*lpPlane2,*lpPlane3;//解码指针
  211. BYTE byPlane0,byPlane1,byPlane2,byPlane3;//码值
  212. // BYTE byIndex1,byIndex2,byIndex3,byIndex4;//解码值
  213. // BYTE byIndex5,byIndex6,byIndex7,byIndex8;//解码值
  214. LPCSTR pSrc = pImage;//读取起点//类似流(?):-)
  215. for(dwImageHeightCount=0;dwImageHeightCount<imgheight;dwImageHeightCount++)//Pcx 总是正向
  216. {
  217. pScan = (char *)(pScanLineBuf);
  218. ScanLinePoint = 0;
  219. //while(ScanLinePoint <dwPCXScanLineSize&&!feof(f1))//base 0;Index
  220. while(ScanLinePoint <dwPcxLineSizeCount)//base 0;Index
  221. {
  222. if((pSrc - lpData)>=iDataSize)break;
  223. ch1=(*pSrc ++)&0xFF;//fgetc() return int;
  224. if((ch1&0xc0)==0xC0)
  225. {
  226. k = ch1&0x3F;
  227. ch2 = (*pSrc ++)&0xFF;
  228. while(k--)//&&ScanLinePoint<dwPCXScanLineSize)
  229. {
  230. pScan[ScanLinePoint++] = ch2;//
  231. }
  232. }
  233. else
  234. {
  235. pScan[ScanLinePoint++] = ch1;
  236. }
  237. }//while (pcxLineWidth)//解压一行
  238. pLineDest = (WORD*)pInfo->pLineAddr[dwImageHeightCount];//当前目标 (行)
  239. //源在pLineBuf
  240. pLineSource = (WORD *)pScanLineBuf;//源....
  241. //源地址总是不变
  242. //目标 都在此初始化
  243. pDesPixAddr555 = (WORD * )pLineDest;
  244. pDesPixAddr565 = (WORD * )pLineDest;
  245. pDesPixAddr24 = (BYTE * )pLineDest;
  246. pDesPixAddr888 = (DWORD * )pLineDest;
  247. dwImageWidthCount = 0;
  248. for(ScanLinePoint=0;ScanLinePoint<dwPcxOneScanLineSize;ScanLinePoint++)//解码一行
  249. {
  250. //****************************************//read 1 byte;
  251. byPlane0 = *((char *)pScanLineBuf+dwPcxOneScanLineSize*0+ScanLinePoint);
  252. byPlane1 = *((char *)pScanLineBuf+dwPcxOneScanLineSize*1+ScanLinePoint);
  253. byPlane2 = *((char *)pScanLineBuf+dwPcxOneScanLineSize*2+ScanLinePoint);
  254. byPlane3 = *((char *)pScanLineBuf+dwPcxOneScanLineSize*3+ScanLinePoint);
  255. //****************************************
  256. //point 1-2 in 1st byte
  257. int i;
  258. BYTE byFlag = 1; //掩码
  259. BYTE byIndex;
  260. for(i = 7; i>=0;i--)//(高位在前)
  261. {
  262. byFlag = 1<<i;
  263. byIndex=0x00;
  264. byIndex |=((byPlane3 & byFlag)? 0x08:byIndex);
  265. byIndex |=((byPlane2 & byFlag)? 0x04:byIndex);
  266. byIndex |=((byPlane1 & byFlag)? 0x02:byIndex);
  267. byIndex |=((byPlane0 & byFlag)? 0x01:byIndex);
  268. {
  269. }
  270. switch(dwDestFormat) // 标准图像格式(目标格式)
  271. {
  272. case DF_16_555:
  273. {
  274. if(dwImageWidthCount < imgwidth)
  275. {
  276. *pDesPixAddr555++ = descol555[byIndex];
  277. dwImageWidthCount ++;
  278. }
  279. break;
  280. }
  281. case DF_16_565:
  282. {
  283. if(dwImageWidthCount < imgwidth)
  284. {
  285. *pDesPixAddr565++ = descol565[byIndex];
  286. dwImageWidthCount ++;
  287. }
  288. break;
  289. }
  290. case DF_24:
  291. {
  292. if(dwImageWidthCount < imgwidth)
  293. {
  294. *pDesPixAddr24++ = lpPalette[byIndex].byBlue;
  295. *pDesPixAddr24++ = lpPalette[byIndex].byGreen;
  296. *pDesPixAddr24++ = lpPalette[byIndex].byRed;
  297. }
  298. break;
  299. }
  300. case DF_32:
  301. {
  302. if(dwImageWidthCount < imgwidth)
  303. {
  304. *pDesPixAddr888++ = descol888[byIndex];
  305. dwImageWidthCount ++;
  306. }
  307. break;
  308. }
  309. case DF_NULL:
  310. default:
  311. ASSERT(FALSE);
  312. pInfo->result = ER_ILLCOMM;
  313. return ER_ILLCOMM;
  314. break;
  315. }//switch(dwDestFormat)
  316. }//for 每8个像素
  317. }//for dwScanLineSize;
  318. }//for imageheight
  319. delete pScanLineBuf;
  320. return ER_SUCCESS;
  321. };
  322. EXERESULT Pcx_Load_sub_8(INFOSTR * pInfo, LPCSTR lpData, int iDataSize)
  323. {
  324. const PCXFILEHEADER *const pcxFileHead=(const PCXFILEHEADER *) lpData;//文件头
  325. LPCSTR const pImage = lpData + sizeof(PCXFILEHEADER);//图像数据、读取起点
  326. const struct PcxPalette * lpPalette = NULL;//调色板
  327. DWORD tempPaletteCount;
  328. GetPcxPalette((struct PcxImgInfo *)pInfo->pImgInfo, (void ** )&lpPalette, &tempPaletteCount);
  329. ASSERT(lpPalette != NULL);
  330. ASSERT(tempPaletteCount == 256);
  331. //from yz
  332. DWORD imgheight = pInfo->imginfo.height; // 图像的高度
  333. DWORD imgwidth  = pInfo->imginfo.width; // 图像的宽度
  334. DWORD dwDestFormat = _get_desformat(pInfo);//目标格式
  335. DWORD dwPcxOneScanLineSize  = pcxFileHead->wLineBytes;// 每一扫描行的宽度(in byte)
  336. DWORD dwPcxLineSizeCount = pcxFileHead->wLineBytes * pcxFileHead->byPlanes;
  337. DWORD dwImageHeightCount, dwImageWidthCount;//用于计数
  338. //
  339. char * const pScanLineBuf = (char *)new char[dwPcxLineSizeCount + 16];//16 for 安全
  340. //解压缓冲区
  341. if(pScanLineBuf == NULL)
  342. ApiMyThrowMem();
  343. WORD * pLineDest = NULL;//目标行首地址、
  344. BYTE * pLineSource = NULL;//源行首地址、
  345. pLineSource = (BYTE *)pScanLineBuf;//源....
  346. // WORD * pPixDest = NULL;//目标地址、(目标地址 依格式分别定义)
  347. BYTE ch1,ch2;
  348. char * pScan = NULL;////解压指针
  349. DWORD ScanLinePoint = 0;//解压计数
  350. // 以各种格式的调色板数据
  351. //..放在循环外、以空间换取时间
  352. //WORD descol555[256];
  353. //WORD descol565[256];
  354. //DWORD descol888[256];
  355. //<节约一下吧 ^_^ >
  356. WORD * descol555 = NULL;
  357. WORD * descol565 = NULL;
  358. DWORD * descol888 = NULL;
  359. WORD * pDesPixAddr555 = NULL;
  360. WORD * pDesPixAddr565 = NULL;
  361. BYTE * pDesPixAddr24 = NULL;
  362. DWORD * pDesPixAddr888 = NULL;
  363. int i;
  364. switch(dwDestFormat) // 标准图像格式(目标格式)
  365. {
  366. case DF_16_555:
  367. {
  368. if(descol555 == NULL)
  369. ApiMyThrowMem();
  370. descol555 = new WORD[256];
  371. for (i=0;i<256;i++) // 初始化色素颜色数据
  372. descol555[i] = _cnv_rgb_to_555(lpPalette[i].byRed, lpPalette[i].byGreen, lpPalette[i].byBlue);
  373. }
  374. break;
  375. case DF_16_565:
  376. {
  377. descol565 = new WORD[256];
  378. if(descol565 == NULL)
  379. ApiMyThrowMem();
  380. for (i=0;i<256;i++) // 初始化色素颜色数据
  381. descol565[i] = _cnv_rgb_to_565(lpPalette[i].byRed, lpPalette[i].byGreen, lpPalette[i].byBlue);
  382. }
  383. break;
  384. case DF_32:
  385. {
  386. descol888 = new DWORD[256];
  387. if(descol888 == NULL)
  388. ApiMyThrowMem();
  389. for (i=0;i<256;i++) // 初始化色素颜色数据
  390. descol888[i] = _cnv_rgb_to_888(lpPalette[i].byRed, lpPalette[i].byGreen, lpPalette[i].byBlue);
  391. }
  392. break;
  393. default:
  394. break;
  395. }
  396. char k;//解压计数
  397. LPCSTR pSrc = pImage;//读取起点//类似流(?):-)
  398. for(dwImageHeightCount=0;dwImageHeightCount<imgheight; dwImageHeightCount++)//Pcx 总是正向
  399. {
  400. pScan = (char *)(pScanLineBuf);
  401. ScanLinePoint = 0;
  402. //while(ScanLinePoint <dwPCXScanLineSize&&!feof(f1))//base 0;Index
  403. while(ScanLinePoint <dwPcxLineSizeCount)//base 0;Index
  404. {
  405. if((pSrc - lpData)>=iDataSize)break;
  406. ch1=(*pSrc ++)&0xFF;//fgetc() return int;
  407. if((ch1&0xc0)==0xC0)
  408. {
  409. k = ch1&0x3F;
  410. ch2 = (*pSrc ++)&0xFF;
  411. while(k--)//&&ScanLinePoint<dwPCXScanLineSize)
  412. {
  413. pScan[ScanLinePoint++] = ch2;//
  414. }
  415. }
  416. else
  417. {
  418. pScan[ScanLinePoint++] = ch1;
  419. }
  420. }//while (pcxLineWidth)//解压一行
  421. pLineDest = (WORD*)pInfo->pLineAddr[dwImageHeightCount];//当前目标 (行)
  422. //源在pLineBuf
  423. pLineSource = (BYTE *)pScanLineBuf;//源....
  424. //源地址总是不变
  425. //目标 都在此初始化
  426. pDesPixAddr555 = (WORD * )pLineDest;
  427. pDesPixAddr565 = (WORD * )pLineDest;
  428. pDesPixAddr24 = (BYTE * )pLineDest;
  429. pDesPixAddr888 = (DWORD * )pLineDest;
  430. dwImageWidthCount = 0;
  431. BYTE byIndex = 0;
  432. for(dwImageWidthCount = 0;dwImageWidthCount<imgwidth;dwImageWidthCount++)//解码一行
  433. {
  434. //****************************************//read 1 byte;
  435. byIndex = *((BYTE *)pLineSource + dwImageWidthCount);
  436. switch(dwDestFormat) // 标准图像格式(目标格式)
  437. {
  438. case DF_16_555:
  439. {
  440. if(dwImageWidthCount < imgwidth)
  441. {
  442. *pDesPixAddr555++ = descol555[byIndex];
  443. }
  444. break;
  445. }
  446. case DF_16_565:
  447. {
  448. if(dwImageWidthCount < imgwidth)
  449. {
  450. *pDesPixAddr565++ = descol565[byIndex];
  451. }
  452. break;
  453. }
  454. case DF_24:
  455. {
  456. if(dwImageWidthCount < imgwidth)
  457. {
  458. *pDesPixAddr24++ = lpPalette[byIndex].byBlue;
  459. *pDesPixAddr24++ = lpPalette[byIndex].byGreen;
  460. *pDesPixAddr24++ = lpPalette[byIndex].byRed;
  461. }
  462. break;
  463. }
  464. case DF_32:
  465. {
  466. if(dwImageWidthCount < imgwidth)
  467. {
  468. *pDesPixAddr888 = descol888[byIndex];
  469. pDesPixAddr888 ++;
  470. }
  471. break;
  472. }
  473. case DF_NULL:
  474. default:
  475. ASSERT(FALSE);
  476. pInfo->result = ER_ILLCOMM;
  477. return ER_ILLCOMM;
  478. break;
  479. }//switch(dwDestFormat)
  480. }//for dwScanLineSize;
  481. }//for imageheight
  482. delete pScanLineBuf;
  483. switch(dwDestFormat) // 标准图像格式(目标格式)
  484. {
  485. case DF_16_555:
  486. {
  487. if(descol555 != NULL)
  488. delete descol555;
  489. }
  490. break;
  491. case DF_16_565:
  492. {
  493. if(descol565 != NULL)
  494. delete descol565;
  495. }
  496. break;
  497. case DF_32:
  498. {
  499. if(descol888 != NULL)
  500. delete descol888;
  501. }
  502. break;
  503. default:
  504. break;
  505. }
  506. return ER_SUCCESS;
  507. };
  508. EXERESULT Pcx_Load_sub_24(INFOSTR * pInfo, LPCSTR lpData, int iDataSize)
  509. {
  510. const PCXFILEHEADER *const pcxFileHead=(const PCXFILEHEADER *) lpData;//文件头
  511. LPCSTR const pImage = lpData + sizeof(PCXFILEHEADER);//图像数据、读取起点
  512. // const struct PcxPalette * const lpPalette = (struct PcxPalette * )pcxFileHead->byPalette;//调色板
  513. //from yz
  514. DWORD imgheight = pInfo->imginfo.height; // 图像的高度
  515. DWORD imgwidth  = pInfo->imginfo.width; // 图像的宽度
  516. DWORD dwDestFormat = _get_desformat(pInfo);//目标格式
  517. DWORD dwPcxOneScanLineSize  = pcxFileHead->wLineBytes;// 每一扫描行的宽度(in byte)
  518. DWORD dwPcxLineSizeCount = pcxFileHead->wLineBytes * pcxFileHead->byPlanes;
  519. DWORD dwImageHeightCount, dwImageWidthCount;//用于计数
  520. //
  521. char * const pScanLineBuf = (char *)new char[dwPcxLineSizeCount + 16];//16 for 安全
  522. //解压缓冲区
  523. if(pScanLineBuf == NULL)
  524. ApiMyThrowMem();
  525. WORD * pLineDest = NULL;//目标行首地址、
  526. WORD * pLineSource = NULL;//源行首地址、
  527. pLineSource = (WORD *)pScanLineBuf;//源....
  528. // WORD * pPixDest = NULL;//目标地址、(目标地址分别定义)
  529. BYTE ch1,ch2;
  530. char * pScan = NULL;////解压指针
  531. DWORD ScanLinePoint = 0;//解压计数
  532. WORD * pDesPixAddr555 = NULL;
  533. WORD * pDesPixAddr565 = NULL;
  534. BYTE * pDesPixAddr24 = NULL;
  535. DWORD * pDesPixAddr888 = NULL;
  536. // int i;
  537. // int i, j;//, isou;
  538. // DWORD dwPCXLineSizeCount;
  539. //char * pSrc = ;
  540. char k;//解压计数
  541. // char *lpPlane0,*lpPlane1,*lpPlane2,*lpPlane3;//解码指针
  542. BYTE byPlane0,byPlane1,byPlane2;//,byPlane3;//码值
  543. // BYTE byIndex1,byIndex2,byIndex3,byIndex4;//解码值
  544. // BYTE byIndex5,byIndex6,byIndex7,byIndex8;//解码值
  545. LPCSTR pSrc = pImage;//读取起点//类似流(?):-)
  546. for(dwImageHeightCount=0;dwImageHeightCount<imgheight;dwImageHeightCount++)//Pcx 总是正向
  547. {
  548. pScan = (char *)(pScanLineBuf);
  549. ScanLinePoint = 0;
  550. //while(ScanLinePoint <dwPCXScanLineSize&&!feof(f1))//base 0;Index
  551. while(ScanLinePoint <dwPcxLineSizeCount)//base 0;Index
  552. {
  553. if((pSrc - lpData)>=iDataSize)break;
  554. ch1=(*pSrc ++)&0xFF;//fgetc() return int;
  555. if((ch1&0xc0)==0xC0)
  556. {
  557. k = ch1&0x3F;
  558. ch2 = (*pSrc ++)&0xFF;
  559. while(k--)//&&ScanLinePoint<dwPCXScanLineSize)
  560. {
  561. pScan[ScanLinePoint++] = ch2;//
  562. }
  563. }
  564. else
  565. {
  566. pScan[ScanLinePoint++] = ch1;
  567. }
  568. }//while (pcxLineWidth)//解压一行
  569. pLineDest = (WORD*)pInfo->pLineAddr[dwImageHeightCount];//当前目标 (行)
  570. //源在pLineBuf
  571. pLineSource = (WORD *)pScanLineBuf;//源....
  572. //源地址总是不变
  573. //目标 都在此初始化
  574. pDesPixAddr555 = (WORD * )pLineDest;
  575. pDesPixAddr565 = (WORD * )pLineDest;
  576. pDesPixAddr24 = (BYTE * )pLineDest;
  577. pDesPixAddr888 = (DWORD * )pLineDest;
  578. dwImageWidthCount = 0;
  579. for(ScanLinePoint=0;ScanLinePoint<dwPcxOneScanLineSize;ScanLinePoint++)//解码一行
  580. {
  581. //****************************************//read 1 byte;
  582. byPlane0 = *((char *)pScanLineBuf+dwPcxOneScanLineSize*0+ScanLinePoint);
  583. byPlane1 = *((char *)pScanLineBuf+dwPcxOneScanLineSize*1+ScanLinePoint);
  584. byPlane2 = *((char *)pScanLineBuf+dwPcxOneScanLineSize*2+ScanLinePoint);
  585. switch(dwDestFormat) // 标准图像格式(目标格式)
  586. {
  587. case DF_16_555:
  588. {
  589. if(dwImageWidthCount < imgwidth)
  590. {
  591. *pDesPixAddr555++ = _cnv_rgb_to_555(byPlane0, byPlane1, byPlane2);
  592. dwImageWidthCount ++;
  593. }
  594. break;
  595. }
  596. case DF_16_565:
  597. {
  598. if(dwImageWidthCount < imgwidth)
  599. {
  600. *pDesPixAddr565++ =  _cnv_rgb_to_565(byPlane0, byPlane1, byPlane2);
  601. dwImageWidthCount ++;
  602. }
  603. break;
  604. }
  605. case DF_24:
  606. {
  607. if(dwImageWidthCount < imgwidth)
  608. {
  609. *pDesPixAddr24++ = byPlane0;
  610. *pDesPixAddr24++ = byPlane1;
  611. *pDesPixAddr24++ = byPlane2;
  612. }
  613. break;
  614. }
  615. case DF_32:
  616. {
  617. if(dwImageWidthCount < imgwidth)
  618. {
  619. *pDesPixAddr888++ =  _cnv_rgb_to_888(byPlane0, byPlane1, byPlane2);
  620. dwImageWidthCount ++;
  621. }
  622. break;
  623. }
  624. case DF_NULL:
  625. default:
  626. ASSERT(FALSE);
  627. pInfo->result = ER_ILLCOMM;
  628. return ER_ILLCOMM;
  629. break;
  630. }//switch(dwDestFormat)
  631. }//for dwScanLineSize;
  632. }//for imageheight
  633. delete pScanLineBuf;
  634. return ER_SUCCESS;
  635. };
  636. EXERESULT Pcx_Load_sub_1(INFOSTR * pInfo, LPCSTR lpData, int iDataSize)
  637. {
  638. const PCXFILEHEADER *const pcxFileHead=(const PCXFILEHEADER *) lpData;
  639. LPCSTR const pImage = lpData + sizeof(PCXFILEHEADER);//图像数据、读取起点
  640. struct PcxPalette * lpPalette = (struct PcxPalette * )pcxFileHead->byPalette;
  641. //?*** from yz
  642. DWORD imgheight = pInfo->imginfo.height; // 图像的高度
  643. DWORD imgwidth  = pInfo->imginfo.width; // 图像的宽度
  644. DWORD pcxLineWidth = pcxFileHead->wLineBytes * pcxFileHead->byPlanes;
  645. DWORD scansize  = pInfo->imginfo.linesize;// 每一扫描行的宽度(in byte)
  646. DWORD heigCount, widthCount;
  647. DWORD dwDestFormat = _get_desformat(pInfo);
  648. PBYTE pCurPixAddr;
  649. try
  650. {
  651. BYTE pix;
  652. BYTE ch1,ch2;
  653. char *pScanLineBuf = (char *)new char[pcxLineWidth + 16];//16 for 安全
  654. if(pScanLineBuf == NULL)
  655. ApiMyThrowMem();
  656. char * pScan = NULL;
  657. WORD * pLineDest = NULL;
  658. DWORD ScanLinePoint = 0;
  659. int i, j;//, isou;
  660. // DWORD dwPCXLineSizeCount;
  661. //char * pSrc = ;
  662. char k;
  663. // char *lpPlane0,*lpPlane1,*lpPlane2,*lpPlane3;
  664. // BYTE byPlane0,byPlane1,byPlane2,byPlane3;
  665. // char * pReceiveLine; //= new char[dwBmpLineSize];
  666. LPCSTR pSrc = pImage;//图像数据、读取起点
  667. for(heigCount=0;heigCount<imgheight;heigCount++)//Pcx 总是正向
  668. {
  669. pScan = (char *)(pScanLineBuf);
  670. ScanLinePoint = 0;
  671. //while(ScanLinePoint <dwPCXScanLineSize&&!feof(f1))//base 0;Index
  672. while(ScanLinePoint <pcxLineWidth)//base 0;Index
  673. {
  674. if((pSrc - lpData)>=iDataSize)break;
  675. ch1=(*pSrc ++)&0xFF;//fgetc() return int;
  676. if((ch1&0xc0)==0xC0)
  677. {
  678. k = ch1&0x3F;
  679. ch2 = (*pSrc ++)&0xFF;
  680. while(k--)//&&ScanLinePoint<dwPCXScanLineSize)
  681. {
  682. pScan[ScanLinePoint++] = ch2;//
  683. }
  684. }
  685. else
  686. {
  687. pScan[ScanLinePoint++] = ch1;
  688. }
  689. }//line
  690. pLineDest = (WORD*)pInfo->pLineAddr[heigCount];//目标
  691. //源在pLineBuf
  692. pCurPixAddr  = (PBYTE)(pScanLineBuf); // 源图像当前行的第一个像素地址
  693. switch(dwDestFormat)//from yz
  694. {
  695. case DF_16_555:
  696. {
  697. // 以555位格式的调色板数据
  698. WORD descol555_0 = 0;
  699. WORD descol555_1 = 0;
  700. descol555_0 = _cnv_rgb_to_555(lpPalette[0].byRed, lpPalette[0].byGreen, lpPalette[0].byBlue);
  701. descol555_1 = _cnv_rgb_to_555(lpPalette[1].byRed, lpPalette[1].byGreen, lpPalette[1].byBlue);
  702. WORD *pDesPixAddr555;
  703. // 正向位图(top-down)
  704. {
  705. {
  706. //pCurPixAddr  = pLineBuf; // 源图像当前行的第一个像素地址
  707. pDesPixAddr555  = (WORD *)pLineDest;// 目标缓冲区当前行第一个像素的地址
  708. for (widthCount=0;widthCount<imgwidth;widthCount+=8)
  709. {
  710. pix = *pCurPixAddr++;
  711. if ((imgwidth-widthCount)<8) // 结尾判断
  712. j = imgwidth-widthCount;
  713. else
  714. j = 8;
  715. for (i=0;i<j;i++)
  716. {
  717. if (((BYTE)(0x80>>i))&pix) // 此位被设置
  718. {
  719. *pDesPixAddr555++ = descol555_1;
  720. }
  721. else
  722. {
  723. *pDesPixAddr555++ = descol555_0;
  724. }
  725. }
  726. }
  727. }
  728. }
  729. }
  730. break;
  731. case DF_16_565:
  732. {
  733. // 以565位格式的调色板数据
  734. WORD descol565_0 = 0;
  735. WORD descol565_1 = 0;
  736. descol565_0 = _cnv_rgb_to_565(lpPalette[0].byRed, lpPalette[0].byGreen, lpPalette[0].byBlue);
  737. descol565_1 = _cnv_rgb_to_565(lpPalette[1].byRed, lpPalette[1].byGreen, lpPalette[1].byBlue);
  738. WORD *pDesPixAddr565;
  739. // 正向位图(top-down)
  740. {
  741. {
  742. pDesPixAddr565  = (WORD *)pLineDest;// 目标缓冲区当前行第一个像素的地址
  743. for (widthCount=0;widthCount<imgwidth;widthCount+=8)
  744. {
  745. pix = *pCurPixAddr++;
  746. if ((imgwidth-widthCount)<8) // 结尾判断
  747. j = imgwidth-widthCount;
  748. else
  749. j = 8;
  750. for (i=0;i<j;i++)
  751. {
  752. if (((BYTE)(0x80>>i))&pix) // 此位被设置
  753. {
  754. *pDesPixAddr565++ = descol565_1;
  755. }
  756. else
  757. {
  758. *pDesPixAddr565++ = descol565_0;
  759. }
  760. }
  761. }
  762. }
  763. }
  764. }
  765. break;
  766. case DF_24:
  767. {
  768. // 24位格式的调色板数据
  769. BYTE red0, red1, green0, green1, blue0, blue1;
  770. red0 = lpPalette[0].byRed;
  771. green0 = lpPalette[0].byGreen;
  772. blue0 = lpPalette[0].byBlue;
  773. red1 = lpPalette[1].byRed;
  774. green1 = lpPalette[1].byGreen;
  775. blue1 = lpPalette[1].byBlue;
  776. PBYTE pDesPixAddr24;
  777. // 正向位图(top-down)
  778. {
  779. {
  780. pDesPixAddr24  = (PBYTE)pLineDest;// 目标缓冲区当前行第一个像素的地址
  781. for (widthCount=0;widthCount<imgwidth;widthCount+=8)
  782. {
  783. pix = *pCurPixAddr++;
  784. if ((imgwidth-widthCount)<8) // 结尾判断
  785. j = imgwidth-widthCount;
  786. else
  787. j = 8;
  788. for (i=0;i<j;i++)
  789. {
  790. if (((BYTE)(0x80>>i))&pix) // 此位被设置
  791. {
  792. *pDesPixAddr24++ = blue1;
  793. *pDesPixAddr24++ = green1;
  794. *pDesPixAddr24++ = red1;
  795. }
  796. else
  797. {
  798. *pDesPixAddr24++ = blue0;
  799. *pDesPixAddr24++ = green0;
  800. *pDesPixAddr24++ = red0;
  801. }
  802. }
  803. }
  804. }
  805. }
  806. }
  807. break;
  808. case DF_32:
  809. {
  810. // 以888位格式的调色板数据
  811. DWORD descol888_0 = 0;
  812. DWORD descol888_1 = 0;
  813. descol888_0 = _cnv_rgb_to_888(lpPalette[0].byRed, lpPalette[0].byGreen, lpPalette[0].byBlue);
  814. descol888_1 = _cnv_rgb_to_888(lpPalette[1].byRed, lpPalette[1].byGreen, lpPalette[1].byBlue);
  815. DWORD *pDesPixAddr888;
  816. // 正向位图(top-down)
  817. {
  818. ///for (heigCount=0;heigCount<imgheight;heigCount++)
  819. {
  820. //pCurPixAddr  = (PBYTE)(lpSou+heigCount*scansize); // 源图像当前行的第一个像素地址
  821. pDesPixAddr888  = (DWORD *)pLineDest;// 目标缓冲区当前行第一个像素的地址
  822. for (widthCount=0;widthCount<imgwidth;widthCount+=8)
  823. {
  824. pix = *pCurPixAddr++;
  825. if ((imgwidth-widthCount)<8) // 结尾判断
  826. j = imgwidth-widthCount;
  827. else
  828. j = 8;
  829. for (i=0;i<j;i++)
  830. {
  831. if (((BYTE)(0x80>>i))&pix) // 此位被设置
  832. {
  833. *pDesPixAddr888++ = descol888_1;
  834. }
  835. else
  836. {
  837. *pDesPixAddr888++ = descol888_0;
  838. }
  839. }
  840. }
  841. }
  842. }
  843. }
  844. break;
  845. case DF_NULL:
  846. default:
  847. ASSERT(FALSE);
  848. pInfo->result = ER_ILLCOMM;
  849. //return ;
  850. break;
  851. }//switch
  852. }//for height
  853. delete pScanLineBuf;
  854. }//try
  855. catch(...)
  856. {
  857. throw;
  858. }
  859. return ER_SUCCESS;
  860. };