Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1698 lines
77 KiB

  1. /****************************************************************************/
  2. /* abdapi.cpp */
  3. /* */
  4. /* Bitmap Decompression API functions */
  5. /* */
  6. /* Copyright(C) Microsoft Corporation 1996-1999 */
  7. /****************************************************************************/
  8. #include <adcg.h>
  9. extern "C" {
  10. #define TRC_GROUP TRC_GROUP_CORE
  11. #define TRC_FILE "abdapi"
  12. #include <atrcapi.h>
  13. }
  14. #define TSC_HR_FILEID TSC_HR_ABDAPI_CPP
  15. #include <abdapi.h>
  16. /****************************************************************************/
  17. /* */
  18. /* See abdapi.h for descriptions of compression codes. */
  19. /* */
  20. /****************************************************************************/
  21. /****************************************************************************/
  22. /* We shouldn't have OS_WINDOWS macros in an "a" file, but this file */
  23. /* generates lots of "conditional expression is constant" warnings due */
  24. /* to the optimised nature of the code (lots of macros). */
  25. /* */
  26. /* The pragmatic (no pun intended) solution to this is to disable this */
  27. /* warning for the whole file in a way that won't affect other OSs. */
  28. /****************************************************************************/
  29. #ifdef OS_WINDOWS
  30. #pragma warning (push)
  31. #pragma warning (disable: 4127)
  32. #endif
  33. /****************************************************************************/
  34. /* Name: BDMemcpy */
  35. /* */
  36. /* Purpose: Copies a given number of bytes from source to destination. */
  37. /* Source and destination may overlap, but copy is always */
  38. /* performed upwards (from start address onwards). */
  39. /* */
  40. /* Params: pDst - pointer to destination */
  41. /* pSrc - pointer to source data */
  42. /* count - number of bytes to copy */
  43. /****************************************************************************/
  44. _inline DCVOID DCINTERNAL BDMemcpy(PDCUINT8 pDst, PDCUINT8 pSrc, DCUINT count)
  45. {
  46. #if defined(DC_DEBUG) || defined(DC_NO_UNALIGNED) || defined(_M_IA64)
  47. DCUINT i;
  48. #endif
  49. DC_BEGIN_FN("BDMemcpy");
  50. /************************************************************************/
  51. /* Bitmap decompression deliberately does overlapped memcpys, e.g. */
  52. /* from the previous bitmap row to the current bitmap row for more than */
  53. /* one row. */
  54. /* */
  55. /* When using the intrinsic memcpy (in the retail build) this works */
  56. /* fine (in the current implementation of the MS compiler), as the copy */
  57. /* always goes upwards through memory. However, if we use the MSVC */
  58. /* run-time library (in the debug build) then memcpy appears to check */
  59. /* for overlap and performs the copy so as to avoid clashing of src and */
  60. /* dst (i.e. effectively performs a memmove). Therefore this does not */
  61. /* do what we want, so manually copy the bytes in a debug build. */
  62. /* */
  63. /* This solution is a little unsatisfactory, as the operation of memset */
  64. /* is officially undefined, but the performance-critical nature of */
  65. /* this bit of code means that we really do want to use a memcpy. */
  66. /* */
  67. /* For non-Intel platforms, cannot rely on the above - so always use */
  68. /* manual version. */
  69. /* */
  70. /************************************************************************/
  71. #if defined(DC_DEBUG) || defined(DC_NO_UNALIGNED) || defined(_M_IA64)
  72. /************************************************************************/
  73. /* Debug build implementation. */
  74. /************************************************************************/
  75. for (i = 0; i < count; i++)
  76. {
  77. *pDst++ = *pSrc++;
  78. }
  79. #else
  80. /************************************************************************/
  81. /* Retail build implementation. */
  82. /************************************************************************/
  83. DC_MEMCPY(pDst, pSrc, count);
  84. #endif
  85. DC_END_FN();
  86. return;
  87. }
  88. /****************************************************************************/
  89. /* Utility macros for decoding codes */
  90. /****************************************************************************/
  91. #define BD_CHECK_READ_ONE_BYTE(pBuffer, pEnd, hr ) \
  92. CHECK_READ_ONE_BYTE(pBuffer, pEnd, hr, \
  93. (TB, _T("Decompress reads one byte end of buffer; [p=0x%x pEnd=0x%x]"), \
  94. (pBuffer), (pEnd) ))
  95. #define BD_CHECK_READ_ONE_BYTE_2ENDED(pBuffer, pStart, pEnd, hr ) \
  96. CHECK_READ_ONE_BYTE_2ENDED(pBuffer, pStart, pEnd, hr, (TB, _T("Decompress reads one byte off end of buffer; [p=0x%x pStart=0x%x pEnd=0x%x]"), \
  97. (pBuffer), (pStart), (pEnd) ))
  98. #define BD_CHECK_WRITE_ONE_BYTE(pBuffer, pEnd, hr ) \
  99. CHECK_WRITE_ONE_BYTE(pBuffer, pEnd, hr, (TB, _T("Decompress writes one byte off end of buffer; [p=0x%x pEnd=0x%x]"), \
  100. (pBuffer), (pEnd) ))
  101. #define BD_CHECK_READ_N_BYTES(pBuffer, pEnd, N, hr ) \
  102. CHECK_READ_N_BYTES(pBuffer, pEnd, N, hr, (TB, _T("Decompress reads off end of buffer; [p=0x%x pEnd=0x%x N=%u]"), \
  103. (pBuffer), (pEnd), (ULONG)(N)))
  104. #define BD_CHECK_READ_N_BYTES_2ENDED(pBuffer, pStart, pEnd, N, hr ) \
  105. CHECK_READ_N_BYTES_2ENDED(pBuffer, pStart, pEnd, N, hr, (TB, _T("Decompress reads off end of buffer; [p=0x%x pStart=0x%x pEnd=0x%x N=%u]"), \
  106. (pBuffer), (pStart), (pEnd), (ULONG)(N) ))
  107. #define BD_CHECK_WRITE_N_BYTES(pBuffer, pEnd, N, hr ) \
  108. CHECK_WRITE_N_BYTES(pBuffer, pEnd, N, hr, (TB, _T("Decompress write off end of buffer; [p=0x%x pEnd=0x%x N=%u]"), \
  109. (pBuffer), (pEnd), (ULONG)(N)))
  110. /****************************************************************************/
  111. /* Macros to extract the length from order codes */
  112. /****************************************************************************/
  113. #define EXTRACT_LENGTH(pBuffer, pEnd, length, hr) \
  114. BD_CHECK_READ_ONE_BYTE(pBuffer, pEnd, hr ) \
  115. length = *pBuffer++ & MAX_LENGTH_ORDER; \
  116. if (length == 0) \
  117. { \
  118. BD_CHECK_READ_ONE_BYTE(pBuffer, pEnd, hr ) \
  119. length = *pBuffer++ + MAX_LENGTH_ORDER + 1; \
  120. }
  121. #define EXTRACT_LENGTH_LITE(pBuffer, pEnd, length, hr ) \
  122. BD_CHECK_READ_ONE_BYTE(pBuffer, pEnd, hr ) \
  123. length = *pBuffer++ & MAX_LENGTH_ORDER_LITE; \
  124. if (length == 0) \
  125. { \
  126. BD_CHECK_READ_ONE_BYTE(pBuffer, pEnd, hr ) \
  127. length = *pBuffer++ + MAX_LENGTH_ORDER_LITE + 1; \
  128. }
  129. #define EXTRACT_LENGTH_FGBG(pBuffer, pEnd, length, hr ) \
  130. BD_CHECK_READ_ONE_BYTE(pBuffer, pEnd, hr ) \
  131. length = *pBuffer++ & MAX_LENGTH_ORDER; \
  132. if (length == 0) \
  133. { \
  134. BD_CHECK_READ_ONE_BYTE(pBuffer, pEnd, hr ) \
  135. length = *pBuffer++ + 1; \
  136. } \
  137. else \
  138. { \
  139. length = length << 3; \
  140. }
  141. #define EXTRACT_LENGTH_FGBG_LITE(pBuffer, pEnd, length, hr) \
  142. BD_CHECK_READ_ONE_BYTE(pBuffer, pEnd, hr ) \
  143. length = *pBuffer++ & MAX_LENGTH_ORDER_LITE; \
  144. if (length == 0) \
  145. { \
  146. BD_CHECK_READ_ONE_BYTE(pBuffer, pEnd, hr ) \
  147. length = *pBuffer++ + 1; \
  148. } \
  149. else \
  150. { \
  151. length = length << 3; \
  152. }
  153. /****************************************************************************/
  154. /* Macro to store an FGBG image */
  155. /* This macro expects that the function defines pDst, pEndDst, hr */
  156. /* If there is not enough data to write the full run, this will set error */
  157. /* and quit */
  158. /****************************************************************************/
  159. #define STORE_FGBG(xorbyte, fgbgChar, fgChar, bits) \
  160. { \
  161. DCUINT numbits = bits; \
  162. BD_CHECK_WRITE_N_BYTES( pDst, pEndDst, max(1, min(numbits, 8)), hr ) \
  163. if (fgbgChar & 0x01) \
  164. { \
  165. *pDst++ = (DCUINT8)(xorbyte ^ fgChar); \
  166. } \
  167. else \
  168. { \
  169. *pDst++ = xorbyte; \
  170. } \
  171. if (--numbits > 0) \
  172. { \
  173. if (fgbgChar & 0x02) \
  174. { \
  175. *pDst++ = (DCUINT8)(xorbyte ^ fgChar); \
  176. } \
  177. else \
  178. { \
  179. *pDst++ = xorbyte; \
  180. } \
  181. if (--numbits > 0) \
  182. { \
  183. if (fgbgChar & 0x04) \
  184. { \
  185. *pDst++ = (DCUINT8)(xorbyte ^ fgChar); \
  186. } \
  187. else \
  188. { \
  189. *pDst++ = xorbyte; \
  190. } \
  191. if (--numbits > 0) \
  192. { \
  193. if (fgbgChar & 0x08) \
  194. { \
  195. *pDst++ = (DCUINT8)(xorbyte ^ fgChar); \
  196. } \
  197. else \
  198. { \
  199. *pDst++ = xorbyte; \
  200. } \
  201. if (--numbits > 0) \
  202. { \
  203. if (fgbgChar & 0x10) \
  204. { \
  205. *pDst++ = (DCUINT8)(xorbyte ^ fgChar); \
  206. } \
  207. else \
  208. { \
  209. *pDst++ = xorbyte; \
  210. } \
  211. if (--numbits > 0) \
  212. { \
  213. if (fgbgChar & 0x20) \
  214. { \
  215. *pDst++ = (DCUINT8)(xorbyte ^ fgChar); \
  216. } \
  217. else \
  218. { \
  219. *pDst++ = xorbyte; \
  220. } \
  221. if (--numbits > 0) \
  222. { \
  223. if (fgbgChar & 0x40) \
  224. { \
  225. *pDst++ = (DCUINT8)(xorbyte ^ fgChar); \
  226. } \
  227. else \
  228. { \
  229. *pDst++ = xorbyte; \
  230. } \
  231. if (--numbits > 0) \
  232. { \
  233. if (fgbgChar & 0x80) \
  234. { \
  235. *pDst++ = (DCUINT8)(xorbyte ^ fgChar); \
  236. } \
  237. else \
  238. { \
  239. *pDst++ = xorbyte; \
  240. } \
  241. } \
  242. } \
  243. } \
  244. } \
  245. } \
  246. } \
  247. } \
  248. }
  249. #ifdef DC_HICOLOR
  250. /****************************************************************************/
  251. /* 8bpp decompression */
  252. /****************************************************************************/
  253. _inline HRESULT DCAPI BDDecompressBitmap8( PDCUINT8 pSrc,
  254. PDCUINT8 pDstBuffer,
  255. DCUINT compressedDataSize,
  256. DCUINT dstBufferSize,
  257. DCUINT8 bitmapBitsPerPel,
  258. DCUINT16 rowDelta)
  259. {
  260. HRESULT hr = S_OK;
  261. DCUINT codeLength;
  262. DCUINT8 codeByte;
  263. DCUINT8 codeByte2;
  264. DCUINT8 decode;
  265. DCUINT8 decodeLite;
  266. DCUINT8 decodeMega;
  267. DCUINT8 fgChar;
  268. PDCUINT8 pDst;
  269. PDCUINT8 pEndSrc;
  270. PDCUINT8 pEndDst;
  271. DCBOOL backgroundNeedsPel;
  272. DCBOOL firstLine;
  273. UNREFERENCED_PARAMETER( bitmapBitsPerPel);
  274. DC_BEGIN_FN("BDDecompressBitmap8");
  275. pEndSrc = pSrc + compressedDataSize;
  276. pDst = pDstBuffer;
  277. pEndDst = pDst + dstBufferSize;
  278. fgChar = 0xFF;
  279. backgroundNeedsPel = FALSE;
  280. firstLine = TRUE;
  281. /************************************************************************/
  282. /* */
  283. /* Main decompression loop */
  284. /* */
  285. /************************************************************************/
  286. while (pSrc < pEndSrc)
  287. {
  288. /********************************************************************/
  289. /* While we are processing the first line we should keep a look out */
  290. /* for the end of the line */
  291. /********************************************************************/
  292. if (firstLine)
  293. {
  294. if ((DCUINT)(pDst - pDstBuffer) >= rowDelta)
  295. {
  296. firstLine = FALSE;
  297. backgroundNeedsPel = FALSE;
  298. }
  299. }
  300. /********************************************************************/
  301. /* Get the decode */
  302. /********************************************************************/
  303. BD_CHECK_READ_ONE_BYTE(pSrc, pEndSrc, hr );
  304. decode = (DCUINT8)(*pSrc & CODE_MASK);
  305. decodeLite = (DCUINT8)(*pSrc & CODE_MASK_LITE);
  306. decodeMega = (DCUINT8)(*pSrc);
  307. /********************************************************************/
  308. /* BG RUN */
  309. /********************************************************************/
  310. if ((decode == CODE_BG_RUN) ||
  311. (decodeMega == CODE_MEGA_MEGA_BG_RUN))
  312. {
  313. if (decode == CODE_BG_RUN)
  314. {
  315. EXTRACT_LENGTH(pSrc, pEndSrc, codeLength, hr);
  316. }
  317. else
  318. {
  319. BD_CHECK_READ_N_BYTES(pSrc+1, pEndSrc, 2, hr);
  320. codeLength = DC_EXTRACT_UINT16_UA(pSrc+1);
  321. pSrc += 3;
  322. }
  323. TRC_DBG((TB, _T("Background run %u"),codeLength));
  324. if (!firstLine)
  325. {
  326. if (backgroundNeedsPel)
  327. {
  328. BD_CHECK_WRITE_ONE_BYTE(pDst, pEndDst, hr);
  329. BD_CHECK_READ_ONE_BYTE_2ENDED(pDst - rowDelta, pDstBuffer, pEndDst, hr);
  330. *pDst++ = (DCUINT8)(*(pDst - rowDelta) ^ fgChar);
  331. codeLength--;
  332. }
  333. BD_CHECK_READ_N_BYTES_2ENDED(pDst-rowDelta, pDstBuffer, pEndDst, codeLength, hr)
  334. BD_CHECK_WRITE_N_BYTES(pDst, pEndDst, codeLength, hr)
  335. BDMemcpy(pDst, pDst-rowDelta, codeLength);
  336. pDst += codeLength;
  337. }
  338. else
  339. {
  340. if (backgroundNeedsPel)
  341. {
  342. BD_CHECK_WRITE_ONE_BYTE(pDst, pEndDst, hr)
  343. *pDst++ = fgChar;
  344. codeLength--;
  345. }
  346. BD_CHECK_WRITE_N_BYTES(pDst, pEndDst, codeLength, hr)
  347. DC_MEMSET(pDst, 0x00, codeLength);
  348. pDst += codeLength;
  349. }
  350. /****************************************************************/
  351. /* A follow on BG run will need a pel inserted */
  352. /****************************************************************/
  353. backgroundNeedsPel = TRUE;
  354. continue;
  355. }
  356. /********************************************************************/
  357. /* For any of the other runtypes a follow on BG run does not need */
  358. /* a FG pel inserted */
  359. /********************************************************************/
  360. backgroundNeedsPel = FALSE;
  361. /********************************************************************/
  362. /* FGBG IMAGE */
  363. /********************************************************************/
  364. if ((decode == CODE_FG_BG_IMAGE) ||
  365. (decodeLite == CODE_SET_FG_FG_BG) ||
  366. (decodeMega == CODE_MEGA_MEGA_FGBG) ||
  367. (decodeMega == CODE_MEGA_MEGA_SET_FGBG))
  368. {
  369. if ((decodeMega == CODE_MEGA_MEGA_FGBG) ||
  370. (decodeMega == CODE_MEGA_MEGA_SET_FGBG))
  371. {
  372. BD_CHECK_READ_N_BYTES(pSrc+1, pEndSrc, 2, hr);
  373. codeLength = DC_EXTRACT_UINT16_UA(pSrc+1);
  374. pSrc += 3;
  375. }
  376. else
  377. {
  378. if (decode == CODE_FG_BG_IMAGE)
  379. {
  380. EXTRACT_LENGTH_FGBG(pSrc, pEndSrc, codeLength, hr);
  381. }
  382. else
  383. {
  384. EXTRACT_LENGTH_FGBG_LITE(pSrc, pEndSrc, codeLength, hr);
  385. }
  386. }
  387. if ((decodeLite == CODE_SET_FG_FG_BG) ||
  388. (decodeMega == CODE_MEGA_MEGA_SET_FGBG))
  389. {
  390. BD_CHECK_READ_ONE_BYTE(pSrc, pEndSrc, hr);
  391. fgChar = *pSrc++;
  392. TRC_DBG((TB, _T("Set FGBG image %u"),codeLength));
  393. }
  394. else
  395. {
  396. TRC_DBG((TB, _T("FGBG image %u"),codeLength));
  397. }
  398. while (codeLength > 8)
  399. {
  400. BD_CHECK_READ_ONE_BYTE(pSrc, pEndSrc, hr);
  401. codeByte = *pSrc++;
  402. if (firstLine)
  403. {
  404. STORE_FGBG(0x00, codeByte, fgChar, 8);
  405. }
  406. else
  407. {
  408. BD_CHECK_READ_ONE_BYTE_2ENDED( pDst -rowDelta, pDstBuffer, pEndDst, hr )
  409. STORE_FGBG(*(pDst - rowDelta), codeByte, fgChar, 8);
  410. }
  411. codeLength -= 8;
  412. }
  413. if (codeLength > 0)
  414. {
  415. BD_CHECK_READ_ONE_BYTE(pSrc, pEndSrc, hr);
  416. codeByte = *pSrc++;
  417. if (firstLine)
  418. {
  419. STORE_FGBG(0x00, codeByte, fgChar, codeLength);
  420. }
  421. else
  422. {
  423. BD_CHECK_READ_ONE_BYTE_2ENDED( pDst -rowDelta, pDstBuffer, pEndDst, hr )
  424. STORE_FGBG(*(pDst - rowDelta),
  425. codeByte,
  426. fgChar,
  427. codeLength);
  428. }
  429. }
  430. continue;
  431. }
  432. /********************************************************************/
  433. /* FG RUN */
  434. /********************************************************************/
  435. if ((decode == CODE_FG_RUN) ||
  436. (decodeLite == CODE_SET_FG_FG_RUN) ||
  437. (decodeMega == CODE_MEGA_MEGA_FG_RUN) ||
  438. (decodeMega == CODE_MEGA_MEGA_SET_FG_RUN))
  439. {
  440. if ((decodeMega == CODE_MEGA_MEGA_FG_RUN) ||
  441. (decodeMega == CODE_MEGA_MEGA_SET_FG_RUN))
  442. {
  443. BD_CHECK_READ_N_BYTES(pSrc+1, pEndSrc, 2, hr);
  444. codeLength = DC_EXTRACT_UINT16_UA(pSrc+1);
  445. pSrc += 3;
  446. }
  447. else
  448. {
  449. if (decode == CODE_FG_RUN)
  450. {
  451. EXTRACT_LENGTH(pSrc, pEndSrc, codeLength, hr);
  452. }
  453. else
  454. {
  455. EXTRACT_LENGTH_LITE(pSrc, pEndSrc, codeLength, hr);
  456. }
  457. }
  458. /****************************************************************/
  459. /* Push the old fgChar down to the ALT position */
  460. /****************************************************************/
  461. if ((decodeLite == CODE_SET_FG_FG_RUN) ||
  462. (decodeMega == CODE_MEGA_MEGA_SET_FG_RUN))
  463. {
  464. BD_CHECK_READ_ONE_BYTE(pSrc, pEndSrc, hr);
  465. TRC_DBG((TB, _T("Set FG run %u"),codeLength));
  466. fgChar = *pSrc++;
  467. }
  468. else
  469. {
  470. TRC_DBG((TB, _T("FG run %u"),codeLength));
  471. }
  472. BD_CHECK_WRITE_N_BYTES(pDst, pEndDst, codeLength, hr)
  473. while (codeLength-- > 0)
  474. {
  475. if (!firstLine)
  476. {
  477. BD_CHECK_READ_ONE_BYTE_2ENDED((pDst -rowDelta), pDstBuffer, pEndDst, hr)
  478. *pDst++ = (DCUINT8)(*(pDst - rowDelta) ^ fgChar);
  479. }
  480. else
  481. {
  482. *pDst++ = fgChar;
  483. }
  484. }
  485. continue;
  486. }
  487. /********************************************************************/
  488. /* DITHERED RUN */
  489. /********************************************************************/
  490. if ((decodeLite == CODE_DITHERED_RUN) ||
  491. (decodeMega == CODE_MEGA_MEGA_DITHER))
  492. {
  493. if (decodeMega == CODE_MEGA_MEGA_DITHER)
  494. {
  495. BD_CHECK_READ_N_BYTES(pSrc+1, pEndSrc, 2, hr);
  496. codeLength = DC_EXTRACT_UINT16_UA(pSrc+1);
  497. pSrc += 3;
  498. }
  499. else
  500. {
  501. EXTRACT_LENGTH_LITE(pSrc, pEndSrc, codeLength, hr);
  502. }
  503. TRC_DBG((TB, _T("Dithered run %u"),codeLength));
  504. BD_CHECK_READ_N_BYTES(pSrc, pEndSrc, 2, hr);
  505. codeByte = *pSrc++;
  506. codeByte2 = *pSrc++;
  507. BD_CHECK_WRITE_N_BYTES(pDst, pEndDst, codeLength * 2, hr)
  508. while (codeLength-- > 0)
  509. {
  510. *pDst++ = codeByte;
  511. *pDst++ = codeByte2;
  512. }
  513. continue;
  514. }
  515. /********************************************************************/
  516. /* COLOR IMAGE */
  517. /********************************************************************/
  518. if ((decode == CODE_COLOR_IMAGE) ||
  519. (decodeMega == CODE_MEGA_MEGA_CLR_IMG))
  520. {
  521. if (decodeMega == CODE_MEGA_MEGA_CLR_IMG)
  522. {
  523. BD_CHECK_READ_N_BYTES(pSrc+1, pEndSrc, 2, hr);
  524. codeLength = DC_EXTRACT_UINT16_UA(pSrc+1);
  525. pSrc += 3;
  526. }
  527. else
  528. {
  529. EXTRACT_LENGTH(pSrc, pEndSrc, codeLength, hr);
  530. }
  531. TRC_DBG((TB, _T("Color image %u"),codeLength));
  532. BD_CHECK_READ_N_BYTES(pSrc, pEndSrc, codeLength, hr)
  533. BD_CHECK_WRITE_N_BYTES(pDst, pEndDst, codeLength, hr)
  534. BDMemcpy(pDst, pSrc, codeLength);
  535. pDst += codeLength;
  536. pSrc += codeLength;
  537. continue;
  538. }
  539. /********************************************************************/
  540. /* COLOR RUN */
  541. /********************************************************************/
  542. if ((decode == CODE_COLOR_RUN) ||
  543. (decodeMega == CODE_MEGA_MEGA_COLOR_RUN))
  544. {
  545. if (decodeMega == CODE_MEGA_MEGA_COLOR_RUN)
  546. {
  547. BD_CHECK_READ_N_BYTES(pSrc+1, pEndSrc, 2, hr);
  548. codeLength = DC_EXTRACT_UINT16_UA(pSrc+1);
  549. pSrc += 3;
  550. }
  551. else
  552. {
  553. EXTRACT_LENGTH(pSrc, pEndSrc, codeLength, hr);
  554. }
  555. TRC_DBG((TB, _T("Color run %u"),codeLength));
  556. BD_CHECK_READ_ONE_BYTE(pSrc, pEndSrc, hr)
  557. codeByte = *pSrc++;
  558. BD_CHECK_WRITE_N_BYTES(pDst, pEndDst, codeLength, hr)
  559. DC_MEMSET(pDst, codeByte, codeLength);
  560. pDst += codeLength;
  561. continue;
  562. }
  563. /********************************************************************/
  564. /* If we get here then the code must be a special one */
  565. /********************************************************************/
  566. TRC_DBG((TB, _T("Special code %#x"),decodeMega));
  567. switch (decodeMega)
  568. {
  569. case CODE_BLACK:
  570. {
  571. BD_CHECK_WRITE_ONE_BYTE(pDst, pEndDst, hr);
  572. *pDst++ = 0x00;
  573. }
  574. break;
  575. case CODE_WHITE:
  576. {
  577. BD_CHECK_WRITE_ONE_BYTE(pDst, pEndDst, hr);
  578. *pDst++ = 0xFF;
  579. }
  580. break;
  581. /****************************************************************/
  582. /* Ignore the unreachable code warnings that follow */
  583. /* Simply because we use the STORE_FGBG macro with a constant */
  584. /* value */
  585. /****************************************************************/
  586. case CODE_SPECIAL_FGBG_1:
  587. {
  588. if (firstLine)
  589. {
  590. STORE_FGBG(0x00, SPECIAL_FGBG_CODE_1, fgChar, 8);
  591. }
  592. else
  593. {
  594. BD_CHECK_READ_ONE_BYTE_2ENDED(pDst-rowDelta, pDstBuffer, pEndDst, hr);
  595. STORE_FGBG(*(pDst - rowDelta),
  596. SPECIAL_FGBG_CODE_1,
  597. fgChar,
  598. 8);
  599. }
  600. }
  601. break;
  602. case CODE_SPECIAL_FGBG_2:
  603. {
  604. if (firstLine)
  605. {
  606. STORE_FGBG(0x00,
  607. SPECIAL_FGBG_CODE_2,
  608. fgChar,
  609. 8);
  610. }
  611. else
  612. {
  613. BD_CHECK_READ_ONE_BYTE_2ENDED(pDst-rowDelta, pDstBuffer, pEndDst, hr);
  614. STORE_FGBG(*(pDst - rowDelta),
  615. SPECIAL_FGBG_CODE_2,
  616. fgChar,
  617. 8);
  618. }
  619. }
  620. break;
  621. default:
  622. {
  623. TRC_ERR((TB, _T("Invalid compression data %x"),decodeMega));
  624. }
  625. break;
  626. }
  627. pSrc++;
  628. }
  629. TRC_DBG((TB, _T("Decompressed to %d"), pDst-pDstBuffer));
  630. DC_EXIT_POINT:
  631. DC_END_FN();
  632. return hr;
  633. }
  634. /****************************************************************************/
  635. /* 15bpp decompression */
  636. /****************************************************************************/
  637. _inline HRESULT DCAPI BDDecompressBitmap15(PDCUINT8 pSrc,
  638. PDCUINT8 pDstBuffer,
  639. DCUINT srcDataSize,
  640. DCUINT dstBufferSize,
  641. DCUINT16 rowDelta)
  642. /****************************************************************************/
  643. /* Function name */
  644. /****************************************************************************/
  645. #define BC_FN_NAME "BDDecompressBitmap15"
  646. /****************************************************************************/
  647. /* Data type of a pixel */
  648. /****************************************************************************/
  649. #define BC_PIXEL DCUINT16
  650. /****************************************************************************/
  651. /* Length in bytes of a pixel */
  652. /****************************************************************************/
  653. #define BC_PIXEL_LEN 2
  654. /****************************************************************************/
  655. /* Default fgPel */
  656. /****************************************************************************/
  657. #define BC_DEFAULT_FGPEL 0x0000FF7F
  658. /****************************************************************************/
  659. /* Macro to move to the next pixel in the buffer (modifies pPos) */
  660. /****************************************************************************/
  661. #define BC_TO_NEXT_PIXEL(pPos) pPos += 2
  662. /****************************************************************************/
  663. /* Macro to returns the value of the pixel at pPos (doesn't modify pPos) */
  664. /****************************************************************************/
  665. #define BC_GET_PIXEL(pPos) ((DCUINT16) (((PDCUINT8)(pPos))[1]) | \
  666. (DCUINT16) ((((PDCUINT8)(pPos))[0]) << 8) )
  667. /****************************************************************************/
  668. /* Macro to insert a pixel value pel at position pPos (doesn't modify pPos) */
  669. /* */
  670. /* pel may well be an expression (e.g. a BC_GET_PIXEL macro) so evaluate */
  671. /* it once into a local variable. */
  672. /****************************************************************************/
  673. #define BC_SET_PIXEL(pPos, pel) \
  674. { \
  675. BC_PIXEL val = pel; \
  676. (((PDCUINT8)(pPos))[1]) = (DCUINT8)( (val) & 0x00FF); \
  677. (((PDCUINT8)(pPos))[0]) = (DCUINT8)(((val)>>8) & 0x00FF); \
  678. }
  679. /****************************************************************************/
  680. /* Include the function body */
  681. /****************************************************************************/
  682. #include <bdcom.c>
  683. /****************************************************************************/
  684. /* Undefine everything */
  685. /****************************************************************************/
  686. #undef BC_FN_NAME
  687. #undef BC_PIXEL
  688. #undef BC_PIXEL_LEN
  689. #undef BC_TO_NEXT_PIXEL
  690. #undef BC_GET_PIXEL
  691. #undef BC_SET_PIXEL
  692. #undef BC_DEFAULT_FGPEL
  693. /****************************************************************************/
  694. /* 16bpp decompression */
  695. /****************************************************************************/
  696. _inline HRESULT DCAPI BDDecompressBitmap16(PDCUINT8 pSrc,
  697. PDCUINT8 pDstBuffer,
  698. DCUINT srcDataSize,
  699. DCUINT dstBufferSize,
  700. DCUINT16 rowDelta)
  701. /****************************************************************************/
  702. /* Function name */
  703. /****************************************************************************/
  704. #define BC_FN_NAME "BDDecompressBitmap16"
  705. /****************************************************************************/
  706. /* Data type of a pixel */
  707. /****************************************************************************/
  708. #define BC_PIXEL DCUINT16
  709. /****************************************************************************/
  710. /* Length in bytes of a pixel */
  711. /****************************************************************************/
  712. #define BC_PIXEL_LEN 2
  713. /****************************************************************************/
  714. /* Default fgPel */
  715. /****************************************************************************/
  716. #define BC_DEFAULT_FGPEL 0x0000FFFF
  717. /****************************************************************************/
  718. /* Macro to move to the next pixel in the buffer (modifies pPos) */
  719. /****************************************************************************/
  720. #define BC_TO_NEXT_PIXEL(pPos) pPos += 2
  721. /****************************************************************************/
  722. /* Macro to returns the value of the pixel at pPos (doesn't modify pPos) */
  723. /****************************************************************************/
  724. #define BC_GET_PIXEL(pPos) ((DCUINT16) (((PDCUINT8)(pPos))[1]) | \
  725. (DCUINT16) ((((PDCUINT8)(pPos))[0]) << 8) )
  726. /****************************************************************************/
  727. /* Macro to insert a pixel value pel at position pPos (doesn't modify pPos) */
  728. /* */
  729. /* pel may well be an expression (e.g. a BC_GET_PIXEL macro) so evaluate */
  730. /* it once into a local variable. */
  731. /****************************************************************************/
  732. #define BC_SET_PIXEL(pPos, pel) \
  733. { \
  734. BC_PIXEL val = pel; \
  735. (((PDCUINT8)(pPos))[1]) = (DCUINT8)( (val) & 0x00FF); \
  736. (((PDCUINT8)(pPos))[0]) = (DCUINT8)(((val)>>8) & 0x00FF); \
  737. }
  738. /****************************************************************************/
  739. /* Include the function body */
  740. /****************************************************************************/
  741. #include <bdcom.c>
  742. /****************************************************************************/
  743. /* Undefine everything */
  744. /****************************************************************************/
  745. #undef BC_FN_NAME
  746. #undef BC_PIXEL
  747. #undef BC_PIXEL_LEN
  748. #undef BC_TO_NEXT_PIXEL
  749. #undef BC_GET_PIXEL
  750. #undef BC_SET_PIXEL
  751. #undef BC_DEFAULT_FGPEL
  752. /****************************************************************************/
  753. /* 24bpp decompression */
  754. /****************************************************************************/
  755. _inline HRESULT DCAPI BDDecompressBitmap24(PDCUINT8 pSrc,
  756. PDCUINT8 pDstBuffer,
  757. DCUINT srcDataSize,
  758. DCUINT dstBufferSize,
  759. DCUINT16 rowDelta)
  760. /****************************************************************************/
  761. /* Function name */
  762. /****************************************************************************/
  763. #define BC_FN_NAME "BDDecompressBitmap24"
  764. /****************************************************************************/
  765. /* Data type of a pixel */
  766. /****************************************************************************/
  767. #define BC_PIXEL DCUINT32
  768. /****************************************************************************/
  769. /* Length in bytes of a pixel */
  770. /****************************************************************************/
  771. #define BC_PIXEL_LEN 3
  772. /****************************************************************************/
  773. /* Default fgPel */
  774. /****************************************************************************/
  775. #define BC_DEFAULT_FGPEL 0x00FFFFFF
  776. /****************************************************************************/
  777. /* Macro to move to the next pixel in the buffer (modifies pPos) */
  778. /****************************************************************************/
  779. #define BC_TO_NEXT_PIXEL(pPos) pPos += 3
  780. /****************************************************************************/
  781. /* Macro to returns the value of the pixel at pPos (doesn't modify pPos) */
  782. /****************************************************************************/
  783. #define BC_GET_PIXEL(pPos) ( \
  784. (DCUINT32) ( (DCUINT16)(((PDCUINT8)(pPos))[2]) ) | \
  785. (DCUINT32) (((DCUINT16)(((PDCUINT8)(pPos))[1])) << 8) | \
  786. (DCUINT32) (((DCUINT32)(((PDCUINT8)(pPos))[0])) << 16) )
  787. /****************************************************************************/
  788. /* Macro to insert a pixel value pel at position pPos (doesn't modify pPos) */
  789. /* */
  790. /* pel may well be an expression (e.g. a BC_GET_PIXEL macro) so evaluate */
  791. /* it once into a local variable. */
  792. /****************************************************************************/
  793. #define BC_SET_PIXEL(pPos, pel) \
  794. { \
  795. BC_PIXEL val = pel; \
  796. (((PDCUINT8)(pPos))[2]) = (DCUINT8)((val) & 0x000000FF); \
  797. (((PDCUINT8)(pPos))[1]) = (DCUINT8)(((val)>>8) & 0x000000FF); \
  798. (((PDCUINT8)(pPos))[0]) = (DCUINT8)(((val)>>16) & 0x000000FF); \
  799. }
  800. /****************************************************************************/
  801. /* Include the function body */
  802. /****************************************************************************/
  803. #include <bdcom.c>
  804. /****************************************************************************/
  805. /* Undefine everything */
  806. /****************************************************************************/
  807. #undef BC_FN_NAME
  808. #undef BC_PIXEL
  809. #undef BC_PIXEL_LEN
  810. #undef BC_TO_NEXT_PIXEL
  811. #undef BC_GET_PIXEL
  812. #undef BC_SET_PIXEL
  813. #undef BC_DEFAULT_FGPEL
  814. /****************************************************************************/
  815. /* 32bpp decompression */
  816. /****************************************************************************/
  817. _inline HRESULT DCAPI BDDecompressBitmap32(PDCUINT8 pSrc,
  818. PDCUINT8 pDstBuffer,
  819. DCUINT srcDataSize,
  820. DCUINT dstBufferSize,
  821. DCUINT16 rowDelta)
  822. /****************************************************************************/
  823. /* Function name */
  824. /****************************************************************************/
  825. #define BC_FN_NAME "BDDecompressBitmap32"
  826. /****************************************************************************/
  827. /* Data type of a pixel */
  828. /****************************************************************************/
  829. #define BC_PIXEL DCUINT32
  830. /****************************************************************************/
  831. /* Length in bytes of a pixel */
  832. /****************************************************************************/
  833. #define BC_PIXEL_LEN 4
  834. /****************************************************************************/
  835. /* Default fgPel */
  836. /****************************************************************************/
  837. #define BC_DEFAULT_FGPEL 0xFFFFFFFF
  838. /****************************************************************************/
  839. /* Macro to move to the next pixel in the buffer (modifies pPos) */
  840. /****************************************************************************/
  841. #define BC_TO_NEXT_PIXEL(pPos) pPos += 4
  842. /****************************************************************************/
  843. /* Macro to returns the value of the pixel at pPos (doesn't modify pPos) */
  844. /****************************************************************************/
  845. #define BC_GET_PIXEL(pPos) ( \
  846. (DCUINT32) ( (DCUINT16)(((PDCUINT8)(pPos))[3]) ) | \
  847. (DCUINT32) (((DCUINT16)(((PDCUINT8)(pPos))[2])) << 8) | \
  848. (DCUINT32) (((DCUINT32)(((PDCUINT8)(pPos))[1])) << 16) | \
  849. (DCUINT32) (((DCUINT32)(((PDCUINT8)(pPos))[0])) << 24))
  850. /****************************************************************************/
  851. /* Macro to insert a pixel value pel at position pPos (doesn't modify pPos) */
  852. /* */
  853. /* pel may well be an expression (e.g. a BC_GET_PIXEL macro) so evaluate */
  854. /* it once into a local variable. */
  855. /****************************************************************************/
  856. #define BC_SET_PIXEL(pPos, pel) \
  857. { \
  858. BC_PIXEL val = pel; \
  859. (((PDCUINT8)(pPos))[3]) = (DCUINT8)((val) & 0x000000FF); \
  860. (((PDCUINT8)(pPos))[2]) = (DCUINT8)(((val)>>8) & 0x000000FF); \
  861. (((PDCUINT8)(pPos))[1]) = (DCUINT8)(((val)>>16) & 0x000000FF); \
  862. (((PDCUINT8)(pPos))[0]) = (DCUINT8)(((val)>>24) & 0x000000FF); \
  863. }
  864. /****************************************************************************/
  865. /* Include the function body */
  866. /****************************************************************************/
  867. #include <bdcom.c>
  868. /****************************************************************************/
  869. /* Undefine everything */
  870. /****************************************************************************/
  871. #undef BC_FN_NAME
  872. #undef BC_PIXEL
  873. #undef BC_PIXEL_LEN
  874. #undef BC_TO_NEXT_PIXEL
  875. #undef BC_GET_PIXEL
  876. #undef BC_SET_PIXEL
  877. #undef BC_DEFAULT_FGPEL
  878. /****************************************************************************/
  879. /* Name: BD_DecompressBitmap */
  880. /* */
  881. /* Purpose: Decompresses compressed bitmap data */
  882. /* */
  883. /* Params: IN - pCompressedData: pointer to compressed bitmap data */
  884. /* OUT - pDstBitmap: pointer to buffer for decompressed data */
  885. /* IN - srcDataSize: the compressed data size */
  886. /* IN - bitmapBitsPerPel: the bits per pel of the data */
  887. /****************************************************************************/
  888. HRESULT DCAPI BD_DecompressBitmap( PDCUINT8 pCompressedData,
  889. PDCUINT8 pDstBuffer,
  890. DCUINT srcDataSize,
  891. DCUINT dstBufferSize,
  892. DCUINT noBCHeader,
  893. DCUINT8 bitmapBitsPerPel,
  894. DCUINT16 bitmapWidth,
  895. DCUINT16 bitmapHeight)
  896. {
  897. HRESULT hr = S_OK;
  898. PDCUINT8 pSrc;
  899. DCUINT16 rowDelta;
  900. DCUINT compressedDataSize;
  901. PTS_CD_HEADER pCompDataHeader;
  902. #ifdef DC_NO_UNALIGNED
  903. TS_CD_HEADER compDataHeader;
  904. #endif
  905. #ifdef DC_DEBUG
  906. DCUINT32 decompLen;
  907. #endif
  908. UNREFERENCED_PARAMETER( bitmapHeight);
  909. DC_BEGIN_FN("BD_DecompressBitmap");
  910. TRC_ASSERT( (pCompressedData != NULL),
  911. (TB, _T("Invalid pCompressedData(%p)"), pCompressedData) );
  912. TRC_ASSERT( (pDstBuffer != NULL),
  913. (TB, _T("Invalid pDstBuffer(%p)"), pDstBuffer) );
  914. TRC_ASSERT( (srcDataSize != 0),
  915. (TB, _T("Invalid srcDataSize(%u)"), srcDataSize) );
  916. TRC_ASSERT( (dstBufferSize != 0),
  917. (TB, _T("Invalid dstBufferSize(%u)"), dstBufferSize) );
  918. #ifdef DC_HICOLOR
  919. #ifdef DC_DEBUG
  920. /************************************************************************/
  921. /* Check the decompression buffer is big enough */
  922. /************************************************************************/
  923. {
  924. decompLen = bitmapWidth * bitmapHeight *
  925. ((bitmapBitsPerPel + 7) / 8);
  926. if (IsBadWritePtr(pDstBuffer, decompLen))
  927. {
  928. TRC_ABORT((TB, _T("Decompression buffer %p not big enough for") \
  929. _T(" bitmap length %d"), pDstBuffer, decompLen ));
  930. }
  931. }
  932. #endif
  933. #else
  934. TRC_ASSERT( (bitmapBitsPerPel == 8),
  935. (TB, _T("Invalid bitmapBitsPerPel(%u)"), bitmapBitsPerPel) );
  936. #endif
  937. /************************************************************************/
  938. /* Initialize variables before main loop. */
  939. /* */
  940. /* No bitmap compression header included */
  941. /************************************************************************/
  942. if (noBCHeader)
  943. {
  944. compressedDataSize = srcDataSize;
  945. pSrc = pCompressedData;
  946. rowDelta = TS_BYTES_IN_SCANLINE(bitmapWidth,
  947. bitmapBitsPerPel);
  948. }
  949. else
  950. {
  951. /************************************************************************/
  952. /* Work out the location in the source data of each component. */
  953. /* Make sure this is naturally aligned (for RISC platforms) */
  954. /************************************************************************/
  955. BD_CHECK_READ_N_BYTES(pCompressedData, (PBYTE)pCompressedData + srcDataSize,
  956. sizeof(TS_CD_HEADER), hr);
  957. #ifdef DC_NO_UNALIGNED
  958. DC_MEMCPY(&compDataHeader, pCompressedData, sizeof(TS_CD_HEADER));
  959. pCompDataHeader = &compDataHeader;
  960. #else
  961. pCompDataHeader = (PTS_CD_HEADER)pCompressedData;
  962. #endif
  963. /********************************************************************/
  964. /* Bitmap compression header included */
  965. /********************************************************************/
  966. compressedDataSize = pCompDataHeader->cbCompMainBodySize;
  967. BD_CHECK_READ_N_BYTES(pCompressedData, pCompressedData + srcDataSize,
  968. compressedDataSize + sizeof(TS_CD_HEADER), hr);
  969. pSrc = pCompressedData + sizeof(TS_CD_HEADER);
  970. rowDelta = pCompDataHeader->cbScanWidth;
  971. if (rowDelta != TS_BYTES_IN_SCANLINE(bitmapWidth, bitmapBitsPerPel)) {
  972. TRC_ABORT((TB, _T("rowDelta in TS_CD_HEADER incorrect ")
  973. _T("[got %u expected %u]"), rowDelta,
  974. TS_BYTES_IN_SCANLINE(bitmapWidth, bitmapBitsPerPel)));
  975. hr = E_TSC_CORE_LENGTH;
  976. DC_QUIT;
  977. }
  978. }
  979. /************************************************************************/
  980. /* Call the appropriate decompress function, based on the color depth */
  981. /************************************************************************/
  982. switch (bitmapBitsPerPel)
  983. {
  984. case 32:
  985. {
  986. hr = BDDecompressBitmap32 (pSrc,
  987. pDstBuffer,
  988. compressedDataSize,
  989. dstBufferSize,
  990. rowDelta);
  991. }
  992. break;
  993. case 24:
  994. {
  995. hr = BDDecompressBitmap24 (pSrc,
  996. pDstBuffer,
  997. compressedDataSize,
  998. dstBufferSize,
  999. rowDelta);
  1000. }
  1001. break;
  1002. case 16:
  1003. {
  1004. hr = BDDecompressBitmap16 (pSrc,
  1005. pDstBuffer,
  1006. compressedDataSize,
  1007. dstBufferSize,
  1008. rowDelta);
  1009. }
  1010. break;
  1011. case 15:
  1012. {
  1013. hr = BDDecompressBitmap15 (pSrc,
  1014. pDstBuffer,
  1015. compressedDataSize,
  1016. dstBufferSize,
  1017. rowDelta);
  1018. }
  1019. break;
  1020. case 8:
  1021. default:
  1022. {
  1023. hr = BDDecompressBitmap8 (pSrc,
  1024. pDstBuffer,
  1025. compressedDataSize,
  1026. dstBufferSize,
  1027. bitmapBitsPerPel,
  1028. rowDelta);
  1029. }
  1030. break;
  1031. }
  1032. DC_EXIT_POINT:
  1033. return hr;
  1034. }
  1035. #else
  1036. /****************************************************************************/
  1037. /* Name: BD_DecompressBitmap */
  1038. /* */
  1039. /* Purpose: Decompresses compressed bitmap data */
  1040. /* */
  1041. /* Params: IN - pCompressedData: pointer to compressed bitmap data */
  1042. /* OUT - pDstBitmap: pointer to buffer for decompressed data */
  1043. /* IN - srcDataSize: the compressed data size */
  1044. /* IN - bitmapBitsPerPel: the bits per pel of the data */
  1045. /****************************************************************************/
  1046. HRESULT DCAPI BD_DecompressBitmap( PDCUINT8 pCompressedData,
  1047. PDCUINT8 pDstBuffer,
  1048. DCUINT srcDataSize,
  1049. DCUINT dstBufferSize,
  1050. DCUINT noBCHeader,
  1051. DCUINT8 bitmapBitsPerPel,
  1052. DCUINT16 bitmapWidth,
  1053. DCUINT16 bitmapHeight )
  1054. {
  1055. HRESULT hr = S_OK;
  1056. UNREFERENCED_PARAMETER(bitmapHeight);
  1057. #ifdef DC_NO_UNALIGNED
  1058. TS_CD_HEADER compDataHeader;
  1059. #endif
  1060. PTS_CD_HEADER pCompDataHeader;
  1061. DCUINT compressedDataSize;
  1062. DCUINT codeLength;
  1063. DCUINT8 codeByte;
  1064. DCUINT8 codeByte2;
  1065. DCUINT8 decode;
  1066. DCUINT8 decodeLite;
  1067. DCUINT8 decodeMega;
  1068. DCUINT8 fgChar;
  1069. PDCUINT8 pSrc;
  1070. PDCUINT8 pDst;
  1071. PDCUINT8 pEndSrc;
  1072. PDCUINT8 pEndDst;
  1073. DCBOOL backgroundNeedsPel;
  1074. DCBOOL firstLine;
  1075. DCUINT rowDelta;
  1076. DC_BEGIN_FN("BD_DecompressBitmap");
  1077. TRC_ASSERT( (pCompressedData != NULL),
  1078. (TB, _T("Invalid pCompressedData(%p)"), pCompressedData) );
  1079. TRC_ASSERT( (pDstBuffer != NULL),
  1080. (TB, _T("Invalid pDstBuffer(%p)"), pDstBuffer) );
  1081. TRC_ASSERT( (srcDataSize != 0),
  1082. (TB, _T("Invalid srcDataSize(%u)"), srcDataSize) );
  1083. TRC_ASSERT( (dstBufferSize != 0),
  1084. (TB, _T("Invalid dstBufferSize(%u)"), dstBufferSize) );
  1085. TRC_ASSERT( (bitmapBitsPerPel == 8),
  1086. (TB, _T("Invalid bitmapBitsPerPel(%u)"), bitmapBitsPerPel) );
  1087. /************************************************************************/
  1088. /* Trace the important parameters. */
  1089. /************************************************************************/
  1090. TRC_DBG((TB, _T("pData(%p) pDst(%p) cbSrc(%u) cbDst(%u)"),
  1091. pCompressedData, pDstBuffer, srcDataSize, dstBufferSize));
  1092. /************************************************************************/
  1093. /* Initialize variables before main loop. */
  1094. /************************************************************************/
  1095. // no bitmap compression header included
  1096. if (noBCHeader) {
  1097. compressedDataSize = srcDataSize;
  1098. pSrc = pCompressedData;
  1099. rowDelta = TS_BYTES_IN_SCANLINE(bitmapWidth, bitmapBitsPerPel);
  1100. }
  1101. // bitmap compression header included
  1102. else {
  1103. /************************************************************************/
  1104. /* Work out the location in the source data of each component. */
  1105. /* Make sure this is naturally aligned (for RISC platforms) */
  1106. /************************************************************************/
  1107. BD_CHECK_READ_N_BYTES(pCompressedData, pCompressedData + srcDataSize,
  1108. sizeof(TS_CD_HEADER), hr);
  1109. #ifdef DC_NO_UNALIGNED
  1110. DC_MEMCPY(&compDataHeader, pCompressedData, sizeof(TS_CD_HEADER));
  1111. pCompDataHeader = &compDataHeader;
  1112. #else
  1113. pCompDataHeader = (PTS_CD_HEADER)pCompressedData;
  1114. #endif
  1115. compressedDataSize = pCompDataHeader->cbCompMainBodySize;
  1116. BD_CHECK_READ_N_BYTES(pCompressedData, pCompressedData + srcDataSize,
  1117. compressedDataSize + sizeof(TS_CD_HEADER), hr);
  1118. pSrc = pCompressedData + sizeof(TS_CD_HEADER);
  1119. rowDelta = pCompDataHeader->cbScanWidth;
  1120. if (rowDelta != TS_BYTES_IN_SCANLINE(bitmapWidth, bitmapBitsPerPel)) {
  1121. TRC_ABORT((TB, _T("rowDelta in TS_CD_HEADER incorrect ")
  1122. _T("[got %u expected %u]"), rowDelta,
  1123. TS_BYTES_IN_SCANLINE(bitmapWidth, bitmapBitsPerPel)));
  1124. hr = E_TSC_CORE_LENGTH;
  1125. DC_QUIT;
  1126. }
  1127. }
  1128. pEndSrc = pSrc + compressedDataSize;
  1129. pDst = pDstBuffer;
  1130. pEndDst = pDst + dstBufferSize;
  1131. fgChar = 0xFF;
  1132. backgroundNeedsPel = FALSE;
  1133. firstLine = TRUE;
  1134. /************************************************************************/
  1135. /* */
  1136. /* Main decompression loop */
  1137. /* */
  1138. /************************************************************************/
  1139. while(pSrc < pEndSrc)
  1140. {
  1141. /********************************************************************/
  1142. /* While we are processing the first line we should keep a look out */
  1143. /* for the end of the line */
  1144. /********************************************************************/
  1145. if (firstLine)
  1146. {
  1147. if ((DCUINT)(pDst - pDstBuffer) >= rowDelta)
  1148. {
  1149. firstLine = FALSE;
  1150. backgroundNeedsPel = FALSE;
  1151. }
  1152. }
  1153. /********************************************************************/
  1154. /* Get the decode */
  1155. /********************************************************************/
  1156. BD_CHECK_READ_ONE_BYTE(pSrc, pEndSrc, hr);
  1157. decode = (DCUINT8)(*pSrc & CODE_MASK);
  1158. decodeLite = (DCUINT8)(*pSrc & CODE_MASK_LITE);
  1159. decodeMega = (DCUINT8)(*pSrc);
  1160. /********************************************************************/
  1161. /* BG RUN */
  1162. /********************************************************************/
  1163. if ((decode == CODE_BG_RUN) ||
  1164. (decodeMega == CODE_MEGA_MEGA_BG_RUN))
  1165. {
  1166. if (decode == CODE_BG_RUN)
  1167. {
  1168. EXTRACT_LENGTH(pSrc, pEndSrc, codeLength, hr);
  1169. }
  1170. else
  1171. {
  1172. BD_CHECK_READ_N_BYTES(pSrc+1, pEndSrc, 2, hr);
  1173. codeLength = DC_EXTRACT_UINT16_UA(pSrc+1);
  1174. pSrc += 3;
  1175. }
  1176. TRC_DBG((TB, _T("Background run %u"),codeLength));
  1177. if (!firstLine)
  1178. {
  1179. if (backgroundNeedsPel)
  1180. {
  1181. BD_CHECK_WRITE_ONE_BYTE(pDst, pEndDst, hr);
  1182. BD_CHECK_READ_ONE_BYTE_2ENDED(pDst - rowDelta, pDstBuffer, pEndDst, hr);
  1183. *pDst++ = (DCUINT8)(*(pDst - rowDelta) ^ fgChar);
  1184. codeLength--;
  1185. }
  1186. BD_CHECK_READ_N_BYTES_2ENDED(pDst - rowDelta, pDstBuffer, pEndDst, codeLength, hr);
  1187. BD_CHECK_WRITE_N_BYTES(pDst, pEndDst, codeLength, hr);
  1188. BDMemcpy(pDst, pDst-rowDelta, codeLength);
  1189. pDst += codeLength;
  1190. }
  1191. else
  1192. {
  1193. if (backgroundNeedsPel)
  1194. {
  1195. BD_CHECK_WRITE_ONE_BYTE(pDst, pEndDst, hr);
  1196. *pDst++ = fgChar;
  1197. codeLength--;
  1198. }
  1199. BD_CHECK_WRITE_N_BYTES(pDst, pEndDst, codeLength, hr);
  1200. DC_MEMSET(pDst, 0x00, codeLength);
  1201. pDst += codeLength;
  1202. }
  1203. /****************************************************************/
  1204. /* A follow on BG run will need a pel inserted */
  1205. /****************************************************************/
  1206. backgroundNeedsPel = TRUE;
  1207. continue;
  1208. }
  1209. /********************************************************************/
  1210. /* For any of the other runtypes a follow on BG run does not need */
  1211. /* a FG pel inserted */
  1212. /********************************************************************/
  1213. backgroundNeedsPel = FALSE;
  1214. /********************************************************************/
  1215. /* FGBG IMAGE */
  1216. /********************************************************************/
  1217. if ((decode == CODE_FG_BG_IMAGE) ||
  1218. (decodeLite == CODE_SET_FG_FG_BG) ||
  1219. (decodeMega == CODE_MEGA_MEGA_FGBG) ||
  1220. (decodeMega == CODE_MEGA_MEGA_SET_FGBG))
  1221. {
  1222. if ((decodeMega == CODE_MEGA_MEGA_FGBG) ||
  1223. (decodeMega == CODE_MEGA_MEGA_SET_FGBG))
  1224. {
  1225. BD_CHECK_READ_N_BYTES(pSrc+1, pEndSrc, 2, hr);
  1226. codeLength = DC_EXTRACT_UINT16_UA(pSrc+1);
  1227. pSrc += 3;
  1228. }
  1229. else
  1230. {
  1231. if (decode == CODE_FG_BG_IMAGE)
  1232. {
  1233. EXTRACT_LENGTH_FGBG(pSrc, pEndSrc, codeLength, hr);
  1234. }
  1235. else
  1236. {
  1237. EXTRACT_LENGTH_FGBG_LITE(pSrc, pEndSrc, codeLength, hr);
  1238. }
  1239. }
  1240. if ((decodeLite == CODE_SET_FG_FG_BG) ||
  1241. (decodeMega == CODE_MEGA_MEGA_SET_FGBG))
  1242. {
  1243. BD_CHECK_READ_ONE_BYTE(pSrc, pEndSrc, hr);
  1244. fgChar = *pSrc++;
  1245. TRC_DBG((TB, _T("Set FGBG image %u"),codeLength));
  1246. }
  1247. else
  1248. {
  1249. TRC_DBG((TB, _T("FGBG image %u"),codeLength));
  1250. }
  1251. while (codeLength > 8)
  1252. {
  1253. BD_CHECK_READ_ONE_BYTE(pSrc, pEndSrc, hr);
  1254. codeByte = *pSrc++;
  1255. if (firstLine)
  1256. {
  1257. STORE_FGBG(0x00, codeByte, fgChar, 8);
  1258. }
  1259. else
  1260. {
  1261. BD_CHECK_READ_ONE_BYTE_2ENDED(pDst - rowDelta, pDstBuffer, pEndDst, hr)
  1262. STORE_FGBG(*(pDst - rowDelta), codeByte, fgChar, 8);
  1263. }
  1264. codeLength -= 8;
  1265. }
  1266. if (codeLength > 0)
  1267. {
  1268. BD_CHECK_READ_ONE_BYTE(pSrc, pEndSrc, hr);
  1269. codeByte = *pSrc++;
  1270. if (firstLine)
  1271. {
  1272. STORE_FGBG(0x00, codeByte, fgChar, codeLength);
  1273. }
  1274. else
  1275. {
  1276. BD_CHECK_READ_ONE_BYTE_2ENDED(pDst - rowDelta, pDstBuffer, pEndDst, hr)
  1277. STORE_FGBG(*(pDst - rowDelta),
  1278. codeByte,
  1279. fgChar,
  1280. codeLength);
  1281. }
  1282. }
  1283. continue;
  1284. }
  1285. /********************************************************************/
  1286. /* FG RUN */
  1287. /********************************************************************/
  1288. if ((decode == CODE_FG_RUN) ||
  1289. (decodeLite == CODE_SET_FG_FG_RUN) ||
  1290. (decodeMega == CODE_MEGA_MEGA_FG_RUN) ||
  1291. (decodeMega == CODE_MEGA_MEGA_SET_FG_RUN))
  1292. {
  1293. if ((decodeMega == CODE_MEGA_MEGA_FG_RUN) ||
  1294. (decodeMega == CODE_MEGA_MEGA_SET_FG_RUN))
  1295. {
  1296. BD_CHECK_READ_N_BYTES(pSrc+1, pEndSrc, 2, hr);
  1297. codeLength = DC_EXTRACT_UINT16_UA(pSrc+1);
  1298. pSrc += 3;
  1299. }
  1300. else
  1301. {
  1302. if (decode == CODE_FG_RUN)
  1303. {
  1304. EXTRACT_LENGTH(pSrc, pEndSrc, codeLength, hr);
  1305. }
  1306. else
  1307. {
  1308. EXTRACT_LENGTH_LITE(pSrc, pEndSrc, codeLength, hr);
  1309. }
  1310. }
  1311. /****************************************************************/
  1312. /* Push the old fgChar down to the ALT position */
  1313. /****************************************************************/
  1314. if ((decodeLite == CODE_SET_FG_FG_RUN) ||
  1315. (decodeMega == CODE_MEGA_MEGA_SET_FG_RUN))
  1316. {
  1317. BD_CHECK_READ_ONE_BYTE(pSrc, pEndSrc, hr);
  1318. TRC_DBG((TB, _T("Set FG run %u"),codeLength));
  1319. fgChar = *pSrc++;
  1320. }
  1321. else
  1322. {
  1323. TRC_DBG((TB, _T("FG run %u"),codeLength));
  1324. }
  1325. BD_CHECK_WRITE_N_BYTES(pDst, pEndDst, codeLength, hr)
  1326. while (codeLength-- > 0)
  1327. {
  1328. if (!firstLine)
  1329. {
  1330. BD_CHECK_READ_ONE_BYTE_2ENDED(pDst - rowDelta, pDstBuffer, pEndDst, hr)
  1331. *pDst++ = (DCUINT8)(*(pDst - rowDelta) ^ fgChar);
  1332. }
  1333. else
  1334. {
  1335. *pDst++ = fgChar;
  1336. }
  1337. }
  1338. continue;
  1339. }
  1340. /********************************************************************/
  1341. /* DITHERED RUN */
  1342. /********************************************************************/
  1343. if ((decodeLite == CODE_DITHERED_RUN) ||
  1344. (decodeMega == CODE_MEGA_MEGA_DITHER))
  1345. {
  1346. if (decodeMega == CODE_MEGA_MEGA_DITHER)
  1347. {
  1348. BD_CHECK_READ_N_BYTES(pSrc+1, pEndSrc, 2, hr);
  1349. codeLength = DC_EXTRACT_UINT16_UA(pSrc+1);
  1350. pSrc += 3;
  1351. }
  1352. else
  1353. {
  1354. EXTRACT_LENGTH_LITE(pSrc, pEndSrc, codeLength, hr);
  1355. }
  1356. TRC_DBG((TB, _T("Dithered run %u"),codeLength));
  1357. BD_CHECK_READ_N_BYTES(pSrc, pEndSrc, 2, hr);
  1358. codeByte = *pSrc++;
  1359. codeByte2 = *pSrc++;
  1360. BD_CHECK_WRITE_N_BYTES(pDst, pEndDst, codeLength * 2, hr)
  1361. while (codeLength-- > 0)
  1362. {
  1363. *pDst++ = codeByte;
  1364. *pDst++ = codeByte2;
  1365. }
  1366. continue;
  1367. }
  1368. /********************************************************************/
  1369. /* COLOR IMAGE */
  1370. /********************************************************************/
  1371. if ((decode == CODE_COLOR_IMAGE) ||
  1372. (decodeMega == CODE_MEGA_MEGA_CLR_IMG))
  1373. {
  1374. if (decodeMega == CODE_MEGA_MEGA_CLR_IMG)
  1375. {
  1376. BD_CHECK_READ_N_BYTES(pSrc+1, pEndSrc, 2, hr);
  1377. codeLength = DC_EXTRACT_UINT16_UA(pSrc+1);
  1378. pSrc += 3;
  1379. }
  1380. else
  1381. {
  1382. EXTRACT_LENGTH(pSrc, pEndSrc, codeLength, hr);
  1383. }
  1384. TRC_DBG((TB, _T("Color image %u"),codeLength));
  1385. BD_CHECK_READ_N_BYTES(pSrc, pEndSrc, codeLength, hr);
  1386. BD_CHECK_WRITE_N_BYTES(pDst, pEndDst, codeLength, hr);
  1387. BDMemcpy(pDst, pSrc, codeLength);
  1388. pDst += codeLength;
  1389. pSrc += codeLength;
  1390. continue;
  1391. }
  1392. /********************************************************************/
  1393. /* PACKED COLOR IMAGE */
  1394. /********************************************************************/
  1395. if ((decode == CODE_PACKED_COLOR_IMAGE) ||
  1396. (decodeMega == CODE_MEGA_MEGA_PACKED_CLR))
  1397. {
  1398. if (decodeMega == CODE_MEGA_MEGA_PACKED_CLR)
  1399. {
  1400. BD_CHECK_READ_N_BYTES(pSrc+1, pEndSrc, 2, hr);
  1401. codeLength = DC_EXTRACT_UINT16_UA(pSrc+1);
  1402. pSrc += 3;
  1403. }
  1404. else
  1405. {
  1406. EXTRACT_LENGTH(pSrc, pEndSrc, codeLength, hr);
  1407. }
  1408. TRC_DBG((TB, _T("Packed color %u"),codeLength));
  1409. if (bitmapBitsPerPel == 4)
  1410. {
  1411. DCUINT worklen = (codeLength)/2;
  1412. DCUINT8 workchar;
  1413. BD_CHECK_READ_N_BYTES(pSrc, pEndSrc, worklen, hr);
  1414. BD_CHECK_WRITE_N_BYTES(pDst, pEndDst, worklen * 2, hr);
  1415. while (worklen--)
  1416. {
  1417. workchar = *pSrc++;
  1418. *pDst++ = (DCUINT8)(workchar >> 4);
  1419. *pDst++ = (DCUINT8)(workchar & 0x0F);
  1420. }
  1421. if (codeLength & 0x0001)
  1422. {
  1423. BD_CHECK_READ_ONE_BYTE(pSrc, pEndSrc, hr);
  1424. BD_CHECK_WRITE_ONE_BYTE(pDst, pEndDst, hr);
  1425. *pDst++ = (DCUINT8)(*pSrc++>>4);
  1426. }
  1427. }
  1428. else
  1429. {
  1430. TRC_ERR((TB, _T("Don't support packed color for 8bpp")));
  1431. }
  1432. continue;
  1433. }
  1434. /********************************************************************/
  1435. /* COLOR RUN */
  1436. /********************************************************************/
  1437. if ((decode == CODE_COLOR_RUN) ||
  1438. (decodeMega == CODE_MEGA_MEGA_COLOR_RUN))
  1439. {
  1440. if (decodeMega == CODE_MEGA_MEGA_COLOR_RUN)
  1441. {
  1442. BD_CHECK_READ_N_BYTES(pSrc+1, pEndSrc, 2, hr);
  1443. codeLength = DC_EXTRACT_UINT16_UA(pSrc+1);
  1444. pSrc += 3;
  1445. }
  1446. else
  1447. {
  1448. EXTRACT_LENGTH(pSrc, pEndSrc, codeLength, hr);
  1449. }
  1450. TRC_DBG((TB, _T("Color run %u"),codeLength));
  1451. BD_CHECK_READ_ONE_BYTE(pSrc, pEndSrc, hr);
  1452. codeByte = *pSrc++;
  1453. BD_CHECK_WRITE_N_BYTES(pDst, pEndDst, codeLength, hr);
  1454. DC_MEMSET(pDst, codeByte, codeLength);
  1455. pDst += codeLength;
  1456. continue;
  1457. }
  1458. /********************************************************************/
  1459. /* If we get here then the code must be a special one */
  1460. /********************************************************************/
  1461. TRC_DBG((TB, _T("Special code %#x"),decodeMega));
  1462. switch (decodeMega)
  1463. {
  1464. case CODE_BLACK:
  1465. {
  1466. BD_CHECK_WRITE_ONE_BYTE(pDst, pEndDst, hr);
  1467. *pDst++ = 0x00;
  1468. }
  1469. break;
  1470. case CODE_WHITE:
  1471. {
  1472. BD_CHECK_WRITE_ONE_BYTE(pDst, pEndDst, hr);
  1473. *pDst++ = 0xFF;
  1474. }
  1475. break;
  1476. /****************************************************************/
  1477. /* Ignore the unreachable code warnings that follow */
  1478. /* Simply because we use the STORE_FGBG macro with a constant */
  1479. /* value */
  1480. /****************************************************************/
  1481. case CODE_SPECIAL_FGBG_1:
  1482. {
  1483. if (firstLine)
  1484. {
  1485. STORE_FGBG(0x00, SPECIAL_FGBG_CODE_1, fgChar, 8);
  1486. }
  1487. else
  1488. {
  1489. BD_CHECK_READ_ONE_BYTE_2ENDED(pDst - rowDelta, pDstBuffer, pEndDst, hr)
  1490. STORE_FGBG(*(pDst - rowDelta),
  1491. SPECIAL_FGBG_CODE_1,
  1492. fgChar,
  1493. 8);
  1494. }
  1495. }
  1496. break;
  1497. case CODE_SPECIAL_FGBG_2:
  1498. {
  1499. if (firstLine)
  1500. {
  1501. STORE_FGBG(0x00,
  1502. SPECIAL_FGBG_CODE_2,
  1503. fgChar,
  1504. 8);
  1505. }
  1506. else
  1507. {
  1508. BD_CHECK_READ_ONE_BYTE_2ENDED(pDst - rowDelta, pDstBuffer, pEndDst, hr)
  1509. STORE_FGBG(*(pDst - rowDelta),
  1510. SPECIAL_FGBG_CODE_2,
  1511. fgChar,
  1512. 8);
  1513. }
  1514. }
  1515. break;
  1516. default:
  1517. {
  1518. TRC_ERR((TB, _T("Invalid compression data %x"),decodeMega));
  1519. }
  1520. break;
  1521. }
  1522. pSrc++;
  1523. }
  1524. TRC_DBG((TB, _T("Decompressed to %d"), pDst-pDstBuffer));
  1525. DC_EXIT_POINT:
  1526. DC_END_FN();
  1527. return hr;
  1528. }
  1529. #endif
  1530. #ifdef OS_WINDOWS
  1531. #pragma warning (default: 4127)
  1532. #endif /* OS_WINDOWS */