/* rleblt.h * * Modified: 21 Oct 1992 by Gerrit van Wingerden [gerritv] * * Purpose: Added an enumerated type and function prototypes for RLE * compression routines. * * Created: 5 Mar 1992 by Andrew Milton (w-andym) * * Purpose: Contains support macros for the RLE blt functions in * and * * See the notes section of the above files for more info about these macros * * Contents: (The interesting macros only) * * RLE_InitVars - Declares & initializes the variables for output position * management and source access in all RLE blt functions. * * RLE_AssertValid - ASSERTs to verify the BLTINFO structure has good data * * RLE_FetchVisibleRect - Declares the visible region variables & initializes * them from the BLTINFO structure * * RLE_SetStartPos - Initializes the output position on the DIB for the RLE * * RLE_SourceExhausted - Verifies that the source contains n more bytes. * * RLE_GetNextCode - Fetches an RLE code. * * RLE_NextLine - Advances to the next line of output on the destination DIB * * RLE_PosDelta - Changes the output postion on the DIB. The delta is * ALWAYS up the DIB, but may move left or right. * * RLE_InVisibleRect - Checks if any portion of a run will fall inside the * visible region. * * RLE_ForceBounds - Returns the left/(right) boundary if an output column is * before/(after) the left/(right) edge. If the column is * inside the interval it does nothing. * * RLE_SavePositon - Saves the current output position, source pointer, * destination pointer, and RLE bytes consumed into the * BLTINFO structure. This information is used by * for complex clipping optimization. * * Copyright (c) 1992-1999 Microsoft Corporation * \***************************************************************************/ /* Miscellaneous Macros *****************************************************/ #define GetLowNybble(b) ((b) & 0x0F) /* Byte Manipulators */ #define GetHighNybble(b) ( ( (b) & 0xF0) >> 4) #define SetLowNybble(b, rn) b = ( ((b) & 0xF0) | ((rn) & 0x0F) ) #define SetHighNybble(b, ln) b = ( ((b) & 0x0F) | (((ln) & 0x0F) << 4) ) #define BuildByte(ln, rn) (BYTE) ((((ln) & 0x0F) << 4) | ((rn) & 0x0F)) /* Word Manipulators */ #define GetLowByte(w) ((w) & 0x00FF) #define GetHighByte(w) ( ( (w) & 0xFF00) >> 8) #define SetLowByte(w, b) w = ( ((w) & 0xFF00) | ((b) & 0x00FF) ) #define SetHighByte(w, b) w = ( ((w) & 0x00FF) | (((b) & 0x00FF) << 4) ) #define RollLeft(x) ( ((x) & 0x80) ? ((x) << 1) | 0x01 : (x) << 1 ) #define RollRight(x) ( ((x) & 0x01) ? ((x) >> 1) | 0x80 : (x) >> 1 ) #define SwapValues(x, y) (x) ^= (y); \ (y) ^= (x); \ (x) ^= (y); /**************************************************************************** * * RLE4_MakeColourBlock - Unpacks & translates a packed byte of 2 colours * into an array * * RLE4_MakePackedWord - Unpacks & translates a packed byte of 2 colours * into 8 Bits/Pel and packs them into a word * * RLE4_MakePackedDWord - Unpacks & translates a packed byte of 2 colours * into 16 Bits/Pel and packs them into a double word * * RLE4_AlignToWord - Verifies all bytes of an Absolute run exist in the * source & sets a flag if the run does not end on a * word boundary. * * RLE4_FixAlignment - Forces the source pointer to a word boundary if the * flag was set by * ****************************************************************************/ /* Source Byte Unpacking ****************************************************/ #define RLE4_MakeColourBlock(PackedColours, ColourBlock, Type, Trans) \ ColourBlock[0] = (Type) Trans[GetHighNybble(PackedColours)]; \ ColourBlock[1] = (Type) Trans[GetLowNybble(PackedColours)]; \ #define RLE4_MakePackedWord(PackedColours, PackedWord, Trans) \ PackedWord = (( (WORD) Trans[GetHighNybble(PackedColours)] ) << 8); \ PackedWord |= ( (WORD) Trans[GetLowNybble(PackedColours)] ); \ #define RLE4_MakePackedDWord(PackedColours, PackedDWord, Trans) \ PackedDWord = (( Trans[GetHighNybble(PackedColours)] ) << 16); \ PackedDWord |= ( Trans[GetLowNybble(PackedColours)] ); \ /* Source Alignment Macros **************************************************/ #define RLE4_ByteLength(RunLength) ((RunLength + 1) >> 1) #define RLE4_AlignToWord(SrcPtr, RunLength) \ ulNotAligned = ((1 + RunLength) >> 1) & 1; #define RLE4_FixAlignment(SrcPtr) \ ulSrcIndex += ulNotAligned; \ SrcPtr += ulNotAligned; /**************************************************************************** * * RLE8_AbsClipLeft - Forces an Absolute run to start at the left edge of * the visible region when the current output column is * before the left edge. * * RLE8_EncClipLeft - Forces an Encoded run to start at the left edge of * the visible region when the current output column is * before the left edge. * * RLE8_AbsClipLeft - Forces any run to end at the right edge of the visible * region when it extends beyond the right edge * * RLE8_AlignToWord - Verifies all bytes of an Absolute run exist in the * source & sets a flag if the run does not end on a * word boundary. * * RLE8_FixAlignment - Forces the source pointer to a word boundary if * the flag was set by * ****************************************************************************/ /* Clipping Macros *********************************************************/ #define RLE8_AbsClipLeft(SrcPtr, IndentAmount, RunLength, OutColumn) \ if (OutColumn < (LONG)ulDstLeft) \ { \ IndentAmount = ulDstLeft - OutColumn; \ OutColumn = ulDstLeft; \ SrcPtr += IndentAmount; \ RunLength -= IndentAmount; \ } #define RLE8_EncClipLeft(IndentAmount, RunLength, OutColumn) \ if (OutColumn < (LONG)ulDstLeft) \ { \ IndentAmount = ulDstLeft - OutColumn; \ RunLength -= IndentAmount; \ OutColumn += IndentAmount; \ } \ #define RLE8_ClipRight(OverRun, RunLength, OutColumn) \ if ((OutColumn + (LONG) RunLength) > (LONG)ulDstRight) \ { \ OverRun = (OutColumn + RunLength) - ulDstRight; \ RunLength -= OverRun; \ } else \ OverRun = 0; \ /* Source Alignment Macros **************************************************/ #define RLE8_AlignToWord(SrcPtr, RunLength) \ ulNotAligned = RunLength & 1; \ #define RLE8_FixAlignment(SrcPtr) \ ulSrcIndex += ulNotAligned; \ SrcPtr += ulNotAligned; #define LOOP_FOREVER while(1) #define bIsOdd(x) ((x) & 1) #define BoundsCheck(a, b, x) ( ((x) >= (a)) ? ( ((x) <= (b)) ? (x) : (b) ) \ : (a) ) /* Startup and Initialization Macros ****************************************/ #define RLE_InitVars(BI, Source, Dest, DstType, Count, Colour, \ OutColumn, Xlate) \ LONG OutColumn; /* Offest from to get to the output column */ \ LONG lOutRow; /* Output scanline */ \ \ ULONG Count; /* First byte of an RLE code */ \ ULONG Colour; /* Second byte of an RLE code */ \ \ PBYTE Source = (BI)->pjSrc; /* Current location into the source RLE */ \ DstType Dest = (DstType)(BI)->pjDst; /* Beginning of crnt. out line */ \ LONG lDeltaDst = (BI)->lDeltaDst / (LONG)sizeof(Dest[0]); \ \ ULONG ulSrcIndex = (BI)->ulConsumed; \ ULONG ulSrcLength = (BI)->pdioSrc->cjBits(); \ \ PULONG Xlate = (BI)->pxlo->pulXlate; \ \ ULONG ulNotAligned; \ #define RLE_AssertValid(BI) \ ASSERTGDI((BI)->xDir == 1, "RLE4 - direction not left to right"); \ ASSERTGDI((BI)->yDir == -1, "RLE4 - direction not up to down"); \ ASSERTGDI((BI)->lDeltaSrc == 0, "RLE - lDeltaSrc not 0"); \ ASSERTGDI(pulXlate != (PULONG) NULL, "ERROR pulXlate NULL in RLE"); \ #define RLE_FetchVisibleRect(BI) \ /* Fetch the visible region boundaries of the passed structure */ \ ULONG ulDstLeft = (BI)->rclDst.left; \ ULONG ulDstRight = (BI)->rclDst.right; \ ULONG ulDstTop = (BI)->rclDst.top; \ ULONG ulDstBottom = (BI)->rclDst.bottom; \ #define RLE_SetStartPos(BI, InitialColumn) \ /* Initialize the starting positions */ \ LONG lDstStart = (BI)->xDstStart; \ InitialColumn = (BI)->ulOutCol; \ lOutRow = (LONG) (BI)->yDstStart; \ /* Source Access ************************************************************/ #define RLE_SourceExhausted(Count) \ ((ulSrcIndex += (Count)) > ulSrcLength) #define RLE_GetNextCode(SrcPtr, Count, Colour) \ Count = (ULONG) *(SrcPtr++); \ Colour = (ULONG) *(SrcPtr++); \ /* Output Position Change Macros ********************************************/ #define RLE_NextLine(DstType, DstPtr, OutColumn) \ /* Goto the next row */ \ DstPtr += lDeltaDst; \ OutColumn = lDstStart; \ lOutRow -= 1; \ #define RLE_PosDelta(DstPtr, OutColumn, ColDelta, RowDelta) \ OutColumn += ColDelta; \ DstPtr += (LONG) (RowDelta) * lDeltaDst; \ lOutRow -= RowDelta; \ /* Visability Check Macros **************************************************/ #define RLE_InVisibleRect(RunLength, OutColumn) \ ((lOutRow < (LONG) ulDstBottom) && \ ((OutColumn) < (LONG)ulDstRight) && \ (((OutColumn) + (LONG) (RunLength)) > (LONG) ulDstLeft)) \ #define RLE_RowVisible ( (lOutRow < (LONG) ulDstBottom) \ && (lOutRow >= (LONG) ulDstTop) ) #define RLE_ColVisible(Col) ( ( (Col) >= (LONG) ulDstLeft ) \ && ( (Col) < (LONG) ulDstRight ) ) #define RLE_ForceBounds(Col) BoundsCheck(ulDstLeft, ulDstRight, Col) #define RLE_PastRightEdge(Col) ((Col) >= (LONG) ulDstRight) #define RLE_PastTopEdge (lOutRow < (LONG) ulDstTop) /* Ending Macro *************************************************************/ #define RLE_SavePosition(BI, SrcPtr, DstPtr, OutColumn) \ (BI)->ulEndConsumed = ulSrcIndex; \ (BI)->pjSrcEnd = (SrcPtr); \ (BI)->pjDstEnd = (PBYTE) (DstPtr); \ (BI)->ulEndCol = (OutColumn); \ (BI)->ulEndRow = (ULONG) lOutRow; enum RLE_TYPE { RLE_START, RLE_ABSOLUTE, RLE_ENCODED }; int EncodeRLE8( BYTE*, BYTE *, UINT, UINT, UINT ); int EncodeRLE4( BYTE*, BYTE*, UINT, UINT, UINT );