KPakFile.cpp
上传用户:dzyhzl
上传日期:2019-04-29
资源大小:56270k
文件大小:16k
源码类别:

模拟服务器

开发平台:

C/C++

  1. //---------------------------------------------------------------------------
  2. // Sword3 Engine (c) 1999-2000 by Kingsoft
  3. //
  4. // File: KPakFile.cpp
  5. // Date: 2000.08.08
  6. // Code: WangWei(Daphnis)
  7. // Desc: File In Dat Class
  8. //---------------------------------------------------------------------------
  9. #include "KWin32.h"
  10. #include "KFilePath.h"
  11. #include "KPakFile.h"
  12. #ifndef _SERVER
  13. #include "KPakList.h"
  14. #endif
  15. //---------------------------------------------------------------------------
  16. // 文件读取模式 0 = 优先从磁盘读取 1 = 优先从文件包读取
  17. static int m_nPakFileMode = 0;
  18. //---------------------------------------------------------------------------
  19. // 函数: SetFileMode
  20. // 功能: 设置文件读取模式
  21. // 参数: int
  22. // 返回: void
  23. //---------------------------------------------------------------------------
  24. void g_SetPakFileMode(int nFileMode)
  25. {
  26. m_nPakFileMode = nFileMode;
  27. }
  28. #define PAK_INDEX_STORE_IN_RESERVED 0
  29. #ifndef _SERVER
  30. //----modify by Wooy to add Adjust color palette and to get rid of #@$%^& ----2003.8.19
  31. SPRHEAD* SprGetHeader(const char* pszFileName, SPROFFS*& pOffsetTable)
  32. {
  33. pOffsetTable = NULL;
  34. if(pszFileName == NULL || pszFileName[0] == 0)
  35. return NULL;
  36. KPakFile File;
  37. if (!File.Open(pszFileName))
  38. return NULL;
  39. SPRHEAD* pSpr = NULL;
  40. if (File.IsFileInPak())
  41. {
  42. //====到文件包内寻找读取图文件=====
  43. XPackElemFileRef PakRef;
  44. //_ASSERT(g_pPakList);
  45. if (g_pPakList->FindElemFile(pszFileName, PakRef))
  46. {
  47. pSpr = g_pPakList->GetSprHeader(PakRef, pOffsetTable);
  48. if (pSpr)
  49. pSpr->Reserved[PAK_INDEX_STORE_IN_RESERVED] = (WORD)(short)PakRef.nPackIndex;
  50. }
  51. }
  52. else
  53. {
  54. bool bOk = false;
  55. SPRHEAD Header;
  56. //---读文件头,并判断是否为合法的spr图文件---
  57. while(File.Read(&Header, sizeof(SPRHEAD)) == sizeof(SPRHEAD))
  58. {
  59. if (*(int*)&Header.Comment[0] != SPR_COMMENT_FLAG || Header.Colors > 256)
  60. break;
  61. //---为输出缓冲区分配空间---
  62. unsigned int uEntireSize = File.Size();
  63. pSpr = (SPRHEAD*)malloc(uEntireSize);
  64. if (pSpr == NULL)
  65. break;
  66. uEntireSize -= sizeof(SPRHEAD);
  67. //---读取spr剩下的数据---
  68. if (File.Read(&pSpr[1], uEntireSize) == uEntireSize)
  69. {
  70. //----获得图形帧索引表的开始位置---
  71. pOffsetTable = (SPROFFS*)(((char*)(pSpr)) + sizeof(SPRHEAD) + Header.Colors * 3);
  72. Header.Reserved[PAK_INDEX_STORE_IN_RESERVED] = (WORD)(-1);
  73. memcpy(pSpr, &Header, sizeof(SPRHEAD));
  74. bOk = true;
  75. }
  76. break;
  77. };
  78. if (bOk == false && pSpr)
  79. {
  80. free (pSpr);
  81. pSpr = NULL;
  82. }
  83. }
  84. File.Close();
  85. return pSpr;
  86. }
  87. void SprReleaseHeader(SPRHEAD* pSprHeader)
  88. {
  89.     if (pSprHeader)
  90. free(pSprHeader);
  91. }
  92. SPRFRAME* SprGetFrame(SPRHEAD* pSprHeader, int nFrame)
  93. {
  94. SPRFRAME* pFrame = NULL;
  95. if (pSprHeader && g_pPakList)
  96. {
  97. int nPakIndex = (short)pSprHeader->Reserved[PAK_INDEX_STORE_IN_RESERVED];
  98. if (nPakIndex >= 0)
  99. pFrame = g_pPakList->GetSprFrame(nPakIndex, pSprHeader, nFrame);
  100. }
  101. return pFrame;
  102. }
  103. void SprReleaseFrame(SPRFRAME* pFrame)
  104. {
  105.     if (pFrame)
  106. free(pFrame);
  107. }
  108. #include "JpgLib.h"
  109. #include "KDDraw.h"
  110. KSGImageContent* get_jpg_image(const char cszName[], unsigned uRGBMask16)
  111. {
  112. KPakFile File;
  113. unsigned char *pbyFileData = NULL;
  114. if (File.Open(cszName))
  115. {
  116. unsigned int uSize = File.Size();
  117. pbyFileData = (unsigned char *)malloc(uSize);
  118. if (pbyFileData)
  119. {
  120. if (File.Read(pbyFileData, uSize) != uSize)
  121. {
  122. free (pbyFileData);
  123. pbyFileData = NULL;
  124. }
  125. }
  126. }
  127. if (!pbyFileData)
  128.         return NULL;
  129. int nResult = false;
  130.     int nRetCode = false;
  131.     KSGImageContent *pImageResult = NULL;
  132. BOOL bRGB555;
  133. JPEG_INFO JpegInfo;
  134.     if (uRGBMask16 == ((unsigned)-1))
  135.     {
  136.      bRGB555 = (g_pDirectDraw->GetRGBBitMask16() == RGB_555) ? TRUE : FALSE;
  137.     }
  138.     else
  139.     {
  140.         bRGB555 = (uRGBMask16 == RGB_555) ? TRUE : FALSE;
  141.     }
  142.     nRetCode = jpeg_decode_init(bRGB555, TRUE);
  143. if(!nRetCode)
  144.         goto Exit0;
  145.          
  146. nRetCode = jpeg_decode_info(pbyFileData, &JpegInfo);
  147.     if (!nRetCode)
  148.         goto Exit0;
  149. pImageResult = (KSGImageContent *)malloc(KSG_IMAGE_CONTENT_SIZE(JpegInfo.width, JpegInfo.height));
  150.     if (!pImageResult)
  151.         goto Exit0;
  152.     pImageResult->nWidth = JpegInfo.width;
  153.     pImageResult->nHeight = JpegInfo.height;
  154. nRetCode = jpeg_decode_data(pImageResult->Data, &JpegInfo);
  155.     if (!nRetCode)
  156.         goto Exit0;
  157.     nResult = true;
  158. Exit0:
  159. free (pbyFileData);
  160.     if (!nResult && pImageResult)
  161. {
  162. free (pImageResult);
  163. pImageResult = NULL;
  164.     }
  165. return pImageResult;
  166. }
  167. void release_image(KSGImageContent *pImage)
  168. {
  169.     if (pImage)
  170.         free (pImage);
  171. }
  172. #endif
  173. //---------------------------------------------------------------------------
  174. // 功能: 购造函数
  175. //---------------------------------------------------------------------------
  176. KPakFile::KPakFile()
  177. {
  178. #ifndef _SERVER
  179. m_PackRef.nPackIndex = -1;
  180. m_PackRef.uId = 0;
  181. #endif
  182. }
  183. //---------------------------------------------------------------------------
  184. // 功能: 析造函数
  185. //---------------------------------------------------------------------------
  186. KPakFile::~KPakFile()
  187. {
  188. Close();
  189. }
  190. //---------------------------------------------------------------------------
  191. // 功能: 判断此文件是否从包中打开的
  192. //---------------------------------------------------------------------------
  193. bool KPakFile::IsFileInPak()
  194. {
  195. #ifndef _SERVER
  196. return (m_PackRef.nPackIndex >= 0 && m_PackRef.uId);
  197. #else
  198. return false;
  199. #endif
  200. }
  201. //---------------------------------------------------------------------------
  202. // 功能: 打开一个文件, 先寻找当前目录下是否有同名的单独文件,
  203. // 参数: FileName 文件名
  204. // 返回: TRUE 成功
  205. // FALSE 失败
  206. //---------------------------------------------------------------------------
  207. BOOL KPakFile::Open(const char* pszFileName)
  208. {
  209. if (pszFileName == NULL || pszFileName[0] == 0)
  210. return false;
  211. bool bOk = false;
  212. Close();
  213. #ifndef _SERVER
  214. if (m_nPakFileMode == 0) //0=优先从磁盘读取
  215. {
  216. #endif
  217. bOk = (m_File.Open((char*)pszFileName) != FALSE);
  218. #ifndef _SERVER
  219. if (bOk == false && g_pPakList)
  220. {
  221. bOk = g_pPakList->FindElemFile(pszFileName, m_PackRef);
  222. }
  223. }
  224. else //1=优先从文件包读取
  225. {
  226. if (g_pPakList)
  227. bOk = g_pPakList->FindElemFile(pszFileName, m_PackRef);
  228. if (bOk == false)
  229. bOk = (m_File.Open((char*)pszFileName) != FALSE);
  230. }
  231. #endif
  232. return bOk;
  233. }
  234. //---------------------------------------------------------------------------
  235. // 功能: 从文件中读取数据
  236. // 参数: pBuffer 缓冲区指针
  237. // dwSize 要读取的长度
  238. // 返回: 读到的字节长度
  239. //---------------------------------------------------------------------------
  240. DWORD KPakFile::Read(void* pBuffer, unsigned int uSize)
  241. {
  242. #ifndef _SERVER
  243. if (m_PackRef.nPackIndex >= 0)
  244. {
  245. if (g_pPakList->ElemFileRead(m_PackRef, pBuffer, uSize) == false)
  246. uSize = 0;
  247. }
  248. else
  249. #endif
  250. {
  251. uSize = m_File.Read(pBuffer, uSize);
  252. }
  253. return uSize;
  254. }
  255. //---------------------------------------------------------------------------
  256. // 功能: 文件读指针定位
  257. // 参数: lOffset 偏移量
  258. // dwMethod 定位方法
  259. // 返回: 文件的指针
  260. //---------------------------------------------------------------------------
  261. DWORD KPakFile::Seek(int nOffset, unsigned int uMethod)
  262. {
  263. #ifndef _SERVER
  264. if (m_PackRef.nPackIndex >= 0)
  265. {
  266. if (uMethod == FILE_BEGIN)
  267. m_PackRef.nOffset = nOffset;
  268. else if (uMethod == FILE_END)
  269. m_PackRef.nOffset = m_PackRef.nSize + nOffset;
  270. else
  271. m_PackRef.nOffset += nOffset;
  272. if (m_PackRef.nOffset > m_PackRef.nSize)
  273. m_PackRef.nOffset =  m_PackRef.nSize;
  274. else if (m_PackRef.nOffset < 0)
  275. m_PackRef.nOffset = 0;
  276. nOffset = m_PackRef.nOffset;
  277. }
  278. else
  279. #endif
  280. {
  281. nOffset = m_File.Seek(nOffset, uMethod);
  282. }
  283. return nOffset;
  284. }
  285. //---------------------------------------------------------------------------
  286. // 功能: 返回文件的指针
  287. // 返回: 文件的指针
  288. //---------------------------------------------------------------------------
  289. DWORD KPakFile::Tell()
  290. {
  291. int nOffset;
  292. #ifndef _SERVER
  293. if (m_PackRef.nPackIndex >= 0)
  294. nOffset = m_PackRef.nOffset;
  295. else
  296. #endif
  297. nOffset = m_File.Tell();
  298. return nOffset;
  299. }
  300. //---------------------------------------------------------------------------
  301. // 功能: 返回文件大小
  302. // 返回: 文件的大小 in bytes
  303. //---------------------------------------------------------------------------
  304. DWORD KPakFile::Size()
  305. {
  306. unsigned int uSize;
  307. #ifndef _SERVER
  308. if (m_PackRef.nPackIndex >= 0)
  309. uSize = m_PackRef.nSize;
  310. else
  311. #endif
  312. uSize = m_File.Size();
  313. return uSize;
  314. }
  315. //---------------------------------------------------------------------------
  316. // 功能: 关闭一个文件
  317. //---------------------------------------------------------------------------
  318. void KPakFile::Close()
  319. {
  320. #ifndef _SERVER
  321. if (m_PackRef.nPackIndex >= 0)
  322. {
  323. m_PackRef.nPackIndex = -1;
  324. m_PackRef.uId = 0;
  325. }
  326. else
  327. #endif
  328. {
  329. m_File.Close();
  330. }
  331. }
  332. //---------------------------------------------------------------------------
  333. // 每次读取数据块的大小
  334. #define BLOCK_SIZE (0x10000L)
  335. //---------------------------------------------------------------------------
  336. // 功能: 打开一个包中的文件
  337. // 参数: FileName 文件名
  338. // 返回: TRUE 成功
  339. // FALSE 失败
  340. //---------------------------------------------------------------------------
  341. /*BOOL KPakFile::OpenPak(LPSTR FileName)
  342. {
  343. if (g_pPakList == NULL)
  344. return FALSE;
  345. KAutoMutex AutoMutex(g_pPakList->GetMutexPtr());
  346. // 在所有文件包中查找要打开的文件是否存在
  347. m_nPackage = g_pPakList->Search(FileName, &m_dwFileOfs, &m_dwFileLen);
  348. if (m_nPackage < 0)
  349. return FALSE;
  350. // m_nBlocks 即块的个数, 源文件每64K打为一个包
  351. // m_nBlocks * 2 为块长度表的大小(每块的大小用一个WORD记录)
  352. m_nBlocks = (m_dwFileLen + 0xffff) >> 16;
  353. // 给 block buffer 分配内存
  354. if (!m_MemBlock.Alloc(m_nBlocks * 2))
  355. return FALSE;
  356. // 给 file buffer 分配内存64K, 为解压做准备
  357. if (!m_MemFile.Alloc(BLOCK_SIZE))
  358. return FALSE;
  359. // 给 read buffer 分配内存64K, 为解压做准备
  360. if (!m_MemRead.Alloc(BLOCK_SIZE))
  361. return FALSE;
  362. // 文件缓冲区指针
  363. m_pBuffer = (PBYTE)m_MemFile.GetMemPtr();
  364. // 每块的长度表
  365. m_pBlocks = (PWORD)m_MemBlock.GetMemPtr();
  366. // 移动到文件开始
  367. g_pPakList->Seek(m_dwFileOfs, FILE_BEGIN);
  368. // 读入每块的大小
  369. g_pPakList->Read(m_pBlocks, m_nBlocks * 2);
  370. // 第一块压缩数据的偏移量
  371. m_dwFileOfs = m_dwFileOfs + m_nBlocks * 2;
  372. // 读取压缩数据起始位置
  373. m_dwDataPtr = m_dwFileOfs;
  374. // 读指针的位置(解码后的位置) = 0;
  375. m_dwFilePtr = 0;
  376. // 成功打开文件
  377. return TRUE;
  378. }
  379. //---------------------------------------------------------------------------
  380. // 函数: ReadPak
  381. // 功能: 从文件中读取数据
  382. // 参数: pBuffer 缓冲区指针
  383. // dwSize 要读取的长度
  384. // 返回: 读到的字节长度
  385. //---------------------------------------------------------------------------
  386. DWORD KPakFile::ReadPak(PVOID pBuffer, DWORD dwSize)
  387. {
  388. KAutoMutex AutoMutex(g_pPakList->GetMutexPtr());
  389. // 如果是包中文件就从包中读
  390. UINT nBlock = 0;
  391. DWORD dwReadSize = 0;
  392. DWORD dwBlockPos = 0;
  393. PBYTE pOutBuf = (PBYTE)pBuffer;
  394. // 如果读取长度大于剩余文件长度
  395. if (m_dwFilePtr + dwSize > m_dwFileLen)
  396. {
  397. dwSize =  m_dwFileLen - m_dwFilePtr;
  398. dwReadSize = dwSize;
  399. }
  400. else
  401. {
  402. dwReadSize = dwSize;
  403. }
  404. // 已经读入的块数
  405. nBlock = m_dwFilePtr >> 16;
  406. // 已经读入小于64K块的长度
  407. dwBlockPos = m_dwFilePtr & 0xffff;
  408. // 以前读过小于64K的数据
  409. if (dwBlockPos)
  410. {
  411. // 要读的数据长度小于64K
  412. if (dwBlockPos + dwSize <= BLOCK_SIZE)
  413. {
  414. // m_pBuffer为64K大小, 上次已读入了
  415. g_MemCopyMmx(pOutBuf, m_pBuffer + dwBlockPos, dwSize);
  416. m_dwFilePtr += dwSize;
  417. // 如果此时 m_dwFilePtr 为64K 的倍数
  418. if ((m_dwFilePtr & 0xffff) == 0)
  419. m_dwDataPtr += (m_pBlocks[nBlock] == 0)? BLOCK_SIZE : m_pBlocks[nBlock];
  420. return dwSize;
  421. }
  422. // 要读的数据长度大于64K
  423. g_MemCopyMmx(pOutBuf, m_pBuffer + dwBlockPos, BLOCK_SIZE - dwBlockPos);
  424. pOutBuf += BLOCK_SIZE - dwBlockPos;
  425. m_dwDataPtr += (m_pBlocks[nBlock] == 0)? BLOCK_SIZE : m_pBlocks[nBlock];
  426. m_dwFilePtr = (++nBlock) << 16;
  427. dwSize -= (BLOCK_SIZE - dwBlockPos);
  428. }
  429. // 读入其余部分
  430. while (dwSize > 0xffff) // 大于64K
  431. {
  432. ReadBlock(pOutBuf, nBlock);
  433. pOutBuf += BLOCK_SIZE;
  434. m_dwDataPtr += (m_pBlocks[nBlock] == 0)? BLOCK_SIZE : m_pBlocks[nBlock];
  435. m_dwFilePtr = (++nBlock) << 16;
  436. dwSize -= BLOCK_SIZE;
  437. }
  438. // 刚好读完则返回
  439. if (dwSize == 0)
  440. {
  441. return dwReadSize;
  442. }
  443. // 读一个64K数据块到缓冲区
  444. ReadBlock(m_pBuffer, nBlock);
  445. // 拷贝缓冲区数据到目标地址
  446. g_MemCopyMmx(pOutBuf, m_pBuffer, dwSize);
  447. // 调整文件指针
  448. m_dwFilePtr += dwSize;
  449. // 返回读取的字节长度
  450. return dwReadSize;
  451. }
  452. //---------------------------------------------------------------------------
  453. // 函数: Seek
  454. // 功能: 文件读指针定位
  455. // 参数: lOffset 偏移量
  456. // dwMethod 定位方法
  457. // 返回: 文件的指针
  458. //---------------------------------------------------------------------------
  459. DWORD KPakFile::SeekPak(long lOffset, DWORD dwMethod)
  460. {
  461. KAutoMutex AutoMutex(g_pPakList->GetMutexPtr());
  462. if (m_nPackage < 0)
  463. {
  464. return m_File.Seek(lOffset, dwMethod);
  465. }
  466. int nFilePtr = m_dwFilePtr;
  467. switch (dwMethod)
  468. {
  469. case FILE_BEGIN:
  470. nFilePtr = lOffset;
  471. break;
  472. case FILE_END:
  473. nFilePtr = m_dwFileLen + lOffset;
  474. break;
  475. case FILE_CURRENT:
  476. nFilePtr = m_dwFilePtr + lOffset;
  477. break;
  478. }
  479. if (nFilePtr < 0)
  480. {
  481. nFilePtr = 0;
  482. }
  483. else if (nFilePtr > (int)m_dwFileLen)
  484. {
  485. nFilePtr = m_dwFileLen;
  486. }
  487. m_dwFilePtr = nFilePtr;
  488. m_dwDataPtr = m_dwFileOfs;
  489. int nBlocks = nFilePtr >> 16;
  490. for (int i = 0; i < nBlocks; i++)
  491. {
  492. m_dwDataPtr += (m_pBlocks[i] == 0)? BLOCK_SIZE : m_pBlocks[i];
  493. }
  494. if (nFilePtr & 0xffff)
  495. {
  496. ReadBlock(m_pBuffer, nBlocks);
  497. }
  498. return m_dwFilePtr;
  499. }
  500. //---------------------------------------------------------------------------
  501. // 函数: Save
  502. // 功能: 保存文件
  503. // 参数: FileName 文件名
  504. // 返回: TRUE 成功
  505. // FALSE 失败
  506. //---------------------------------------------------------------------------
  507. */
  508. BOOL KPakFile::Save(const char* pszFileName)
  509. {
  510. /* if (m_nPackage < 0)
  511. return TRUE;
  512. if (!m_File.Create(pszFileName))
  513. return FALSE;
  514. DWORD dwSize = m_dwFileLen;
  515. int nBlock = 0;
  516. // set data ptr
  517. m_dwDataPtr = m_dwFileOfs;
  518. // read blocks and write to file
  519. while (dwSize > BLOCK_SIZE)
  520. {
  521. ReadBlock(m_pBuffer, nBlock);
  522. dwSize -= BLOCK_SIZE;
  523. m_File.Write(m_pBuffer, BLOCK_SIZE);
  524. m_dwDataPtr += (m_pBlocks[nBlock] == 0)? BLOCK_SIZE : m_pBlocks[nBlock];
  525. nBlock++;
  526. }
  527. // read last block and write to file
  528. ReadBlock(m_pBuffer, nBlock);
  529. m_File.Write(m_pBuffer, dwSize);*/
  530. return FALSE;
  531. }
  532. /*
  533. //---------------------------------------------------------------------------
  534. // 函数: ReadBlock
  535. // 功能: 读一个压缩数据块
  536. // 参数: pBuffer 缓冲区指针
  537. // nBlock 块索引
  538. // 返回: void
  539. //---------------------------------------------------------------------------
  540. void KPakFile::ReadBlock(PBYTE pBuffer, int nBlock)
  541. {
  542. TCodeInfo CodeInfo;
  543. // 设置当前使用的文件包
  544. g_pPakList->SetActivePak(m_nPackage);
  545. // 填充解压缩接口结构
  546. CodeInfo.lpPack = (PBYTE)m_MemRead.GetMemPtr();
  547. CodeInfo.dwPackLen = m_pBlocks[nBlock];
  548. CodeInfo.lpData = pBuffer;
  549. CodeInfo.dwDataLen = BLOCK_SIZE;
  550. // 检查是否压缩过
  551. if (CodeInfo.dwPackLen == 0) // 没有压缩
  552. {
  553. g_pPakList->Seek(m_dwDataPtr, FILE_BEGIN);
  554. g_pPakList->Read(CodeInfo.lpData, CodeInfo.dwDataLen);
  555. return;
  556. }
  557. // 最后一块的实际长度(只有LHA用)
  558. if (nBlock == (m_nBlocks - 1))
  559. {
  560. CodeInfo.dwDataLen = m_dwFileLen - nBlock * BLOCK_SIZE;
  561. }
  562. // 移动指针,读取压缩数据,再解压缩
  563. g_pPakList->Seek(m_dwDataPtr, FILE_BEGIN);
  564. g_pPakList->Read(CodeInfo.lpPack, CodeInfo.dwPackLen);
  565. g_pPakList->Decode(&CodeInfo);
  566. }
  567. //---------------------------------------------------------------------------
  568. */