Sample Code
Windows Driver Samples/ MSPLOT Plotter Driver Sample/ C++/ plotter/ transpos.c/
/*++ 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); }
Our Services
-
What our customers say about us?
Read our customer testimonials to find out why our clients keep returning for their projects.
View Testimonials