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.

285 lines
14 KiB

  1. /* rleblt.h
  2. *
  3. * Modified: 21 Oct 1992 by Gerrit van Wingerden [gerritv]
  4. *
  5. * Purpose: Added an enumerated type and function prototypes for RLE
  6. * compression routines.
  7. *
  8. * Created: 5 Mar 1992 by Andrew Milton (w-andym)
  9. *
  10. * Purpose: Contains support macros for the RLE blt functions in
  11. * <rle4blt.cxx> and <rle8blt.cxx>
  12. *
  13. * See the notes section of the above files for more info about these macros
  14. *
  15. * Contents: (The interesting macros only)
  16. *
  17. * RLE_InitVars - Declares & initializes the variables for output position
  18. * management and source access in all RLE blt functions.
  19. *
  20. * RLE_AssertValid - ASSERTs to verify the BLTINFO structure has good data
  21. *
  22. * RLE_FetchVisibleRect - Declares the visible region variables & initializes
  23. * them from the BLTINFO structure
  24. *
  25. * RLE_SetStartPos - Initializes the output position on the DIB for the RLE
  26. *
  27. * RLE_SourceExhausted - Verifies that the source contains n more bytes.
  28. *
  29. * RLE_GetNextCode - Fetches an RLE code.
  30. *
  31. * RLE_NextLine - Advances to the next line of output on the destination DIB
  32. *
  33. * RLE_PosDelta - Changes the output postion on the DIB. The delta is
  34. * ALWAYS up the DIB, but may move left or right.
  35. *
  36. * RLE_InVisibleRect - Checks if any portion of a run will fall inside the
  37. * visible region.
  38. *
  39. * RLE_ForceBounds - Returns the left/(right) boundary if an output column is
  40. * before/(after) the left/(right) edge. If the column is
  41. * inside the interval it does nothing.
  42. *
  43. * RLE_SavePositon - Saves the current output position, source pointer,
  44. * destination pointer, and RLE bytes consumed into the
  45. * BLTINFO structure. This information is used by
  46. * <EngCopyBits> for complex clipping optimization.
  47. *
  48. * Copyright (c) 1992-1999 Microsoft Corporation
  49. *
  50. \***************************************************************************/
  51. /* Miscellaneous Macros *****************************************************/
  52. #define GetLowNybble(b) ((b) & 0x0F)
  53. /* Byte Manipulators */
  54. #define GetHighNybble(b) ( ( (b) & 0xF0) >> 4)
  55. #define SetLowNybble(b, rn) b = ( ((b) & 0xF0) | ((rn) & 0x0F) )
  56. #define SetHighNybble(b, ln) b = ( ((b) & 0x0F) | (((ln) & 0x0F) << 4) )
  57. #define BuildByte(ln, rn) (BYTE) ((((ln) & 0x0F) << 4) | ((rn) & 0x0F))
  58. /* Word Manipulators */
  59. #define GetLowByte(w) ((w) & 0x00FF)
  60. #define GetHighByte(w) ( ( (w) & 0xFF00) >> 8)
  61. #define SetLowByte(w, b) w = ( ((w) & 0xFF00) | ((b) & 0x00FF) )
  62. #define SetHighByte(w, b) w = ( ((w) & 0x00FF) | (((b) & 0x00FF) << 4) )
  63. #define RollLeft(x) ( ((x) & 0x80) ? ((x) << 1) | 0x01 : (x) << 1 )
  64. #define RollRight(x) ( ((x) & 0x01) ? ((x) >> 1) | 0x80 : (x) >> 1 )
  65. #define SwapValues(x, y) (x) ^= (y); \
  66. (y) ^= (x); \
  67. (x) ^= (y);
  68. /****************************************************************************
  69. *
  70. * RLE4_MakeColourBlock - Unpacks & translates a packed byte of 2 colours
  71. * into an array
  72. *
  73. * RLE4_MakePackedWord - Unpacks & translates a packed byte of 2 colours
  74. * into 8 Bits/Pel and packs them into a word
  75. *
  76. * RLE4_MakePackedDWord - Unpacks & translates a packed byte of 2 colours
  77. * into 16 Bits/Pel and packs them into a double word
  78. *
  79. * RLE4_AlignToWord - Verifies all bytes of an Absolute run exist in the
  80. * source & sets a flag if the run does not end on a
  81. * word boundary.
  82. *
  83. * RLE4_FixAlignment - Forces the source pointer to a word boundary if the
  84. * flag was set by <RLE4_AlignToWord>
  85. *
  86. ****************************************************************************/
  87. /* Source Byte Unpacking ****************************************************/
  88. #define RLE4_MakeColourBlock(PackedColours, ColourBlock, Type, Trans) \
  89. ColourBlock[0] = (Type) Trans[GetHighNybble(PackedColours)]; \
  90. ColourBlock[1] = (Type) Trans[GetLowNybble(PackedColours)]; \
  91. #define RLE4_MakePackedWord(PackedColours, PackedWord, Trans) \
  92. PackedWord = (( (WORD) Trans[GetHighNybble(PackedColours)] ) << 8); \
  93. PackedWord |= ( (WORD) Trans[GetLowNybble(PackedColours)] ); \
  94. #define RLE4_MakePackedDWord(PackedColours, PackedDWord, Trans) \
  95. PackedDWord = (( Trans[GetHighNybble(PackedColours)] ) << 16); \
  96. PackedDWord |= ( Trans[GetLowNybble(PackedColours)] ); \
  97. /* Source Alignment Macros **************************************************/
  98. #define RLE4_ByteLength(RunLength) ((RunLength + 1) >> 1)
  99. #define RLE4_AlignToWord(SrcPtr, RunLength) \
  100. ulNotAligned = ((1 + RunLength) >> 1) & 1;
  101. #define RLE4_FixAlignment(SrcPtr) \
  102. ulSrcIndex += ulNotAligned; \
  103. SrcPtr += ulNotAligned;
  104. /****************************************************************************
  105. *
  106. * RLE8_AbsClipLeft - Forces an Absolute run to start at the left edge of
  107. * the visible region when the current output column is
  108. * before the left edge.
  109. *
  110. * RLE8_EncClipLeft - Forces an Encoded run to start at the left edge of
  111. * the visible region when the current output column is
  112. * before the left edge.
  113. *
  114. * RLE8_AbsClipLeft - Forces any run to end at the right edge of the visible
  115. * region when it extends beyond the right edge
  116. *
  117. * RLE8_AlignToWord - Verifies all bytes of an Absolute run exist in the
  118. * source & sets a flag if the run does not end on a
  119. * word boundary.
  120. *
  121. * RLE8_FixAlignment - Forces the source pointer to a word boundary if
  122. * the flag was set by <RLE8_AlignToWord>
  123. *
  124. ****************************************************************************/
  125. /* Clipping Macros *********************************************************/
  126. #define RLE8_AbsClipLeft(SrcPtr, IndentAmount, RunLength, OutColumn) \
  127. if (OutColumn < (LONG)ulDstLeft) \
  128. { \
  129. IndentAmount = ulDstLeft - OutColumn; \
  130. OutColumn = ulDstLeft; \
  131. SrcPtr += IndentAmount; \
  132. RunLength -= IndentAmount; \
  133. }
  134. #define RLE8_EncClipLeft(IndentAmount, RunLength, OutColumn) \
  135. if (OutColumn < (LONG)ulDstLeft) \
  136. { \
  137. IndentAmount = ulDstLeft - OutColumn; \
  138. RunLength -= IndentAmount; \
  139. OutColumn += IndentAmount; \
  140. } \
  141. #define RLE8_ClipRight(OverRun, RunLength, OutColumn) \
  142. if ((OutColumn + (LONG) RunLength) > (LONG)ulDstRight) \
  143. { \
  144. OverRun = (OutColumn + RunLength) - ulDstRight; \
  145. RunLength -= OverRun; \
  146. } else \
  147. OverRun = 0; \
  148. /* Source Alignment Macros **************************************************/
  149. #define RLE8_AlignToWord(SrcPtr, RunLength) \
  150. ulNotAligned = RunLength & 1; \
  151. #define RLE8_FixAlignment(SrcPtr) \
  152. ulSrcIndex += ulNotAligned; \
  153. SrcPtr += ulNotAligned;
  154. #define LOOP_FOREVER while(1)
  155. #define bIsOdd(x) ((x) & 1)
  156. #define BoundsCheck(a, b, x) ( ((x) >= (a)) ? ( ((x) <= (b)) ? (x) : (b) ) \
  157. : (a) )
  158. /* Startup and Initialization Macros ****************************************/
  159. #define RLE_InitVars(BI, Source, Dest, DstType, Count, Colour, \
  160. OutColumn, Xlate) \
  161. LONG OutColumn; /* Offest from <pjDst> to get to the output column */ \
  162. LONG lOutRow; /* Output scanline */ \
  163. \
  164. ULONG Count; /* First byte of an RLE code */ \
  165. ULONG Colour; /* Second byte of an RLE code */ \
  166. \
  167. PBYTE Source = (BI)->pjSrc; /* Current location into the source RLE */ \
  168. DstType Dest = (DstType)(BI)->pjDst; /* Beginning of crnt. out line */ \
  169. LONG lDeltaDst = (BI)->lDeltaDst / (LONG)sizeof(Dest[0]); \
  170. \
  171. ULONG ulSrcIndex = (BI)->ulConsumed; \
  172. ULONG ulSrcLength = (BI)->pdioSrc->cjBits(); \
  173. \
  174. PULONG Xlate = (BI)->pxlo->pulXlate; \
  175. \
  176. ULONG ulNotAligned; \
  177. #define RLE_AssertValid(BI) \
  178. ASSERTGDI((BI)->xDir == 1, "RLE4 - direction not left to right"); \
  179. ASSERTGDI((BI)->yDir == -1, "RLE4 - direction not up to down"); \
  180. ASSERTGDI((BI)->lDeltaSrc == 0, "RLE - lDeltaSrc not 0"); \
  181. ASSERTGDI(pulXlate != (PULONG) NULL, "ERROR pulXlate NULL in RLE"); \
  182. #define RLE_FetchVisibleRect(BI) \
  183. /* Fetch the visible region boundaries of the passed structure */ \
  184. ULONG ulDstLeft = (BI)->rclDst.left; \
  185. ULONG ulDstRight = (BI)->rclDst.right; \
  186. ULONG ulDstTop = (BI)->rclDst.top; \
  187. ULONG ulDstBottom = (BI)->rclDst.bottom; \
  188. #define RLE_SetStartPos(BI, InitialColumn) \
  189. /* Initialize the starting positions */ \
  190. LONG lDstStart = (BI)->xDstStart; \
  191. InitialColumn = (BI)->ulOutCol; \
  192. lOutRow = (LONG) (BI)->yDstStart; \
  193. /* Source Access ************************************************************/
  194. #define RLE_SourceExhausted(Count) \
  195. ((ulSrcIndex += (Count)) > ulSrcLength)
  196. #define RLE_GetNextCode(SrcPtr, Count, Colour) \
  197. Count = (ULONG) *(SrcPtr++); \
  198. Colour = (ULONG) *(SrcPtr++); \
  199. /* Output Position Change Macros ********************************************/
  200. #define RLE_NextLine(DstType, DstPtr, OutColumn) \
  201. /* Goto the next row */ \
  202. DstPtr += lDeltaDst; \
  203. OutColumn = lDstStart; \
  204. lOutRow -= 1; \
  205. #define RLE_PosDelta(DstPtr, OutColumn, ColDelta, RowDelta) \
  206. OutColumn += ColDelta; \
  207. DstPtr += (LONG) (RowDelta) * lDeltaDst; \
  208. lOutRow -= RowDelta; \
  209. /* Visability Check Macros **************************************************/
  210. #define RLE_InVisibleRect(RunLength, OutColumn) \
  211. ((lOutRow < (LONG) ulDstBottom) && \
  212. ((OutColumn) < (LONG)ulDstRight) && \
  213. (((OutColumn) + (LONG) (RunLength)) > (LONG) ulDstLeft)) \
  214. #define RLE_RowVisible ( (lOutRow < (LONG) ulDstBottom) \
  215. && (lOutRow >= (LONG) ulDstTop) )
  216. #define RLE_ColVisible(Col) ( ( (Col) >= (LONG) ulDstLeft ) \
  217. && ( (Col) < (LONG) ulDstRight ) )
  218. #define RLE_ForceBounds(Col) BoundsCheck(ulDstLeft, ulDstRight, Col)
  219. #define RLE_PastRightEdge(Col) ((Col) >= (LONG) ulDstRight)
  220. #define RLE_PastTopEdge (lOutRow < (LONG) ulDstTop)
  221. /* Ending Macro *************************************************************/
  222. #define RLE_SavePosition(BI, SrcPtr, DstPtr, OutColumn) \
  223. (BI)->ulEndConsumed = ulSrcIndex; \
  224. (BI)->pjSrcEnd = (SrcPtr); \
  225. (BI)->pjDstEnd = (PBYTE) (DstPtr); \
  226. (BI)->ulEndCol = (OutColumn); \
  227. (BI)->ulEndRow = (ULONG) lOutRow;
  228. enum RLE_TYPE { RLE_START, RLE_ABSOLUTE, RLE_ENCODED };
  229. int EncodeRLE8( BYTE*, BYTE *, UINT, UINT, UINT );
  230. int EncodeRLE4( BYTE*, BYTE*, UINT, UINT, UINT );