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.

1753 lines
49 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: rleblt8.cxx
  3. *
  4. * This contains the bitmap simulation functions that blt from an 8 bit
  5. * Run-Length Encoded (RLE) source to a DIB surface. The DIB surface can be
  6. * 1, 4, 8, 16, 24, or 32 bits/pel.
  7. *
  8. * The code is based on functions found in 'srcblt8.cxx', version 23,
  9. * although now bears no resembalence to them at all.
  10. *
  11. * Notes:
  12. *
  13. * 1) These functions return a BOOL value. This value is TRUE if the
  14. * function ends before running out of data in the source RLE or before
  15. * hitting an End-of-Bitmap code. Otherwise, we return FALSE. This return
  16. * value is used by <EngCopyBits> in the complex clipping case to decide
  17. * if the blt is complete.
  18. *
  19. * 2) Before exiting a function with a TRUE value, position information is
  20. * saved by the macro <RLE_SavePosition>. This is used by <EngCopyBits>
  21. * to speed up the complex clipping case.
  22. *
  23. * 3) The below functions use about twenty different macros. This is
  24. * because they are all using the same basic algorithm to play an RLE
  25. * compression. The macros allow us to focus in on the nifty stuff of writing
  26. * the bytes out to the DIB. Routine administrivia is handled by the macros.
  27. *
  28. * The macros themselves are used to manage
  29. *
  30. * - Source Access and data alignment
  31. * - Visability Checking
  32. * - Clipping
  33. * - Output position changes with Newline & Delta codes
  34. *
  35. * The macro <RLE_InitVars> is used to define the varibles that relate to
  36. * the above information, and to define variables common to all RLE 4
  37. * blt functions. Note that actual names of the common variables are passed
  38. * in as parameters to the macro. Why? Two reasons. Firstly, they are
  39. * initialized by values taken of the BLTINFO structure passed into the blt
  40. * function. Secondly, showing the variable names in the macro 'call' means
  41. * they don't just appear from nowhere into the function. RLE_InitVars
  42. * is the one macro that you should think three times about before modifying.
  43. *
  44. * One further note. The variables 'ulDstLeft' and 'ulDstRight' appear to
  45. * come from nowhere. This is not true. They are in fact declared by the
  46. * macro <RLE_GetVisibleRect>. However, showing these names in the macro
  47. * 'call' tended to obscure the code. Pretend you can see the declaration.
  48. *
  49. * Where can I find a macro definition?
  50. *
  51. * Good question, glad you asked. Look at the prefix:
  52. *
  53. * RLE_<stuff> - lives in RLEBLT.H
  54. * RLE8_<blah> - lives in RLE8BLT.H
  55. *
  56. * Anything else in here that looks like function call is not. It's a macro.
  57. * Probably for bitwise manipulations. Look for it in BITMANIP.H or in
  58. * the Miscellaneous section of RLEBLT.H
  59. * Added RLE Encoding functions: 10 Oct 92 @ 10:18
  60. * Gerrit van Wingerden [gerritv]
  61. *
  62. * Created: 19 Jan 92 @ 19:00
  63. * Author: Andrew Milton (w-andym)
  64. *
  65. * Copyright (c) 1990, 1999 Microsoft Corporation
  66. *
  67. \**************************************************************************/
  68. #include "precomp.hxx"
  69. /******************************Public*Routine******************************\
  70. * bSrcCopySRLE8D8
  71. *
  72. * Secure RLE blting that does clipping and won't die or write somewhere
  73. * it shouldn't if given bad data.
  74. *
  75. * History:
  76. * 19 Jan 1992 - Andrew Milton (w-andym):
  77. * Moved most of the initialization code back up to <EngCopyBits()> in
  78. * <trivblt.cxx>. This way it is done once instead of once per call
  79. * of this function.
  80. *
  81. * The rclDst field is now the visible rectangle of our bitmap, not the
  82. * target rectangle. This cleans up the visible region checking.
  83. *
  84. * 24-Oct-1991 -by- Patrick Haluptzok patrickh
  85. * Updated, add clipping support
  86. *
  87. * 06-Feb-1991 -by- Patrick Haluptzok patrickh
  88. * Wrote it.
  89. \**************************************************************************/
  90. BOOL
  91. bSrcCopySRLE8D8(
  92. PBLTINFO psb)
  93. {
  94. // Common RLE Initialization
  95. RLE_InitVars(psb, pjSrc, pjDst, PBYTE, ulCount, ulNext, lOutCol, pulXlate);
  96. RLE_AssertValid(psb);
  97. RLE_FetchVisibleRect(psb);
  98. RLE_SetStartPos(psb, lOutCol);
  99. // Outta here if we start past the top edge. Don't need to save our position.
  100. if (RLE_PastTopEdge)
  101. return(TRUE); // Must have bits left in the bitmap since we haven't
  102. // consumed any.
  103. // Main Process Loop
  104. LOOP_FOREVER
  105. {
  106. // Outta here if we can't get two more bytes
  107. if (RLE_SourceExhausted(2))
  108. return(FALSE);
  109. RLE_GetNextCode(pjSrc, ulCount, ulNext);
  110. if (ulCount == 0)
  111. {
  112. // Absolute or Escape Mode
  113. switch (ulNext)
  114. {
  115. case 0:
  116. // Newline
  117. RLE_NextLine(PBYTE, pjDst, lOutCol);
  118. if (RLE_PastTopEdge)
  119. {
  120. RLE_SavePosition(psb, pjSrc, pjDst, lOutCol);
  121. return(TRUE);
  122. }
  123. break;
  124. case 1:
  125. // End of the Bitmap
  126. return(FALSE);
  127. case 2:
  128. // Position Delta. Fetch & Evaluate
  129. // Outta here if we can't get the delta values
  130. if (RLE_SourceExhausted(2))
  131. return(FALSE);
  132. RLE_GetNextCode(pjSrc, ulCount, ulNext);
  133. RLE_PosDelta(pjDst, lOutCol, ulCount, ulNext);
  134. if (RLE_PastTopEdge)
  135. {
  136. RLE_SavePosition(psb, pjSrc, pjDst, lOutCol);
  137. return(TRUE);
  138. }
  139. break;
  140. default:
  141. // Absolute Mode
  142. // Outta here if the bytes are not in the source
  143. if (RLE_SourceExhausted(ulNext))
  144. return(FALSE);
  145. RLE8_AlignToWord(pjSrc, ulNext);
  146. if (RLE_InVisibleRect(ulNext, lOutCol))
  147. {
  148. RLE8_AbsClipLeft(pjSrc, ulCount, ulNext, lOutCol);
  149. RLE8_ClipRight(ulCount, ulNext, lOutCol);
  150. // Slap the bits on. -- this is the funky-doodle stuff.
  151. while (ulNext--)
  152. {
  153. pjDst[lOutCol] =
  154. (BYTE) pulXlate[(ULONG) *(pjSrc++)];
  155. lOutCol++;
  156. }
  157. // Adjust for the right side clipping.
  158. pjSrc += ulCount;
  159. lOutCol += ulCount;
  160. }
  161. else
  162. {
  163. /* Not on a visible scanline.
  164. * Adjust our x output position and source pointer.
  165. */
  166. lOutCol += ulNext;
  167. pjSrc += ulNext;
  168. } /* if */
  169. // Fix up if this run was not WORD aligned.
  170. RLE8_FixAlignment(pjSrc)
  171. } /* switch */
  172. }
  173. else
  174. {
  175. // Encoded Mode
  176. if (RLE_InVisibleRect(ulCount, lOutCol))
  177. {
  178. ULONG ulClipMargin = 0;
  179. ulNext = pulXlate[ulNext];
  180. RLE8_EncClipLeft(ulClipMargin, ulCount, lOutCol);
  181. RLE8_ClipRight(ulClipMargin, ulCount, lOutCol);
  182. // Slap the bits on.
  183. while (ulCount--)
  184. {
  185. pjDst[lOutCol] = (BYTE) ulNext;
  186. lOutCol++;
  187. }
  188. // Adjust for the right side clipping.
  189. lOutCol += ulClipMargin;
  190. }
  191. else
  192. {
  193. // Not on a visible scanline. Adjust our x output position
  194. lOutCol += ulCount;
  195. } /* if */
  196. } /* if */
  197. } /* LOOP_FOREVER */
  198. } /* bSrcCopySRLE8D8 */
  199. /******************************Public*Routine******************************\
  200. * bSrcCopySRLE8D1
  201. *
  202. * Secure RLE blting to a 1 BPP DIB that does clipping and won't die or
  203. * write somewhere it shouldn't if given bad data.
  204. *
  205. * History:
  206. * 5 Feb 1992 - Andrew Milton (w-andym):
  207. * Added clip support.
  208. * 22 Jan 1992 - Andrew Milton (w-andym): Creation.
  209. *
  210. \**************************************************************************/
  211. /* NOTE: In the Escape Modes, the current working byte must be
  212. * written to destination before the escape is executed.
  213. * These writes look unpleasant because we have to mask
  214. * current destination contents onto the working byte when
  215. * it is written. To such an end, the below macro...
  216. */
  217. #define RLE8to1_WritePartial(DstPtr, OutByte, OutColumn, WritePos) \
  218. if (RLE_RowVisible && (jBitPos = (BYTE) (OutColumn) & 7)) \
  219. { \
  220. if (RLE_ColVisible(OutColumn)) \
  221. DstPtr[WritePos] = OutByte | \
  222. ((~ajBits[jBitPos]) & DstPtr[WritePos]); \
  223. else \
  224. if (RLE_PastRightEdge(OutColumn)) \
  225. DstPtr[ulRightWritePos] = OutByte | \
  226. (DstPtr[ulRightWritePos] & jRightMask); \
  227. }
  228. #define ColToBitPos(col) (7 - (BYTE) ((col) & 7) )
  229. /* Lookup tables for bit patterns *****************************************/
  230. static BYTE
  231. ajPosMask[] = // The i'th entry contains a byte with the i'th bit set
  232. {
  233. 0x01, 0x02, 0x04, 0x08,
  234. 0x10, 0x20, 0x40, 0x80, 0x00
  235. };
  236. static BYTE
  237. ajBits[] = // The i'th entry contains a byte with the high i bits set
  238. {
  239. 0x00, 0x80, 0xC0, 0xE0, 0xF0,
  240. 0xF8, 0xFC, 0xFE, 0xFF
  241. };
  242. /* And now the function ***************************************************/
  243. BOOL
  244. bSrcCopySRLE8D1(
  245. PBLTINFO psb)
  246. {
  247. // Common RLE Initialization
  248. RLE_InitVars(psb, pjSrc, pjDst, PBYTE, ulCount, ulNext, lOutCol, pulXlate);
  249. RLE_AssertValid(psb);
  250. RLE_FetchVisibleRect(psb);
  251. RLE_SetStartPos(psb, lOutCol);
  252. // Outta here if we start past the top edge. Don't need to save our position.
  253. if (RLE_PastTopEdge)
  254. return(TRUE); // Must have bits left in the bitmap since we haven't
  255. // consumed any.
  256. // Extra Variables
  257. BYTE jWorking; // Hold area to build a byte for output
  258. ULONG ulWritePos; // Write position off <pjDst> into the destination
  259. ULONG ulLeftWritePos; // Leftmost write position
  260. BYTE jLeftMask; // Bitmask for taking bytes off the left edge
  261. ULONG ulRightWritePos; // Rightmost write position
  262. BYTE jRightMask; // Bitmask for taking bytes off the right edge
  263. BYTE jBitPos; // Bit number of the next write into <jWorking>
  264. BYTE jBitPosMask; // Bitmask with the <jBitPos>th bit set.
  265. ULONG ulClipMargin; // Number of bytes clipped off the right side of a run
  266. ULONG ulCompBytes; // Number of complete bytes in an absolute run.
  267. // Our Initialization
  268. ulLeftWritePos = (ULONG)(ulDstLeft >> 3);
  269. jLeftMask = ajBits[(ulDstLeft % 8)];
  270. ulRightWritePos = (ULONG) (ulDstRight >> 3);
  271. jRightMask = ~ajBits[(ulDstRight % 8)];
  272. /* Fetch first working byte from the source. Yes, this is ugly.
  273. * We cannot assume we are at a left edge because the complex clipping
  274. * case could resume an RLE in the middle of its bitmap. We cannot do
  275. * a simple bounds check like RLE 8 to 4 because of bitmasking. Argh.
  276. */
  277. ulWritePos = lOutCol >> 3;
  278. if (RLE_RowVisible)
  279. {
  280. if (RLE_ColVisible(lOutCol))
  281. jWorking = pjDst[ulWritePos] & ajBits[lOutCol & 7];
  282. else
  283. {
  284. if (RLE_PastRightEdge(lOutCol))
  285. jWorking = pjDst[ulRightWritePos];
  286. else
  287. jWorking = pjDst[ulLeftWritePos] & jLeftMask;
  288. }
  289. }
  290. // Diddle the translation table
  291. int i, j;
  292. for (i = 1, j=1; i < 256; i+=1, j^= 1) pulXlate[i] = j;
  293. LOOP_FOREVER
  294. {
  295. // Outta here if we can't get two more bytes
  296. if (RLE_SourceExhausted(2))
  297. return(FALSE);
  298. RLE_GetNextCode(pjSrc, ulCount, ulNext);
  299. ulWritePos = lOutCol >> 3;
  300. if (ulCount == 0)
  301. {
  302. // Absolute or Escape Mode
  303. switch (ulNext)
  304. {
  305. case 0:
  306. // New line
  307. RLE8to1_WritePartial(pjDst, jWorking, lOutCol, ulWritePos);
  308. RLE_NextLine(PBYTE, pjDst, lOutCol);
  309. if (RLE_PastTopEdge)
  310. {
  311. RLE_SavePosition(psb, pjSrc, pjDst, lOutCol);
  312. return(TRUE);
  313. }
  314. if (RLE_RowVisible)
  315. jWorking = pjDst[ulLeftWritePos] & jLeftMask;
  316. break;
  317. case 1:
  318. // End of the bitmap
  319. RLE8to1_WritePartial(pjDst, jWorking, lOutCol, ulWritePos);
  320. return(FALSE);
  321. case 2:
  322. // Positional Delta
  323. RLE8to1_WritePartial(pjDst, jWorking, lOutCol, ulWritePos);
  324. // Outta here if we can't get the delta values
  325. if (RLE_SourceExhausted(2))
  326. return(FALSE);
  327. RLE_GetNextCode(pjSrc, ulCount, ulNext);
  328. RLE_PosDelta(pjDst, lOutCol, ulCount, ulNext);
  329. if (RLE_PastTopEdge)
  330. {
  331. RLE_SavePosition(psb, pjSrc, pjDst, lOutCol);
  332. return(TRUE);
  333. }
  334. // Fetch a new working byte off the destination
  335. ulWritePos = lOutCol >> 3;
  336. if (RLE_RowVisible)
  337. {
  338. if (RLE_ColVisible(lOutCol))
  339. jWorking = pjDst[ulWritePos] & ajBits[lOutCol & 7];
  340. else
  341. {
  342. if (RLE_PastRightEdge(lOutCol))
  343. jWorking = pjDst[ulRightWritePos];
  344. else
  345. jWorking = pjDst[ulLeftWritePos] & jLeftMask;
  346. }
  347. }
  348. break;
  349. default:
  350. // Absolute Mode
  351. // Outta here if the bytes are not in the source
  352. if (RLE_SourceExhausted(ulNext))
  353. return(FALSE);
  354. RLE8_AlignToWord(pjSrc, ulNext);
  355. // Output if we are on a visible scanline.
  356. if (RLE_InVisibleRect(ulNext, lOutCol))
  357. {
  358. // Left side clipping
  359. if (lOutCol < (LONG)ulDstLeft)
  360. {
  361. ulCount = ulDstLeft - lOutCol;
  362. ulNext -= ulCount;
  363. lOutCol += ulCount;
  364. ulWritePos = lOutCol >> 3;
  365. pjSrc += ulCount;
  366. }
  367. RLE8_ClipRight(ulCount, ulNext, lOutCol);
  368. jBitPos = (BYTE) ColToBitPos(lOutCol);
  369. jBitPosMask = ajPosMask[jBitPos];
  370. lOutCol += (LONG) ulNext;
  371. // Write the run
  372. do {
  373. // Fill the working byte
  374. while(jBitPosMask && ulNext)
  375. {
  376. if (pulXlate[*pjSrc++])
  377. jWorking |= jBitPosMask;
  378. jBitPosMask >>= 1;
  379. ulNext--;
  380. }
  381. // Write it
  382. if (!(jBitPosMask))
  383. {
  384. pjDst[ulWritePos] = jWorking;
  385. ulWritePos++;
  386. jBitPosMask = 0x80;
  387. jWorking = 0;
  388. }
  389. } while (ulNext);
  390. // Adjust for the right side clipping.
  391. pjSrc += ulCount;
  392. lOutCol += ulCount;
  393. }
  394. else
  395. {
  396. /* Not on a visible scanline.
  397. * Adjust our x output position and source pointer.
  398. */
  399. lOutCol += ulNext;
  400. pjSrc += ulNext;
  401. } /* if */
  402. // Fix up if this run was not WORD aligned.
  403. RLE8_FixAlignment(pjSrc);
  404. } /* switch */
  405. }
  406. else
  407. {
  408. // Encoded Mode
  409. if (RLE_InVisibleRect(ulCount, lOutCol))
  410. {
  411. // Left side clipping
  412. if (lOutCol < (LONG)ulDstLeft)
  413. {
  414. ulClipMargin = ulDstLeft - lOutCol;
  415. ulCount -= ulClipMargin;
  416. lOutCol += ulClipMargin;
  417. ulWritePos = lOutCol >> 3;
  418. }
  419. RLE8_ClipRight(ulClipMargin, ulCount, lOutCol);
  420. // Initialize for the run. Now we get funky-doodle
  421. jBitPos = ColToBitPos(lOutCol);
  422. lOutCol += ulCount;
  423. ulNext = pulXlate[ulNext];
  424. // Deal with the left side partial byte
  425. if (jBitPos >= (BYTE) ulCount)
  426. {
  427. // Will not fill the current working byte
  428. ulCompBytes = 0; // No Complete bytes.
  429. if (ulNext)
  430. jWorking |= (ajBits[ulCount] >> (7-jBitPos));
  431. else
  432. jWorking &= ~(ajBits[ulCount] >> (7-jBitPos));
  433. jBitPos -= (BYTE)ulCount;
  434. ulCount = 0;
  435. }
  436. else
  437. {
  438. /* Will fill the current working byte.
  439. * We may have complete bytes to output.
  440. */
  441. ulCompBytes = ((BYTE)ulCount - jBitPos - 1) >> 3;
  442. if (ulNext)
  443. jWorking |= (~ajBits[7 - jBitPos]);
  444. else
  445. jWorking &= (ajBits[7 - jBitPos]);
  446. pjDst[ulWritePos] = jWorking;
  447. ulWritePos++;
  448. jWorking = 0;
  449. ulCount -= (jBitPos + 1);
  450. jBitPos = 7;
  451. }
  452. // Deal with complete byte output
  453. if (ulCompBytes)
  454. {
  455. UINT i;
  456. jWorking = (ulNext) ? 0xFF : 0x00;
  457. for (i = 0; i < ulCompBytes; i++)
  458. pjDst[ulWritePos + i] = jWorking;
  459. ulWritePos += ulCompBytes;
  460. jBitPos = 7;
  461. jWorking = 0;
  462. ulCount -= (ulCompBytes << 3);
  463. } /* if */
  464. // Deal with the right side partial byte
  465. if (ulCount)
  466. {
  467. if (ulNext)
  468. jWorking |= ajBits[ulCount];
  469. else
  470. jWorking = 0;
  471. }
  472. // Adjust for the right side clipping.
  473. lOutCol += ulClipMargin;
  474. }
  475. else
  476. {
  477. /* Not on a visible scanline.
  478. * Adjust our x output position and source pointer.
  479. */
  480. lOutCol += ulCount;
  481. } /* if */
  482. } /* if */
  483. } /* LOOP_FOREVER */
  484. } /* bSrcCopySRLE8D1 */
  485. /******************************Public*Routine******************************\
  486. * bSrcCopySRLE8D4
  487. *
  488. * Secure RLE blting to a 4 BPP DIB that does clipping and won't die or
  489. * write somewhere it shouldn't if given bad data.
  490. *
  491. * History:
  492. * 5 Feb 1992 - Andrew Milton (w-andym):
  493. * Added clip support.
  494. *
  495. * 24 Jan 1992 - Andrew Milton (w-andym): Creation.
  496. *
  497. \**************************************************************************/
  498. /* NOTE: In the Escape Modes, the current working byte must be
  499. * written to destination before the escape is executed.
  500. * To this end, the below macro...
  501. */
  502. #define RLE8to4_WritePartial(DstPtr, OutByte, OutColumn, WritePos) \
  503. if (RLE_RowVisible) \
  504. { \
  505. if (RLE_ColVisible(OutColumn) && bIsOdd(OutColumn)) \
  506. { \
  507. SetLowNybble(OutByte, DstPtr[WritePos]); \
  508. DstPtr[WritePos] = OutByte; \
  509. } \
  510. else \
  511. { \
  512. if (bRightPartial && RLE_PastRightEdge(OutColumn)) \
  513. { \
  514. /*DbgBreakPoint();*/ \
  515. SetLowNybble(OutByte, DstPtr[ulRightWritePos]); \
  516. DstPtr[ulRightWritePos] = OutByte; \
  517. } \
  518. } \
  519. } \
  520. BOOL
  521. bSrcCopySRLE8D4(
  522. PBLTINFO psb)
  523. {
  524. // Common RLE Initialization
  525. RLE_InitVars(psb, pjSrc, pjDst, PBYTE, ulCount, ulNext,
  526. lOutCol, pulXlate);
  527. RLE_AssertValid(psb);
  528. RLE_FetchVisibleRect(psb);
  529. RLE_SetStartPos(psb, lOutCol);
  530. // Outta here if we start past the top edge. Don't need to save our position.
  531. if (RLE_PastTopEdge)
  532. return(TRUE); // Must have bits left in the bitmap since we haven't
  533. // consumed any.
  534. // Extra Variables
  535. BOOL bRightPartial; // TRUE when a visible row ends in a partial byte
  536. BYTE jWorking; // Hold area to build a byte for output
  537. ULONG ulWritePos; // Write position off <pjDst> into the destination
  538. ULONG ulLeftWritePos; // Leftmost write position
  539. ULONG ulRightWritePos; // Rightmost write position
  540. ULONG ulClipMargin; // Number of bytes clipped in an encoded run
  541. // Our Initialization
  542. ulLeftWritePos = ulDstLeft >> 1;
  543. ulRightWritePos = ulDstRight >> 1;
  544. bRightPartial = (BOOL) bIsOdd(ulDstRight);
  545. // Fetch our inital working byte
  546. ulWritePos = lOutCol >> 1;
  547. if (RLE_RowVisible)
  548. jWorking = pjDst[BoundsCheck(ulLeftWritePos, ulRightWritePos,
  549. ulWritePos)];
  550. // Main processing loop
  551. LOOP_FOREVER
  552. {
  553. ulWritePos = lOutCol >> 1;
  554. // Outta here if we can't get two more bytes
  555. if (RLE_SourceExhausted(2))
  556. return(FALSE);
  557. RLE_GetNextCode(pjSrc, ulCount, ulNext);
  558. if (ulCount == 0)
  559. {
  560. // Absolute or Escape Mode
  561. switch (ulNext)
  562. {
  563. case 0:
  564. // New line.
  565. RLE8to4_WritePartial(pjDst, jWorking, lOutCol, ulWritePos);
  566. RLE_NextLine(PBYTE, pjDst, lOutCol);
  567. if (RLE_PastTopEdge)
  568. {
  569. RLE_SavePosition(psb, pjSrc, pjDst, lOutCol);
  570. return(TRUE);
  571. }
  572. if (RLE_RowVisible)
  573. jWorking = pjDst[ulLeftWritePos];
  574. break;
  575. case 1:
  576. // End of the bitmap.
  577. RLE8to4_WritePartial(pjDst, jWorking, lOutCol, ulWritePos);
  578. return(FALSE);
  579. case 2:
  580. // Positional Delta - Fetch and evaluate
  581. RLE8to4_WritePartial(pjDst, jWorking, lOutCol, ulWritePos);
  582. // Outta here if we can't get the delta values
  583. if (RLE_SourceExhausted(2))
  584. return(FALSE);
  585. RLE_GetNextCode(pjSrc, ulCount, ulNext);
  586. RLE_PosDelta(pjDst, lOutCol, ulCount, ulNext);
  587. if (RLE_PastTopEdge)
  588. {
  589. RLE_SavePosition(psb, pjSrc, pjDst, lOutCol);
  590. return(TRUE);
  591. }
  592. // Read a new working byte off the destination
  593. ulWritePos = lOutCol >> 1;
  594. if (RLE_RowVisible)
  595. jWorking = pjDst[BoundsCheck(ulLeftWritePos, ulRightWritePos,
  596. ulWritePos)];
  597. break;
  598. default:
  599. // Absolute Mode
  600. // Outta here if the bytes are not in the source
  601. if (RLE_SourceExhausted(ulNext))
  602. return(FALSE);
  603. RLE8_AlignToWord(pjSrc, ulNext);
  604. if (RLE_InVisibleRect(ulNext, lOutCol))
  605. {
  606. // Left side clipping
  607. if (lOutCol < (LONG)ulDstLeft)
  608. {
  609. ulCount = ulDstLeft - lOutCol;
  610. ulNext -= ulCount;
  611. lOutCol += ulCount;
  612. ulWritePos = lOutCol >> 1;
  613. pjSrc += ulCount;
  614. }
  615. RLE8_ClipRight(ulCount, ulNext, lOutCol);
  616. // Account for a right side partial byte
  617. if (bIsOdd(lOutCol))
  618. {
  619. SetLowNybble(jWorking,
  620. (BYTE)(pulXlate[(ULONG) *pjSrc++]));
  621. pjDst[ulWritePos] = jWorking;
  622. lOutCol++;
  623. ulWritePos++;
  624. ulNext--;
  625. }
  626. // Write the run
  627. lOutCol += ulNext;
  628. ulNext >>= 1;
  629. while (ulNext)
  630. {
  631. jWorking = ((BYTE)pulXlate[(ULONG) *pjSrc++]) << 4;
  632. SetLowNybble(jWorking,
  633. (BYTE)pulXlate[(ULONG) *pjSrc++]);
  634. pjDst[ulWritePos] = jWorking;
  635. ulWritePos++;
  636. ulNext--;
  637. }
  638. // Account for a left side partial byte
  639. if (bIsOdd(lOutCol))
  640. SetHighNybble(jWorking,
  641. (BYTE)pulXlate[(ULONG) *pjSrc++]);
  642. // Adjust for the right side clipping.
  643. pjSrc += ulCount;
  644. lOutCol += ulCount;
  645. }
  646. else
  647. {
  648. /* Not on a visible scanline.
  649. * Adjust our x output position and source pointer.
  650. */
  651. pjSrc += ulNext;
  652. lOutCol += ulNext;
  653. } /* if */
  654. // Fix up if this run was not WORD aligned.
  655. RLE8_FixAlignment(pjSrc);
  656. } /* switch */
  657. } else {
  658. // Encoded Mode
  659. if (RLE_InVisibleRect(ulCount, lOutCol))
  660. {
  661. // Left side clipping
  662. if (lOutCol < (LONG)ulDstLeft)
  663. {
  664. ulClipMargin = ulDstLeft - lOutCol;
  665. ulCount -= ulClipMargin;
  666. lOutCol += ulClipMargin;
  667. ulWritePos = lOutCol >> 1;
  668. }
  669. RLE8_ClipRight(ulClipMargin, ulCount, lOutCol);
  670. ulNext = pulXlate[ulNext];
  671. // Account for a left side partial byte
  672. if (bIsOdd(lOutCol))
  673. {
  674. SetLowNybble(jWorking, (BYTE)ulNext);
  675. pjDst[ulWritePos] = jWorking;
  676. ulWritePos++;
  677. lOutCol++;
  678. ulCount--;
  679. }
  680. // Write complete bytes of the run
  681. lOutCol += ulCount;
  682. ulCount >>= 1;
  683. jWorking = BuildByte((BYTE)ulNext, (BYTE)ulNext);
  684. while(ulCount)
  685. {
  686. pjDst[ulWritePos] = jWorking;
  687. ulWritePos++;
  688. ulCount--;
  689. }
  690. // Account for the partial byte on the right side
  691. if (bIsOdd(lOutCol))
  692. {
  693. SetHighNybble(jWorking, (BYTE)ulNext);
  694. }
  695. // Adjust for the right side clipping.
  696. lOutCol += ulClipMargin;
  697. ulWritePos = lOutCol >> 1;
  698. }
  699. else
  700. {
  701. // Not on a visible scanline. Adjust our x output position
  702. lOutCol += ulCount;
  703. ulWritePos = lOutCol >> 1;
  704. } /* if */
  705. } /* if */
  706. } /* LOOP_FOREVER */
  707. } /* bSrcCopySRLE8D4 */
  708. /******************************Public*Routine******************************\
  709. * bSrcCopySRLE8D16
  710. *
  711. * Secure RLE blting to a 16 BPP DIB that does clipping and won't die or
  712. * write somewhere it shouldn't if given bad data.
  713. *
  714. * History:
  715. * 02 Feb 1992 - Andrew Milton (w-andym): Creation.
  716. *
  717. \**************************************************************************/
  718. BOOL
  719. bSrcCopySRLE8D16(
  720. PBLTINFO psb)
  721. {
  722. // Common RLE Initialization
  723. RLE_InitVars(psb, pjSrc, pwDst, PWORD, ulCount, ulNext, lOutCol, pulXlate);
  724. RLE_AssertValid(psb);
  725. RLE_FetchVisibleRect(psb);
  726. RLE_SetStartPos(psb, lOutCol);
  727. // Outta here if we start past the top edge. Don't need to save our position.
  728. if (RLE_PastTopEdge)
  729. return(TRUE); // Must have bits left in the bitmap since we haven't
  730. // consumed any.
  731. ULONG ulClipMargin = 0;
  732. // Main Processing Loop
  733. LOOP_FOREVER
  734. {
  735. // Outta here if we can't get two more bytes
  736. if (RLE_SourceExhausted(2))
  737. return(FALSE);
  738. RLE_GetNextCode(pjSrc, ulCount, ulNext);
  739. if (ulCount == 0)
  740. {
  741. // Absolute or Escape Mode
  742. switch (ulNext)
  743. {
  744. case 0:
  745. // Newline
  746. RLE_NextLine(PWORD, pwDst, lOutCol);
  747. if (RLE_PastTopEdge)
  748. {
  749. RLE_SavePosition(psb, pjSrc, pwDst, lOutCol);
  750. return(TRUE);
  751. }
  752. break;
  753. case 1:
  754. // End of the Bitmap
  755. return(FALSE);
  756. case 2:
  757. // Positional Delta. -- Fetch & Evaluate
  758. // Outta here if we can't get the delta values
  759. if (RLE_SourceExhausted(2))
  760. return(FALSE);
  761. RLE_GetNextCode(pjSrc, ulCount, ulNext);
  762. RLE_PosDelta(pwDst, lOutCol, ulCount, ulNext);
  763. if (RLE_PastTopEdge)
  764. {
  765. RLE_SavePosition(psb, pjSrc, pwDst, lOutCol);
  766. return(TRUE);
  767. }
  768. break;
  769. default:
  770. // Absolute Mode
  771. // Outta here if the bytes are not in the source
  772. if (RLE_SourceExhausted(ulNext))
  773. return(FALSE);
  774. RLE8_AlignToWord(pjSrc, ulNext);
  775. if (RLE_InVisibleRect(ulNext, lOutCol))
  776. {
  777. RLE8_AbsClipLeft(pjSrc, ulCount, ulNext, lOutCol);
  778. RLE8_ClipRight(ulCount, ulNext, lOutCol);
  779. // Slap the bits on. -- this is the funky-doodle stuff.
  780. while (ulNext--)
  781. {
  782. pwDst[lOutCol] = (WORD)pulXlate[(ULONG)*(pjSrc++)];
  783. lOutCol++;
  784. }
  785. // Adjust for the right side clipping
  786. pjSrc += ulCount;
  787. lOutCol += ulCount;
  788. }
  789. else
  790. {
  791. /* Not on a visible scanline.
  792. * Adjust our x output position and source pointer.
  793. */
  794. lOutCol += ulNext;
  795. pjSrc += ulNext;
  796. }
  797. // Fix up if this run was not WORD aligned.
  798. RLE8_FixAlignment(pjSrc)
  799. } /* switch */
  800. }
  801. else
  802. {
  803. // Encoded Mode
  804. if (RLE_InVisibleRect(ulCount, lOutCol))
  805. {
  806. ulNext = pulXlate[ulNext];
  807. RLE8_EncClipLeft(ulClipMargin, ulCount, lOutCol);
  808. RLE8_ClipRight(ulClipMargin, ulCount, lOutCol);
  809. // Slap the bits on.
  810. while (ulCount--)
  811. {
  812. pwDst[lOutCol] = (WORD)ulNext;
  813. lOutCol++;
  814. }
  815. // Adjust for the right side clipping.
  816. lOutCol += ulClipMargin;
  817. }
  818. else
  819. {
  820. // Not on a visible scanline. Adjust our x output position
  821. lOutCol += ulCount;
  822. } /* if */
  823. } /* if */
  824. } /* LOOP_FOREVER */
  825. } /* bSrcCopySRLE8D16 */
  826. /******************************Public*Routine******************************\
  827. * bSrcCopySRLE8D24
  828. *
  829. * Secure RLE blting to a 24 BPP DIB that does clipping and won't die or
  830. * write somewhere it shouldn't if given bad data.
  831. *
  832. * History:
  833. * 02 Feb 1992 - Andrew Milton (w-andym): Creation.
  834. *
  835. \**************************************************************************/
  836. #define RLE_24BitWrite(pjDst, BytePos, Colour) \
  837. pjDst[BytePos] = (BYTE)Colour; \
  838. pjDst[BytePos+1] = (BYTE)(Colour >> 8); \
  839. pjDst[BytePos+2] = (BYTE)(Colour >> 16); \
  840. BytePos += 3; \
  841. BOOL
  842. bSrcCopySRLE8D24(
  843. PBLTINFO psb)
  844. {
  845. // Common RLE Initialization
  846. RLE_InitVars(psb, pjSrc, pjDst, PBYTE, ulCount, ulNext, lOutCol, pulXlate);
  847. RLE_AssertValid(psb);
  848. RLE_FetchVisibleRect(psb);
  849. RLE_SetStartPos(psb, lOutCol);
  850. // Outta here if we start past the top edge. Don't need to save our position.
  851. if (RLE_PastTopEdge)
  852. return(TRUE); // Must have bits left in the bitmap since we haven't
  853. // consumed any.
  854. // Extra Variables
  855. ULONG ulWritePos;
  856. ULONG ulNextColour;
  857. // Main Processing Loop
  858. LOOP_FOREVER
  859. {
  860. // Outta here if we can't get two more bytes
  861. if (RLE_SourceExhausted(2))
  862. return(FALSE);
  863. RLE_GetNextCode(pjSrc, ulCount, ulNext);
  864. if (ulCount == 0)
  865. {
  866. // Absolute or Escape Mode
  867. switch (ulNext)
  868. {
  869. case 0:
  870. // New line
  871. RLE_NextLine(PBYTE, pjDst, lOutCol);
  872. if (RLE_PastTopEdge)
  873. {
  874. RLE_SavePosition(psb, pjSrc, pjDst, lOutCol);
  875. return(TRUE);
  876. }
  877. break;
  878. case 1:
  879. // End of the Bitmap
  880. return(FALSE);
  881. case 2:
  882. // Positional Delta. Fetch & Evaluate
  883. // Outta here if we can't get the delta values
  884. if (RLE_SourceExhausted(2))
  885. return(FALSE);
  886. RLE_GetNextCode(pjSrc, ulCount, ulNext);
  887. RLE_PosDelta(pjDst, lOutCol, ulCount, ulNext);
  888. if (RLE_PastTopEdge)
  889. {
  890. RLE_SavePosition(psb, pjSrc, pjDst, lOutCol);
  891. return(TRUE);
  892. }
  893. break;
  894. default:
  895. // Absolute Mode
  896. // Outta here if the bytes are not in the source
  897. if (RLE_SourceExhausted(ulNext))
  898. return(FALSE);
  899. RLE8_AlignToWord(pjSrc, ulNext);
  900. if (RLE_InVisibleRect(ulNext, lOutCol))
  901. {
  902. RLE8_AbsClipLeft(pjSrc, ulCount, ulNext, lOutCol);
  903. ulWritePos = 3*lOutCol;
  904. RLE8_ClipRight(ulCount, ulNext, lOutCol);
  905. // Slap the bits on. -- this is the funky-doodle stuff.
  906. // Brute force & ignorance hard at work in this loop
  907. while (ulNext--)
  908. {
  909. ulNextColour = pulXlate[*pjSrc++];
  910. RLE_24BitWrite(pjDst, ulWritePos, ulNextColour);
  911. lOutCol += 1;
  912. }
  913. // Adjust for the right side clipping.
  914. pjSrc += ulCount;
  915. lOutCol += ulCount;
  916. }
  917. else
  918. {
  919. /* Not on a visible scanline.
  920. * Adjust our x output position and source pointer.
  921. */
  922. lOutCol += ulNext;
  923. pjSrc += ulNext;
  924. } /* if */
  925. // Fix up if this run was not WORD aligned.
  926. RLE8_FixAlignment(pjSrc)
  927. } /* switch */
  928. }
  929. else
  930. {
  931. // Encoded Mode
  932. if (RLE_InVisibleRect(ulCount, lOutCol))
  933. {
  934. ULONG ulClipMargin = 0;
  935. ulNext = pulXlate[ulNext];
  936. RLE8_EncClipLeft(ulClipMargin, ulCount, lOutCol);
  937. RLE8_ClipRight(ulClipMargin, ulCount, lOutCol);
  938. ulWritePos = 3*lOutCol;
  939. lOutCol += ulCount;
  940. // Slap the bits on. -- Not very funky-doodle this time....
  941. // ...but more brute force and ignorance
  942. while (ulCount--)
  943. {
  944. RLE_24BitWrite(pjDst, ulWritePos, ulNext);
  945. }
  946. // Adjust for the right side clipping.
  947. lOutCol += ulClipMargin;
  948. }
  949. else
  950. {
  951. /* Not on a visible scanline.
  952. * Adjust our x output position
  953. */
  954. lOutCol += ulCount;
  955. } /* if */
  956. } /* if */
  957. } /* LOOP_FOREVER */
  958. } /* bSrcCopySRLE8D24 */
  959. /******************************Public*Routine******************************\
  960. * bSrcCopySRLE8D32
  961. *
  962. * Secure RLE blting to a 32 BPP DIB that does clipping and won't die or
  963. * write somewhere it shouldn't if given bad data.
  964. *
  965. * History:
  966. * 02 Feb 1992 - Andrew Milton (w-andym): Creation.
  967. *
  968. \**************************************************************************/
  969. BOOL
  970. bSrcCopySRLE8D32(
  971. PBLTINFO psb)
  972. {
  973. // Common RLE Initialization
  974. RLE_InitVars(psb, pjSrc, pdwDst, PDWORD, ulCount, ulNext,
  975. lOutCol, pulXlate);
  976. RLE_AssertValid(psb);
  977. RLE_FetchVisibleRect(psb);
  978. RLE_SetStartPos(psb, lOutCol);
  979. // Outta here if we start past the top edge. Don't need to save our position.
  980. if (RLE_PastTopEdge)
  981. return(TRUE); // Must have bits left in the bitmap since we haven't
  982. // consumed any.
  983. // Main Process Loop
  984. LOOP_FOREVER
  985. {
  986. // Outta here if we can't get two more bytes
  987. if (RLE_SourceExhausted(2))
  988. return(FALSE);
  989. RLE_GetNextCode(pjSrc, ulCount, ulNext);
  990. if (ulCount == 0)
  991. {
  992. // Absolute or Escape Mode
  993. switch (ulNext)
  994. {
  995. case 0:
  996. // New line
  997. RLE_NextLine(PDWORD, pdwDst, lOutCol);
  998. if (RLE_PastTopEdge)
  999. {
  1000. RLE_SavePosition(psb, pjSrc, pdwDst, lOutCol);
  1001. return(TRUE);
  1002. }
  1003. break;
  1004. case 1:
  1005. // End of the Bitmap
  1006. return(FALSE);
  1007. case 2:
  1008. // Positional Delta. -- Fetch & Evaluate
  1009. // Outta here if we can't get the delta values
  1010. if (RLE_SourceExhausted(2))
  1011. return(FALSE);
  1012. RLE_GetNextCode(pjSrc, ulCount, ulNext);
  1013. RLE_PosDelta(pdwDst, lOutCol, ulCount, ulNext);
  1014. if (RLE_PastTopEdge)
  1015. {
  1016. RLE_SavePosition(psb, pjSrc, pdwDst, lOutCol);
  1017. return(TRUE);
  1018. }
  1019. break;
  1020. default:
  1021. // Absolute Mode
  1022. // Outta here if the bytes are not in the source
  1023. if (RLE_SourceExhausted(ulNext))
  1024. return(FALSE);
  1025. RLE8_AlignToWord(pjSrc, ulNext);
  1026. if (RLE_InVisibleRect(ulNext, lOutCol))
  1027. {
  1028. RLE8_AbsClipLeft(pjSrc, ulCount, ulNext, lOutCol);
  1029. RLE8_ClipRight(ulCount, ulNext, lOutCol);
  1030. // Slap the bits on. -- this is the funky-doodle stuff.
  1031. while (ulNext--)
  1032. {
  1033. pdwDst[lOutCol] = pulXlate[(ULONG) *(pjSrc++)];
  1034. lOutCol++;
  1035. }
  1036. // Adjust for the right side clipping.
  1037. lOutCol += ulCount;
  1038. pjSrc += ulCount;
  1039. }
  1040. else
  1041. {
  1042. /* Not on a visible scanline.
  1043. * Adjust our x output position and source pointer.
  1044. */
  1045. lOutCol += ulNext;
  1046. pjSrc += ulNext;
  1047. } /* if */
  1048. // Fix up if this run was not WORD aligned.
  1049. RLE8_FixAlignment(pjSrc)
  1050. } /* switch */
  1051. }
  1052. else
  1053. {
  1054. // Encoded Mode
  1055. if (RLE_InVisibleRect(ulCount, lOutCol))
  1056. {
  1057. ULONG ulClipMargin = 0;
  1058. ulNext = pulXlate[ulNext];
  1059. RLE8_EncClipLeft(ulClipMargin, ulCount, lOutCol);
  1060. RLE8_ClipRight(ulClipMargin, ulCount, lOutCol);
  1061. // Slap the bits on.
  1062. while (ulCount--)
  1063. {
  1064. pdwDst[lOutCol] = ulNext;
  1065. lOutCol++;
  1066. }
  1067. // Adjust for the right side clipping.
  1068. lOutCol += ulClipMargin;
  1069. }
  1070. else
  1071. {
  1072. // Not on a visible scanline. Adjust our x output position
  1073. lOutCol += ulCount;
  1074. } /* if */
  1075. } /* if */
  1076. } /* LOOP_FOREVER */
  1077. } /* bSrcCopySRLE8D32 */
  1078. /*******************************Public*Routine*****************************\
  1079. * WriteEncoded8
  1080. *
  1081. * A helper function for EncodeRLE8. Writes a run of bytes in encoded format.
  1082. *
  1083. * Created: 28 Oct 92 @ 14:00
  1084. *
  1085. * Author: Gerrit van Wingerden [gerritv]
  1086. *
  1087. \**************************************************************************/
  1088. int WriteEncoded8( BYTE bValue, BYTE *pbTarget, UINT uiLength,
  1089. BYTE *pbEndOfBuffer )
  1090. {
  1091. if( pbTarget == NULL )
  1092. return(2);
  1093. if( pbTarget + 2 > pbEndOfBuffer )
  1094. return(0);
  1095. *pbTarget++ = (BYTE) uiLength;
  1096. *pbTarget++ = bValue;
  1097. return(2);
  1098. }
  1099. /*******************************Public*Routine*****************************\
  1100. * WriteAbsolute8
  1101. *
  1102. * A helper function for EncodeRLE8. Writes a run of bytes in absolute format.
  1103. *
  1104. * Created: 28 Oct 92 @ 14:00
  1105. *
  1106. * Author: Gerrit van Wingerden [gerritv]
  1107. *
  1108. \**************************************************************************/
  1109. int WriteAbsolute8( BYTE *pbRunStart, BYTE *pbTarget, int cRunLength,
  1110. BYTE *pbEndOfBuffer )
  1111. {
  1112. int iRet;
  1113. if( cRunLength == 1 )
  1114. {
  1115. iRet = 2;
  1116. }
  1117. else
  1118. {
  1119. if( cRunLength == 2 )
  1120. {
  1121. iRet = 4;
  1122. }
  1123. else
  1124. {
  1125. if( cRunLength & 0x01 )
  1126. {
  1127. iRet = cRunLength + 3;
  1128. }
  1129. else
  1130. {
  1131. iRet = cRunLength + 2;
  1132. }
  1133. }
  1134. }
  1135. if( pbTarget == NULL )
  1136. return(iRet);
  1137. if( pbTarget + iRet > pbEndOfBuffer )
  1138. return(0);
  1139. if( cRunLength == 1 )
  1140. {
  1141. *pbTarget++ = 0x01;
  1142. *pbTarget = *pbRunStart;
  1143. return(2);
  1144. }
  1145. if( cRunLength == 2 )
  1146. {
  1147. *pbTarget++ = 0x01;
  1148. *pbTarget++ = *pbRunStart++;
  1149. *pbTarget++ = 0x01;
  1150. *pbTarget = *pbRunStart;
  1151. return(4);
  1152. }
  1153. *pbTarget++ = 0;
  1154. *pbTarget++ = (BYTE) cRunLength;
  1155. RtlMoveMemory( pbTarget, pbRunStart, cRunLength );
  1156. pbTarget += cRunLength;
  1157. if( cRunLength & 0x01 )
  1158. {
  1159. *pbTarget++ = 0;
  1160. return( iRet );
  1161. }
  1162. else
  1163. return( iRet );
  1164. }
  1165. /*******************************Public*Routine*****************************\
  1166. * EncodeRLE8
  1167. *
  1168. * Encodes a bitmap into RLE8 format and returns the length of the of the
  1169. * encoded format. If the target is NULL it just returns the length of
  1170. * the format. If there is a target and the encoded output is longer than
  1171. * cBufferSize then the function stops encoding and returns 0.
  1172. *
  1173. * History:
  1174. * 28 Oct 1992 Gerrit van Wingerden [gerritv] : creation
  1175. * 15 Mar 1993 Stephan J. Zachwieja [szach] : return 0 if buffer too small
  1176. *
  1177. \**************************************************************************/
  1178. int EncodeRLE8( BYTE *pbSource, BYTE *pbTarget, UINT uiWidth, UINT cNumLines,
  1179. UINT cBufferSize )
  1180. {
  1181. UINT cLineCount;
  1182. BYTE bLastByte;
  1183. BYTE *pbEndOfBuffer;
  1184. BYTE *pbRunStart;
  1185. BYTE *pbLineEnd;
  1186. BYTE *pbCurPos;
  1187. BYTE bCurChar;
  1188. INT cCurrentRunLength;
  1189. INT iMode, cTemp, uiLineWidth;
  1190. UINT cTotal = 0;
  1191. pbEndOfBuffer = pbTarget + cBufferSize;
  1192. uiLineWidth = ( ( uiWidth + 3 ) >> 2 ) << 2;
  1193. for( cLineCount = 0; cLineCount < cNumLines; cLineCount ++ )
  1194. {
  1195. pbRunStart = pbSource + uiLineWidth * cLineCount;
  1196. bLastByte = *pbRunStart;
  1197. pbLineEnd = pbRunStart + uiWidth;
  1198. iMode = RLE_START;
  1199. cCurrentRunLength = 1;
  1200. for(pbCurPos = pbRunStart+1;pbCurPos <= pbLineEnd; pbCurPos += 1)
  1201. {
  1202. // We won't really encode the value at *pbLineEnd since it points
  1203. // past the end of the scan so it doesn't matter what value we use.
  1204. // However, it is important not to reference it since it may point
  1205. // past the end of the buffer which can be uncommited memory.
  1206. if( pbCurPos == pbLineEnd )
  1207. {
  1208. bCurChar = 0xFF;
  1209. }
  1210. else
  1211. {
  1212. bCurChar = *pbCurPos;
  1213. }
  1214. switch( iMode )
  1215. {
  1216. case RLE_START:
  1217. iMode = (bCurChar == bLastByte) ? RLE_ENCODED : RLE_ABSOLUTE;
  1218. bLastByte = bCurChar;
  1219. break;
  1220. case RLE_ABSOLUTE:
  1221. if( ( bCurChar == bLastByte ) ||
  1222. ( cCurrentRunLength == 0xFF ) )
  1223. {
  1224. int iOffset;
  1225. if( cCurrentRunLength == 0xFF )
  1226. {
  1227. iOffset = 0;
  1228. iMode = RLE_START;
  1229. }
  1230. else
  1231. {
  1232. iOffset = 1;
  1233. iMode = RLE_ENCODED;
  1234. }
  1235. // if pbTarget is not NULL and cTemp is zero then
  1236. // the buffer is too small to hold encoded data
  1237. cTemp = WriteAbsolute8(pbRunStart, pbTarget,
  1238. cCurrentRunLength - iOffset, pbEndOfBuffer);
  1239. if(pbTarget != NULL) {
  1240. if (cTemp == 0) return(0);
  1241. pbTarget += cTemp;
  1242. }
  1243. cTotal += cTemp;
  1244. pbRunStart = pbCurPos;
  1245. cCurrentRunLength = iOffset;
  1246. }
  1247. bLastByte = bCurChar;
  1248. break;
  1249. case RLE_ENCODED:
  1250. if( ( bCurChar != bLastByte ) ||
  1251. ( cCurrentRunLength == 0xFF ) )
  1252. {
  1253. cTemp = WriteEncoded8( bLastByte, pbTarget,
  1254. cCurrentRunLength, pbEndOfBuffer);
  1255. // if pbTarget is not NULL and cTemp is zero then
  1256. // the buffer is too small to hold encoded data
  1257. if (pbTarget != NULL) {
  1258. if (cTemp == 0) return(0);
  1259. pbTarget += cTemp;
  1260. }
  1261. cTotal += cTemp;
  1262. bLastByte = bCurChar;
  1263. pbRunStart = pbCurPos;
  1264. cCurrentRunLength = 0;
  1265. iMode = RLE_START ;
  1266. }
  1267. }
  1268. cCurrentRunLength += 1;
  1269. }
  1270. if( cCurrentRunLength > 1 )
  1271. {
  1272. if(iMode == RLE_ABSOLUTE)
  1273. cTemp = WriteAbsolute8(pbRunStart, pbTarget,
  1274. cCurrentRunLength - 1, pbEndOfBuffer);
  1275. else {
  1276. cTemp = WriteEncoded8(bLastByte, pbTarget,
  1277. cCurrentRunLength - 1, pbEndOfBuffer);
  1278. }
  1279. // if pbTarget is not NULL and cTemp is zero then
  1280. // the buffer is too small to hold encoded data
  1281. if (pbTarget != NULL) {
  1282. if (cTemp == 0) return(0);
  1283. pbTarget += cTemp;
  1284. }
  1285. cTotal += cTemp;
  1286. }
  1287. if( pbTarget <= pbEndOfBuffer )
  1288. cTotal += 2;
  1289. if( pbTarget != NULL )
  1290. {
  1291. *((WORD *) pbTarget) = 0;
  1292. pbTarget += 2;
  1293. }
  1294. }
  1295. // Write "End of bitmap" at the end so we're win31 compatible.
  1296. if( pbTarget == NULL )
  1297. return(cTotal + 2);
  1298. if( pbTarget + 2 > pbEndOfBuffer )
  1299. return(0);
  1300. *pbTarget++ = 0;
  1301. *pbTarget++ = 1;
  1302. return(cTotal + 2);
  1303. }