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.

1652 lines
72 KiB

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