palcommon.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923
  1. //
  2. // Copyright (c) 2009, Wei Mingzhi <whistler_wmz@users.sf.net>.
  3. // All rights reserved.
  4. //
  5. // Based on PAL MapEditor by Baldur.
  6. //
  7. // This file is part of SDLPAL.
  8. //
  9. // SDLPAL is free software: you can redistribute it and/or modify
  10. // it under the terms of the GNU General Public License as published by
  11. // the Free Software Foundation, either version 3 of the License, or
  12. // (at your option) any later version.
  13. //
  14. // This program is distributed in the hope that it will be useful,
  15. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. // GNU General Public License for more details.
  18. //
  19. // You should have received a copy of the GNU General Public License
  20. // along with this program. If not, see <http://www.gnu.org/licenses/>.
  21. //
  22. #include "palcommon.h"
  23. INT
  24. PAL_RLEBlitToSurface(
  25. LPCBITMAPRLE lpBitmapRLE,
  26. SDL_Surface *lpDstSurface,
  27. PAL_POS pos
  28. )
  29. /*++
  30. Purpose:
  31. Blit an RLE-compressed bitmap to an SDL surface.
  32. NOTE: Assume the surface is already locked, and the surface is a 8-bit one.
  33. Parameters:
  34. [IN] lpBitmapRLE - pointer to the RLE-compressed bitmap to be decoded.
  35. [OUT] lpDstSurface - pointer to the destination SDL surface.
  36. [IN] pos - position of the destination area.
  37. Return value:
  38. 0 = success, -1 = error.
  39. --*/
  40. {
  41. UINT i, j;
  42. INT x, y;
  43. UINT uiLen = 0;
  44. UINT uiWidth = 0;
  45. UINT uiHeight = 0;
  46. BYTE T;
  47. INT dx = PAL_X(pos);
  48. INT dy = PAL_Y(pos);
  49. //
  50. // Check for NULL pointer.
  51. //
  52. if (lpBitmapRLE == NULL || lpDstSurface == NULL)
  53. {
  54. return -1;
  55. }
  56. //
  57. // Skip the 0x00000002 in the file header.
  58. //
  59. if (lpBitmapRLE[0] == 0x02 && lpBitmapRLE[1] == 0x00 &&
  60. lpBitmapRLE[2] == 0x00 && lpBitmapRLE[3] == 0x00)
  61. {
  62. lpBitmapRLE += 4;
  63. }
  64. //
  65. // Get the width and height of the bitmap.
  66. //
  67. uiWidth = lpBitmapRLE[0] | (lpBitmapRLE[1] << 8);
  68. uiHeight = lpBitmapRLE[2] | (lpBitmapRLE[3] << 8);
  69. //
  70. // Calculate the total length of the bitmap.
  71. // The bitmap is 8-bpp, each pixel will use 1 byte.
  72. //
  73. uiLen = uiWidth * uiHeight;
  74. //
  75. // Start decoding and blitting the bitmap.
  76. //
  77. lpBitmapRLE += 4;
  78. for (i = 0; i < uiLen;)
  79. {
  80. T = *lpBitmapRLE++;
  81. if ((T & 0x80) && T <= 0x80 + uiWidth)
  82. {
  83. i += T - 0x80;
  84. }
  85. else
  86. {
  87. for (j = 0; j < T; j++)
  88. {
  89. //
  90. // Calculate the destination coordination.
  91. // FIXME: This could be optimized
  92. //
  93. y = (i + j) / uiWidth + dy;
  94. x = (i + j) % uiWidth + dx;
  95. //
  96. // Skip the points which are out of the surface.
  97. //
  98. if (x < 0)
  99. {
  100. j += -x - 1;
  101. continue;
  102. }
  103. else if (x >= lpDstSurface->w)
  104. {
  105. j += x - lpDstSurface->w;
  106. continue;
  107. }
  108. if (y < 0)
  109. {
  110. j += -y * uiWidth - 1;
  111. continue;
  112. }
  113. else if (y >= lpDstSurface->h)
  114. {
  115. goto end; // No more pixels needed, break out
  116. }
  117. //
  118. // Put the pixel onto the surface (FIXME: inefficient).
  119. //
  120. ((LPBYTE)lpDstSurface->pixels)[y * lpDstSurface->pitch + x] = lpBitmapRLE[j];
  121. }
  122. lpBitmapRLE += T;
  123. i += T;
  124. }
  125. }
  126. end:
  127. //
  128. // Success
  129. //
  130. return 0;
  131. }
  132. INT
  133. PAL_RLEBlitWithColorShift(
  134. LPCBITMAPRLE lpBitmapRLE,
  135. SDL_Surface *lpDstSurface,
  136. PAL_POS pos,
  137. INT iColorShift
  138. )
  139. /*++
  140. Purpose:
  141. Blit an RLE-compressed bitmap to an SDL surface.
  142. NOTE: Assume the surface is already locked, and the surface is a 8-bit one.
  143. Parameters:
  144. [IN] lpBitmapRLE - pointer to the RLE-compressed bitmap to be decoded.
  145. [OUT] lpDstSurface - pointer to the destination SDL surface.
  146. [IN] pos - position of the destination area.
  147. [IN] iColorShift - shift the color by this value.
  148. Return value:
  149. 0 = success, -1 = error.
  150. --*/
  151. {
  152. UINT i, j;
  153. INT x, y;
  154. UINT uiLen = 0;
  155. UINT uiWidth = 0;
  156. UINT uiHeight = 0;
  157. BYTE T, b;
  158. INT dx = PAL_X(pos);
  159. INT dy = PAL_Y(pos);
  160. //
  161. // Check for NULL pointer.
  162. //
  163. if (lpBitmapRLE == NULL || lpDstSurface == NULL)
  164. {
  165. return -1;
  166. }
  167. //
  168. // Skip the 0x00000002 in the file header.
  169. //
  170. if (lpBitmapRLE[0] == 0x02 && lpBitmapRLE[1] == 0x00 &&
  171. lpBitmapRLE[2] == 0x00 && lpBitmapRLE[3] == 0x00)
  172. {
  173. lpBitmapRLE += 4;
  174. }
  175. //
  176. // Get the width and height of the bitmap.
  177. //
  178. uiWidth = lpBitmapRLE[0] | (lpBitmapRLE[1] << 8);
  179. uiHeight = lpBitmapRLE[2] | (lpBitmapRLE[3] << 8);
  180. //
  181. // Calculate the total length of the bitmap.
  182. // The bitmap is 8-bpp, each pixel will use 1 byte.
  183. //
  184. uiLen = uiWidth * uiHeight;
  185. //
  186. // Start decoding and blitting the bitmap.
  187. //
  188. lpBitmapRLE += 4;
  189. for (i = 0; i < uiLen;)
  190. {
  191. T = *lpBitmapRLE++;
  192. if ((T & 0x80) && T <= 0x80 + uiWidth)
  193. {
  194. i += T - 0x80;
  195. }
  196. else
  197. {
  198. for (j = 0; j < T; j++)
  199. {
  200. //
  201. // Calculate the destination coordination.
  202. // FIXME: This could be optimized
  203. //
  204. y = (i + j) / uiWidth + dy;
  205. x = (i + j) % uiWidth + dx;
  206. //
  207. // Skip the points which are out of the surface.
  208. //
  209. if (x < 0)
  210. {
  211. j += -x - 1;
  212. continue;
  213. }
  214. else if (x >= lpDstSurface->w)
  215. {
  216. j += x - lpDstSurface->w;
  217. continue;
  218. }
  219. if (y < 0)
  220. {
  221. j += -y * uiWidth - 1;
  222. continue;
  223. }
  224. else if (y >= lpDstSurface->h)
  225. {
  226. goto end; // No more pixels needed, break out
  227. }
  228. //
  229. // Put the pixel onto the surface (FIXME: inefficient).
  230. //
  231. b = (lpBitmapRLE[j] & 0x0F);
  232. if ((INT)b + iColorShift > 0x0F)
  233. {
  234. b = 0x0F;
  235. }
  236. else if ((INT)b + iColorShift < 0)
  237. {
  238. b = 0;
  239. }
  240. else
  241. {
  242. b += iColorShift;
  243. }
  244. ((LPBYTE)lpDstSurface->pixels)[y * lpDstSurface->pitch + x] =
  245. (b | (lpBitmapRLE[j] & 0xF0));
  246. }
  247. lpBitmapRLE += T;
  248. i += T;
  249. }
  250. }
  251. end:
  252. //
  253. // Success
  254. //
  255. return 0;
  256. }
  257. INT
  258. PAL_RLEBlitMonoColor(
  259. LPCBITMAPRLE lpBitmapRLE,
  260. SDL_Surface *lpDstSurface,
  261. PAL_POS pos,
  262. BYTE bColor,
  263. INT iColorShift
  264. )
  265. /*++
  266. Purpose:
  267. Blit an RLE-compressed bitmap to an SDL surface in mono-color form.
  268. NOTE: Assume the surface is already locked, and the surface is a 8-bit one.
  269. Parameters:
  270. [IN] lpBitmapRLE - pointer to the RLE-compressed bitmap to be decoded.
  271. [OUT] lpDstSurface - pointer to the destination SDL surface.
  272. [IN] pos - position of the destination area.
  273. [IN] bColor - the color to be used while drawing.
  274. [IN] iColorShift - shift the color by this value.
  275. Return value:
  276. 0 = success, -1 = error.
  277. --*/
  278. {
  279. UINT i, j;
  280. INT x, y;
  281. UINT uiLen = 0;
  282. UINT uiWidth = 0;
  283. UINT uiHeight = 0;
  284. BYTE T, b;
  285. INT dx = PAL_X(pos);
  286. INT dy = PAL_Y(pos);
  287. //
  288. // Check for NULL pointer.
  289. //
  290. if (lpBitmapRLE == NULL || lpDstSurface == NULL)
  291. {
  292. return -1;
  293. }
  294. //
  295. // Skip the 0x00000002 in the file header.
  296. //
  297. if (lpBitmapRLE[0] == 0x02 && lpBitmapRLE[1] == 0x00 &&
  298. lpBitmapRLE[2] == 0x00 && lpBitmapRLE[3] == 0x00)
  299. {
  300. lpBitmapRLE += 4;
  301. }
  302. //
  303. // Get the width and height of the bitmap.
  304. //
  305. uiWidth = lpBitmapRLE[0] | (lpBitmapRLE[1] << 8);
  306. uiHeight = lpBitmapRLE[2] | (lpBitmapRLE[3] << 8);
  307. //
  308. // Calculate the total length of the bitmap.
  309. // The bitmap is 8-bpp, each pixel will use 1 byte.
  310. //
  311. uiLen = uiWidth * uiHeight;
  312. //
  313. // Start decoding and blitting the bitmap.
  314. //
  315. lpBitmapRLE += 4;
  316. bColor &= 0xF0;
  317. for (i = 0; i < uiLen;)
  318. {
  319. T = *lpBitmapRLE++;
  320. if ((T & 0x80) && T <= 0x80 + uiWidth)
  321. {
  322. i += T - 0x80;
  323. }
  324. else
  325. {
  326. for (j = 0; j < T; j++)
  327. {
  328. //
  329. // Calculate the destination coordination.
  330. // FIXME: This could be optimized
  331. //
  332. y = (i + j) / uiWidth + dy;
  333. x = (i + j) % uiWidth + dx;
  334. //
  335. // Skip the points which are out of the surface.
  336. //
  337. if (x < 0)
  338. {
  339. j += -x - 1;
  340. continue;
  341. }
  342. else if (x >= lpDstSurface->w)
  343. {
  344. j += x - lpDstSurface->w;
  345. continue;
  346. }
  347. if (y < 0)
  348. {
  349. j += -y * uiWidth - 1;
  350. continue;
  351. }
  352. else if (y >= lpDstSurface->h)
  353. {
  354. goto end; // No more pixels needed, break out
  355. }
  356. //
  357. // Put the pixel onto the surface (FIXME: inefficient).
  358. //
  359. b = lpBitmapRLE[j] & 0x0F;
  360. if ((INT)b + iColorShift > 0x0F)
  361. {
  362. b = 0x0F;
  363. }
  364. else if ((INT)b + iColorShift < 0)
  365. {
  366. b = 0;
  367. }
  368. else
  369. {
  370. b += iColorShift;
  371. }
  372. ((LPBYTE)lpDstSurface->pixels)[y * lpDstSurface->pitch + x] = (b | bColor);
  373. }
  374. lpBitmapRLE += T;
  375. i += T;
  376. }
  377. }
  378. end:
  379. //
  380. // Success
  381. //
  382. return 0;
  383. }
  384. INT
  385. PAL_FBPBlitToSurface(
  386. LPBYTE lpBitmapFBP,
  387. SDL_Surface *lpDstSurface
  388. )
  389. /*++
  390. Purpose:
  391. Blit an uncompressed bitmap in FBP.MKF to an SDL surface.
  392. NOTE: Assume the surface is already locked, and the surface is a 8-bit 320x200 one.
  393. Parameters:
  394. [IN] lpBitmapFBP - pointer to the RLE-compressed bitmap to be decoded.
  395. [OUT] lpDstSurface - pointer to the destination SDL surface.
  396. Return value:
  397. 0 = success, -1 = error.
  398. --*/
  399. {
  400. int x, y;
  401. LPBYTE p;
  402. if (lpBitmapFBP == NULL || lpDstSurface == NULL ||
  403. lpDstSurface->w != 320 || lpDstSurface->h != 200)
  404. {
  405. return -1;
  406. }
  407. //
  408. // simply copy everything to the surface
  409. //
  410. for (y = 0; y < 200; y++)
  411. {
  412. p = (LPBYTE)(lpDstSurface->pixels) + y * lpDstSurface->pitch;
  413. for (x = 0; x < 320; x++)
  414. {
  415. *(p++) = *(lpBitmapFBP++);
  416. }
  417. }
  418. return 0;
  419. }
  420. UINT
  421. PAL_RLEGetWidth(
  422. LPCBITMAPRLE lpBitmapRLE
  423. )
  424. /*++
  425. Purpose:
  426. Get the width of an RLE-compressed bitmap.
  427. Parameters:
  428. [IN] lpBitmapRLE - pointer to an RLE-compressed bitmap.
  429. Return value:
  430. Integer value which indicates the height of the bitmap.
  431. --*/
  432. {
  433. if (lpBitmapRLE == NULL)
  434. {
  435. return 0;
  436. }
  437. //
  438. // Skip the 0x00000002 in the file header.
  439. //
  440. if (lpBitmapRLE[0] == 0x02 && lpBitmapRLE[1] == 0x00 &&
  441. lpBitmapRLE[2] == 0x00 && lpBitmapRLE[3] == 0x00)
  442. {
  443. lpBitmapRLE += 4;
  444. }
  445. //
  446. // Return the width of the bitmap.
  447. //
  448. return lpBitmapRLE[0] | (lpBitmapRLE[1] << 8);
  449. }
  450. UINT
  451. PAL_RLEGetHeight(
  452. LPCBITMAPRLE lpBitmapRLE
  453. )
  454. /*++
  455. Purpose:
  456. Get the height of an RLE-compressed bitmap.
  457. Parameters:
  458. [IN] lpBitmapRLE - pointer of an RLE-compressed bitmap.
  459. Return value:
  460. Integer value which indicates the height of the bitmap.
  461. --*/
  462. {
  463. if (lpBitmapRLE == NULL)
  464. {
  465. return 0;
  466. }
  467. //
  468. // Skip the 0x00000002 in the file header.
  469. //
  470. if (lpBitmapRLE[0] == 0x02 && lpBitmapRLE[1] == 0x00 &&
  471. lpBitmapRLE[2] == 0x00 && lpBitmapRLE[3] == 0x00)
  472. {
  473. lpBitmapRLE += 4;
  474. }
  475. //
  476. // Return the height of the bitmap.
  477. //
  478. return lpBitmapRLE[2] | (lpBitmapRLE[3] << 8);
  479. }
  480. WORD
  481. PAL_SpriteGetNumFrames(
  482. LPCSPRITE lpSprite
  483. )
  484. /*++
  485. Purpose:
  486. Get the total number of frames of a sprite.
  487. Parameters:
  488. [IN] lpSprite - pointer to the sprite.
  489. Return value:
  490. Number of frames of the sprite.
  491. --*/
  492. {
  493. if (lpSprite == NULL)
  494. {
  495. return 0;
  496. }
  497. return (lpSprite[0] | (lpSprite[1] << 8)) - 1;
  498. }
  499. LPCBITMAPRLE
  500. PAL_SpriteGetFrame(
  501. LPCSPRITE lpSprite,
  502. INT iFrameNum
  503. )
  504. /*++
  505. Purpose:
  506. Get the pointer to the specified frame from a sprite.
  507. Parameters:
  508. [IN] lpSprite - pointer to the sprite.
  509. [IN] iFrameNum - number of the frame.
  510. Return value:
  511. Pointer to the specified frame. NULL if the frame does not exist.
  512. --*/
  513. {
  514. int imagecount, offset;
  515. if (lpSprite == NULL)
  516. {
  517. return NULL;
  518. }
  519. //
  520. // Hack for broken sprites like the Bloody-Mouth Bug
  521. //
  522. // imagecount = (lpSprite[0] | (lpSprite[1] << 8)) - 1;
  523. imagecount = (lpSprite[0] | (lpSprite[1] << 8));
  524. if (iFrameNum < 0 || iFrameNum >= imagecount)
  525. {
  526. //
  527. // The frame does not exist
  528. //
  529. return NULL;
  530. }
  531. //
  532. // Get the offset of the frame
  533. //
  534. iFrameNum <<= 1;
  535. offset = (WORD)((lpSprite[iFrameNum] | (lpSprite[iFrameNum + 1] << 8)) << 1);
  536. return &lpSprite[offset];
  537. }
  538. INT
  539. PAL_MKFGetChunkCount(
  540. FILE *fp
  541. )
  542. /*++
  543. Purpose:
  544. Get the number of chunks in an MKF archive.
  545. Parameters:
  546. [IN] fp - pointer to an fopen'ed MKF file.
  547. Return value:
  548. Integer value which indicates the number of chunks in the specified MKF file.
  549. --*/
  550. {
  551. INT iNumChunk;
  552. if (fp == NULL)
  553. {
  554. return 0;
  555. }
  556. fseek(fp, 0, SEEK_SET);
  557. fread(&iNumChunk, sizeof(INT), 1, fp);
  558. iNumChunk = (SWAP32(iNumChunk) - 4) / 4;
  559. return iNumChunk;
  560. }
  561. INT
  562. PAL_MKFGetChunkSize(
  563. UINT uiChunkNum,
  564. FILE *fp
  565. )
  566. /*++
  567. Purpose:
  568. Get the size of a chunk in an MKF archive.
  569. Parameters:
  570. [IN] uiChunkNum - the number of the chunk in the MKF archive.
  571. [IN] fp - pointer to the fopen'ed MKF file.
  572. Return value:
  573. Integer value which indicates the size of the chunk.
  574. -1 if the chunk does not exist.
  575. --*/
  576. {
  577. UINT uiOffset = 0;
  578. UINT uiNextOffset = 0;
  579. UINT uiChunkCount = 0;
  580. //
  581. // Get the total number of chunks.
  582. //
  583. uiChunkCount = PAL_MKFGetChunkCount(fp);
  584. if (uiChunkNum >= uiChunkCount)
  585. {
  586. return -1;
  587. }
  588. //
  589. // Get the offset of the specified chunk and the next chunk.
  590. //
  591. fseek(fp, 4 * uiChunkNum, SEEK_SET);
  592. fread(&uiOffset, sizeof(UINT), 1, fp);
  593. fread(&uiNextOffset, sizeof(UINT), 1, fp);
  594. uiOffset = SWAP32(uiOffset);
  595. uiNextOffset = SWAP32(uiNextOffset);
  596. //
  597. // Return the length of the chunk.
  598. //
  599. return uiNextOffset - uiOffset;
  600. }
  601. INT
  602. PAL_MKFReadChunk(
  603. LPBYTE lpBuffer,
  604. UINT uiBufferSize,
  605. UINT uiChunkNum,
  606. FILE *fp
  607. )
  608. /*++
  609. Purpose:
  610. Read a chunk from an MKF archive into lpBuffer.
  611. Parameters:
  612. [OUT] lpBuffer - pointer to the destination buffer.
  613. [IN] uiBufferSize - size of the destination buffer.
  614. [IN] uiChunkNum - the number of the chunk in the MKF archive to read.
  615. [IN] fp - pointer to the fopen'ed MKF file.
  616. Return value:
  617. Integer value which indicates the size of the chunk.
  618. -1 if there are error in parameters.
  619. -2 if buffer size is not enough.
  620. --*/
  621. {
  622. UINT uiOffset = 0;
  623. UINT uiNextOffset = 0;
  624. UINT uiChunkCount;
  625. UINT uiChunkLen;
  626. if (lpBuffer == NULL || fp == NULL || uiBufferSize == 0)
  627. {
  628. return -1;
  629. }
  630. //
  631. // Get the total number of chunks.
  632. //
  633. uiChunkCount = PAL_MKFGetChunkCount(fp);
  634. if (uiChunkNum >= uiChunkCount)
  635. {
  636. return -1;
  637. }
  638. //
  639. // Get the offset of the chunk.
  640. //
  641. fseek(fp, 4 * uiChunkNum, SEEK_SET);
  642. fread(&uiOffset, 4, 1, fp);
  643. fread(&uiNextOffset, 4, 1, fp);
  644. uiOffset = SWAP32(uiOffset);
  645. uiNextOffset = SWAP32(uiNextOffset);
  646. //
  647. // Get the length of the chunk.
  648. //
  649. uiChunkLen = uiNextOffset - uiOffset;
  650. if (uiChunkLen > uiBufferSize)
  651. {
  652. return -2;
  653. }
  654. if (uiChunkLen != 0)
  655. {
  656. fseek(fp, uiOffset, SEEK_SET);
  657. fread(lpBuffer, uiChunkLen, 1, fp);
  658. }
  659. else
  660. {
  661. return -1;
  662. }
  663. return (INT)uiChunkLen;
  664. }
  665. INT
  666. PAL_MKFGetDecompressedSize(
  667. UINT uiChunkNum,
  668. FILE *fp
  669. )
  670. /*++
  671. Purpose:
  672. Get the decompressed size of a compressed chunk in an MKF archive.
  673. Parameters:
  674. [IN] uiChunkNum - the number of the chunk in the MKF archive.
  675. [IN] fp - pointer to the fopen'ed MKF file.
  676. Return value:
  677. Integer value which indicates the size of the chunk.
  678. -1 if the chunk does not exist.
  679. --*/
  680. {
  681. DWORD buf[2];
  682. UINT uiOffset;
  683. UINT uiChunkCount;
  684. if (fp == NULL)
  685. {
  686. return -1;
  687. }
  688. //
  689. // Get the total number of chunks.
  690. //
  691. uiChunkCount = PAL_MKFGetChunkCount(fp);
  692. if (uiChunkNum >= uiChunkCount)
  693. {
  694. return -1;
  695. }
  696. //
  697. // Get the offset of the chunk.
  698. //
  699. fseek(fp, 4 * uiChunkNum, SEEK_SET);
  700. fread(&uiOffset, 4, 1, fp);
  701. uiOffset = SWAP32(uiOffset);
  702. //
  703. // Read the header.
  704. //
  705. fseek(fp, uiOffset, SEEK_SET);
  706. fread(buf, sizeof(DWORD), 2, fp);
  707. buf[0] = SWAP32(buf[0]);
  708. buf[1] = SWAP32(buf[1]);
  709. return (buf[0] != 0x315f4a59) ? -1 : (INT)buf[1];
  710. }
  711. INT
  712. PAL_MKFDecompressChunk(
  713. LPBYTE lpBuffer,
  714. UINT uiBufferSize,
  715. UINT uiChunkNum,
  716. FILE *fp
  717. )
  718. /*++
  719. Purpose:
  720. Decompress a compressed chunk from an MKF archive into lpBuffer.
  721. Parameters:
  722. [OUT] lpBuffer - pointer to the destination buffer.
  723. [IN] uiBufferSize - size of the destination buffer.
  724. [IN] uiChunkNum - the number of the chunk in the MKF archive to read.
  725. [IN] fp - pointer to the fopen'ed MKF file.
  726. Return value:
  727. Integer value which indicates the size of the chunk.
  728. -1 if there are error in parameters, or buffer size is not enough.
  729. -3 if cannot allocate memory for decompression.
  730. --*/
  731. {
  732. LPBYTE buf;
  733. int len;
  734. len = PAL_MKFGetChunkSize(uiChunkNum, fp);
  735. if (len <= 0)
  736. {
  737. return len;
  738. }
  739. buf = (LPBYTE)malloc(len);
  740. if (buf == NULL)
  741. {
  742. return -3;
  743. }
  744. PAL_MKFReadChunk(buf, len, uiChunkNum, fp);
  745. len = Decompress(buf, lpBuffer, uiBufferSize);
  746. free(buf);
  747. return len;
  748. }