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.
 
 
 
 
 
 

477 lines
12 KiB

/*++
Copyright (c) 1990-2003 Microsoft Corporation
Module Name:
transpos.c
Abstract:
This module implements the functions for transposing an 8BPP, 4BPP and
1BPP bitmap. There is also a helper function for building a table which
speeds some of the rotation logic.
Author:
22-Dec-1993 Wed 13:09:11 created
[Environment:]
GDI Device Driver - Plotter.
[Notes:]
Revision History:
--*/
#include "precomp.h"
#pragma hdrstop
#define DBG_PLOTFILENAME DbgTransPos
#define DBG_BUILD_TP8x8 0x00000001
#define DBG_TP_1BPP 0x00000002
#define DBG_TP_4BPP 0x00000004
DEFINE_DBGVAR(0);
//
// Private #defines and data structures for use only in this module.
//
#define ENTRY_TP8x8 256
#define SIZE_TP8x8 (sizeof(DWORD) * 2 * ENTRY_TP8x8)
LPDWORD
Build8x8TransPosTable(
VOID
)
/*++
Routine Description:
This function build the 8x8 transpos table for use later in transposing
1bpp.
Arguments:
Return Value:
Author:
22-Dec-1993 Wed 14:19:50 created
Revision History:
--*/
{
LPDWORD pdwTP8x8;
//
// We now build the table which will represent the data for doing a
// rotation. Basically for each combination of bits in the byte, we
// build the equivalent 8 byte rotation for those bits. The 1st byte
// of the translated bytes are mapped to the 0x01 bit of the source and
// the last byte is mapped to the 0x80 bit.
if (pdwTP8x8 = (LPDWORD)LocalAlloc(LPTR, SIZE_TP8x8)) {
LPBYTE pbData = (LPBYTE)pdwTP8x8;
WORD Entry;
WORD Bits;
//
// Now start buiding the table, for each entry we expand each bit
// in the byte to the rotate byte value.
//
for (Entry = 0; Entry < ENTRY_TP8x8; Entry++) {
//
// For each of bit combinations in the byte, we will examine each
// bit from bit 0 to bit 7, and set each of the trasposed bytes to
// either 1 (bit set) or 0 (bit clear)
//
Bits = (WORD)Entry | (WORD)0xff00;
while (Bits & 0x0100) {
*pbData++ = (BYTE)(Bits & 0x01);
Bits >>= 1;
}
}
} else {
PLOTERR(("Build8x8TransPosTable: LocalAlloc(SIZE_TP8x8=%ld) failed",
SIZE_TP8x8));
}
return(pdwTP8x8);
}
BOOL
TransPos4BPP(
PTPINFO pTPInfo
)
/*++
Routine Description:
This function rotates a 4bpp source to a 4bpp destination
Arguments:
pTPINFO - Pointer to the TPINFO to describe how to do transpose, the fields
must be set to following
pPDev: Pointer to the PDEV
pSrc: Pointer to the soruce bitmap starting point
pDest Pointer to the destination bitmap location which stores the
transpos result starting from the fist destination scan
line in the rotated direction (rotating right will have
low nibble source bytes as the first destination scan line)
cbSrcScan: Count to be added to advance to next source bitmap line
cbDestScan: Count to be added to advance to the high nibble destination
bitmap line
cySrc Total source lines to be processed
DestXStart: not used, Ignored
NOTE: 1. The size of buffer area pointed to by pDestL must have at least
(((cySrc + 1) / 2) * 2) size in bytes, and ABS(DestDelta)
must at least half of that size.
2. Unused last destination byte will be padded with 0
Current transposition assumes the bitmap is rotated to the right, if caller
wants to rotate the bitmap to the left then you must first call the macro
ROTLEFT_4BPP_TPIINFO(pTPInfo)
Return Value:
TRUE if sucessful, FALSE if failed.
if sucessful the pTPInfo->pSrc will be automatically:
1. Incremented by one (1) if cbDestScan is negative (Rotated left 90 degree)
2. Decremented by one (1) if cbDestScan is positive (Rotated right 90 degree)
Author:
22-Dec-1993 Wed 13:11:30 created
Revision History:
--*/
{
LPBYTE pSrc;
LPBYTE pDest1st;
LPBYTE pDest2nd;
LONG cbSrcScan;
DWORD cySrc;
BYTE b0;
BYTE b1;
PLOTASSERT(1, "cbDestScan is not big enough (%ld)",
(DWORD)(ABS(pTPInfo->cbDestScan)) >=
(DWORD)(((pTPInfo->cySrc) + 1) >> 1), pTPInfo->cbDestScan);
//
// This is a simple 2x2 4bpp transpos, we will transpos only up to cySrc
// if cySrc is an odd number then the last destination low nibble is set
// padded with 0
//
// Scan 0 - Src0_H Src0_L pNibbleL - Src0_L Src1_L Src2_L Src3_L
// Scan 1 - Src1_H Src1_L ----> pNibbleH - Src0_H Src1_H Src2_H Src3_H
// Scan 2 - Src2_H Src2_L
// Scan 3 - Src3_H Src3_L
//
//
pSrc = pTPInfo->pSrc;
cbSrcScan = pTPInfo->cbSrcScan;
pDest1st = pTPInfo->pDest;
pDest2nd = pDest1st + pTPInfo->cbDestScan;
cySrc = pTPInfo->cySrc;
//
// Compute the transpose, leaving the last scan line for later. This
// way we don't pollute the loop with having to check if its the last
// line.
//
while (cySrc > 1) {
//
// Compose two input scan line buffers from the input scan buffer
// by reading in the Y direction
//
b0 = *pSrc;
b1 = *(pSrc += cbSrcScan);
*pDest1st++ = (BYTE)((b0 << 4) | (b1 & 0x0f));
*pDest2nd++ = (BYTE)((b1 >> 4) | (b0 & 0xf0));
pSrc += cbSrcScan;
cySrc -= 2;
}
//
// Deal with last odd source scan line
//
if (cySrc > 0) {
b0 = *pSrc;
*pDest1st = (BYTE)(b0 << 4);
*pDest2nd = (BYTE)(b0 & 0xf0);
}
pTPInfo->pSrc += (INT)((pTPInfo->cbDestScan > 0) ? -1 : 1);
return(TRUE);
}
BOOL
TransPos1BPP(
PTPINFO pTPInfo
)
/*++
Routine Description:
This function rotates a 1bpp source to 1bpp destination.
Arguments:
pTPINFO - Pointer to the TPINFO to describe how to do the transpose, the
fields must be set to the following:
pPDev: Pointer to the PDEV
pSrc: Pointer to the soruce bitmap starting point
pDest Pointer to the destination bitmap location which stores the
transpos result starting from the fist destination scan
line in the rotated direction (rotating right will have
0x01 source bit as first destination scan line)
cbSrcScan: Count to be added to advance to next source bitmap line
cbDestScan: Count to be added to advance to the next destination line
cySrc Total source lines to be processed
DestXStart Specifies where the transposed destination buffer starts,
in bit position. It is computed as DestXStart % 8. 0 means
it starts at the top bit (0x80), 1 means the next bit (0x40)
and so forth.
NOTE:
1. The ABS(DestDelta) must be large enough to accomodate the
transposed scan line. The size depends on cySrc and DestXStart,
the mimimum size must at least be of the size:
MinSize = (cySrc + (DestXStart % 8) + 7) / 8
2. The size of the buffer are pointed to by pDest must have at
least ABS(DestDelta) * 8 bytes, if cySrc >= 8, or
ABS(DestDelta) * cySrc if cySrc is less than 8.
3. Unused last byte destinations are padded with 0
Current transposition assumes the bitmap is rotated to the right, if caller
wants to rotate the bitmap to the left then you must first call the macro
ROTLEFT_1BPP_TPIINFO(pTPInfo)
Return Value:
TRUE if sucessful FALSE if failed
if sucessful the pTPInfo->pSrc will be automatically
1. Incremented by one (1) if cbDestScan is negative (Rotated left 90 degree)
2. Decremented by one (1) if cbDestScan is positive (Rotated right 90 degree)
Author:
22-Dec-1993 Wed 13:46:01 created
24-Dec-1993 Fri 04:58:24 updated
Fixed the RemainBits problem, we have to shift final data left if the
cySrc is already exhausted and RemainBits is not zero.
Revision History:
--*/
{
LPDWORD pdwTP8x8;
LPBYTE pSrc;
TPINFO TPInfo;
INT RemainBits;
INT cbNextDest;
union {
BYTE b[8];
DWORD dw[2];
} TPData;
TPInfo = *pTPInfo;
TPInfo.DestXStart &= 0x07;
PLOTASSERT(1, "cbDestScan is not big enough (%ld)",
(DWORD)(ABS(TPInfo.cbDestScan)) >=
(DWORD)((TPInfo.cySrc + TPInfo.DestXStart + 7) >> 3),
TPInfo.cbDestScan);
//
// Make sure we have the required transpose translate table. If we don't
// get one built.
//
if (!(pdwTP8x8 = (LPDWORD)pTPInfo->pPDev->pTransPosTable)) {
if (!(pdwTP8x8 = Build8x8TransPosTable())) {
PLOTERR(("TransPos1BPP: Build 8x8 transpos table failed"));
return(FALSE);
}
pTPInfo->pPDev->pTransPosTable = (LPVOID)pdwTP8x8;
}
//
// set up all required parameters, and start TPData with 0s
//
pSrc = TPInfo.pSrc;
RemainBits = (INT)(7 - TPInfo.DestXStart);
cbNextDest = (INT)((TPInfo.cbDestScan > 0) ? 1 : -1);
TPData.dw[0] =
TPData.dw[1] = 0;
while (TPInfo.cySrc--) {
LPDWORD pdwTmp;
LPBYTE pbTmp;
//
// Translate a byte to 8 bytes with each bit corresponding to each byte
// each byte is shifted to the left by 1 before combining with the new
// bit.
//
pdwTmp = pdwTP8x8 + ((UINT)*pSrc << 1);
TPData.dw[0] = (TPData.dw[0] << 1) | *(pdwTmp + 0);
TPData.dw[1] = (TPData.dw[1] << 1) | *(pdwTmp + 1);
pSrc += TPInfo.cbSrcScan;
//
// Check to see if we are done with source scan lines. If this is the
// case we need to possible shift the transposed scan lines by the
// apropriate number based on RemainBits.
//
if (!TPInfo.cySrc) {
//
// We are done, check to see if we need to shift the resultant
// transposed scan lines.
//
if (RemainBits) {
TPData.dw[0] <<= RemainBits;
TPData.dw[1] <<= RemainBits;
RemainBits = 0;
}
}
if (RemainBits--) {
NULL;
} else {
//
// Save the current result to the output destination scan buffer.
// Unwind the processing, to give the compiler a chance to generate
// some fast code, rather that relying on a while loop.
//
*(pbTmp = TPInfo.pDest ) = TPData.b[0];
*(pbTmp += TPInfo.cbDestScan) = TPData.b[1];
*(pbTmp += TPInfo.cbDestScan) = TPData.b[2];
*(pbTmp += TPInfo.cbDestScan) = TPData.b[3];
*(pbTmp += TPInfo.cbDestScan) = TPData.b[4];
*(pbTmp += TPInfo.cbDestScan) = TPData.b[5];
*(pbTmp += TPInfo.cbDestScan) = TPData.b[6];
*(pbTmp + TPInfo.cbDestScan) = TPData.b[7];
//
// Reset RemainBits back to 7, TPData back to 0 and and advance to
// the next destination
//
RemainBits = 7;
TPData.dw[0] =
TPData.dw[1] = 0;
TPInfo.pDest += cbNextDest;
}
}
//
// Since we succeded in transposing the bitmap, the next source byte
// location must be incremented or decremented by one.
//
// The cbNextDest is 1 if the bitmap is rotated to the right 90 degrees, so
// we want to decrement by 1.
//
// The cbNextDest is -1 if the bitmap is rotated to the right 90 degrees, so
// we want to increment by 1.
//
pTPInfo->pSrc -= cbNextDest;
return(TRUE);
}