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

  1. /*++
  2. Copyright (c) 1990-2003 Microsoft Corporation
  3. Module Name:
  4. transpos.c
  5. Abstract:
  6. This module implements the functions for transposing an 8BPP, 4BPP and
  7. 1BPP bitmap. There is also a helper function for building a table which
  8. speeds some of the rotation logic.
  9. Author:
  10. 22-Dec-1993 Wed 13:09:11 created
  11. [Environment:]
  12. GDI Device Driver - Plotter.
  13. [Notes:]
  14. Revision History:
  15. --*/
  16. #include "precomp.h"
  17. #pragma hdrstop
  18. #define DBG_PLOTFILENAME DbgTransPos
  19. #define DBG_BUILD_TP8x8 0x00000001
  20. #define DBG_TP_1BPP 0x00000002
  21. #define DBG_TP_4BPP 0x00000004
  22. DEFINE_DBGVAR(0);
  23. //
  24. // Private #defines and data structures for use only in this module.
  25. //
  26. #define ENTRY_TP8x8 256
  27. #define SIZE_TP8x8 (sizeof(DWORD) * 2 * ENTRY_TP8x8)
  28. LPDWORD
  29. Build8x8TransPosTable(
  30. VOID
  31. )
  32. /*++
  33. Routine Description:
  34. This function build the 8x8 transpos table for use later in transposing
  35. 1bpp.
  36. Arguments:
  37. Return Value:
  38. Author:
  39. 22-Dec-1993 Wed 14:19:50 created
  40. Revision History:
  41. --*/
  42. {
  43. LPDWORD pdwTP8x8;
  44. //
  45. // We now build the table which will represent the data for doing a
  46. // rotation. Basically for each combination of bits in the byte, we
  47. // build the equivalent 8 byte rotation for those bits. The 1st byte
  48. // of the translated bytes are mapped to the 0x01 bit of the source and
  49. // the last byte is mapped to the 0x80 bit.
  50. if (pdwTP8x8 = (LPDWORD)LocalAlloc(LPTR, SIZE_TP8x8)) {
  51. LPBYTE pbData = (LPBYTE)pdwTP8x8;
  52. WORD Entry;
  53. WORD Bits;
  54. //
  55. // Now start buiding the table, for each entry we expand each bit
  56. // in the byte to the rotate byte value.
  57. //
  58. for (Entry = 0; Entry < ENTRY_TP8x8; Entry++) {
  59. //
  60. // For each of bit combinations in the byte, we will examine each
  61. // bit from bit 0 to bit 7, and set each of the trasposed bytes to
  62. // either 1 (bit set) or 0 (bit clear)
  63. //
  64. Bits = (WORD)Entry | (WORD)0xff00;
  65. while (Bits & 0x0100) {
  66. *pbData++ = (BYTE)(Bits & 0x01);
  67. Bits >>= 1;
  68. }
  69. }
  70. } else {
  71. PLOTERR(("Build8x8TransPosTable: LocalAlloc(SIZE_TP8x8=%ld) failed",
  72. SIZE_TP8x8));
  73. }
  74. return(pdwTP8x8);
  75. }
  76. BOOL
  77. TransPos4BPP(
  78. PTPINFO pTPInfo
  79. )
  80. /*++
  81. Routine Description:
  82. This function rotates a 4bpp source to a 4bpp destination
  83. Arguments:
  84. pTPINFO - Pointer to the TPINFO to describe how to do transpose, the fields
  85. must be set to following
  86. pPDev: Pointer to the PDEV
  87. pSrc: Pointer to the soruce bitmap starting point
  88. pDest Pointer to the destination bitmap location which stores the
  89. transpos result starting from the fist destination scan
  90. line in the rotated direction (rotating right will have
  91. low nibble source bytes as the first destination scan line)
  92. cbSrcScan: Count to be added to advance to next source bitmap line
  93. cbDestScan: Count to be added to advance to the high nibble destination
  94. bitmap line
  95. cySrc Total source lines to be processed
  96. DestXStart: not used, Ignored
  97. NOTE: 1. The size of buffer area pointed to by pDestL must have at least
  98. (((cySrc + 1) / 2) * 2) size in bytes, and ABS(DestDelta)
  99. must at least half of that size.
  100. 2. Unused last destination byte will be padded with 0
  101. Current transposition assumes the bitmap is rotated to the right, if caller
  102. wants to rotate the bitmap to the left then you must first call the macro
  103. ROTLEFT_4BPP_TPIINFO(pTPInfo)
  104. Return Value:
  105. TRUE if sucessful, FALSE if failed.
  106. if sucessful the pTPInfo->pSrc will be automatically:
  107. 1. Incremented by one (1) if cbDestScan is negative (Rotated left 90 degree)
  108. 2. Decremented by one (1) if cbDestScan is positive (Rotated right 90 degree)
  109. Author:
  110. 22-Dec-1993 Wed 13:11:30 created
  111. Revision History:
  112. --*/
  113. {
  114. LPBYTE pSrc;
  115. LPBYTE pDest1st;
  116. LPBYTE pDest2nd;
  117. LONG cbSrcScan;
  118. DWORD cySrc;
  119. BYTE b0;
  120. BYTE b1;
  121. PLOTASSERT(1, "cbDestScan is not big enough (%ld)",
  122. (DWORD)(ABS(pTPInfo->cbDestScan)) >=
  123. (DWORD)(((pTPInfo->cySrc) + 1) >> 1), pTPInfo->cbDestScan);
  124. //
  125. // This is a simple 2x2 4bpp transpos, we will transpos only up to cySrc
  126. // if cySrc is an odd number then the last destination low nibble is set
  127. // padded with 0
  128. //
  129. // Scan 0 - Src0_H Src0_L pNibbleL - Src0_L Src1_L Src2_L Src3_L
  130. // Scan 1 - Src1_H Src1_L ----> pNibbleH - Src0_H Src1_H Src2_H Src3_H
  131. // Scan 2 - Src2_H Src2_L
  132. // Scan 3 - Src3_H Src3_L
  133. //
  134. //
  135. pSrc = pTPInfo->pSrc;
  136. cbSrcScan = pTPInfo->cbSrcScan;
  137. pDest1st = pTPInfo->pDest;
  138. pDest2nd = pDest1st + pTPInfo->cbDestScan;
  139. cySrc = pTPInfo->cySrc;
  140. //
  141. // Compute the transpose, leaving the last scan line for later. This
  142. // way we don't pollute the loop with having to check if its the last
  143. // line.
  144. //
  145. while (cySrc > 1) {
  146. //
  147. // Compose two input scan line buffers from the input scan buffer
  148. // by reading in the Y direction
  149. //
  150. b0 = *pSrc;
  151. b1 = *(pSrc += cbSrcScan);
  152. *pDest1st++ = (BYTE)((b0 << 4) | (b1 & 0x0f));
  153. *pDest2nd++ = (BYTE)((b1 >> 4) | (b0 & 0xf0));
  154. pSrc += cbSrcScan;
  155. cySrc -= 2;
  156. }
  157. //
  158. // Deal with last odd source scan line
  159. //
  160. if (cySrc > 0) {
  161. b0 = *pSrc;
  162. *pDest1st = (BYTE)(b0 << 4);
  163. *pDest2nd = (BYTE)(b0 & 0xf0);
  164. }
  165. pTPInfo->pSrc += (INT)((pTPInfo->cbDestScan > 0) ? -1 : 1);
  166. return(TRUE);
  167. }
  168. BOOL
  169. TransPos1BPP(
  170. PTPINFO pTPInfo
  171. )
  172. /*++
  173. Routine Description:
  174. This function rotates a 1bpp source to 1bpp destination.
  175. Arguments:
  176. pTPINFO - Pointer to the TPINFO to describe how to do the transpose, the
  177. fields must be set to the following:
  178. pPDev: Pointer to the PDEV
  179. pSrc: Pointer to the soruce bitmap starting point
  180. pDest Pointer to the destination bitmap location which stores the
  181. transpos result starting from the fist destination scan
  182. line in the rotated direction (rotating right will have
  183. 0x01 source bit as first destination scan line)
  184. cbSrcScan: Count to be added to advance to next source bitmap line
  185. cbDestScan: Count to be added to advance to the next destination line
  186. cySrc Total source lines to be processed
  187. DestXStart Specifies where the transposed destination buffer starts,
  188. in bit position. It is computed as DestXStart % 8. 0 means
  189. it starts at the top bit (0x80), 1 means the next bit (0x40)
  190. and so forth.
  191. NOTE:
  192. 1. The ABS(DestDelta) must be large enough to accomodate the
  193. transposed scan line. The size depends on cySrc and DestXStart,
  194. the mimimum size must at least be of the size:
  195. MinSize = (cySrc + (DestXStart % 8) + 7) / 8
  196. 2. The size of the buffer are pointed to by pDest must have at
  197. least ABS(DestDelta) * 8 bytes, if cySrc >= 8, or
  198. ABS(DestDelta) * cySrc if cySrc is less than 8.
  199. 3. Unused last byte destinations are padded with 0
  200. Current transposition assumes the bitmap is rotated to the right, if caller
  201. wants to rotate the bitmap to the left then you must first call the macro
  202. ROTLEFT_1BPP_TPIINFO(pTPInfo)
  203. Return Value:
  204. TRUE if sucessful FALSE if failed
  205. if sucessful the pTPInfo->pSrc will be automatically
  206. 1. Incremented by one (1) if cbDestScan is negative (Rotated left 90 degree)
  207. 2. Decremented by one (1) if cbDestScan is positive (Rotated right 90 degree)
  208. Author:
  209. 22-Dec-1993 Wed 13:46:01 created
  210. 24-Dec-1993 Fri 04:58:24 updated
  211. Fixed the RemainBits problem, we have to shift final data left if the
  212. cySrc is already exhausted and RemainBits is not zero.
  213. Revision History:
  214. --*/
  215. {
  216. LPDWORD pdwTP8x8;
  217. LPBYTE pSrc;
  218. TPINFO TPInfo;
  219. INT RemainBits;
  220. INT cbNextDest;
  221. union {
  222. BYTE b[8];
  223. DWORD dw[2];
  224. } TPData;
  225. TPInfo = *pTPInfo;
  226. TPInfo.DestXStart &= 0x07;
  227. PLOTASSERT(1, "cbDestScan is not big enough (%ld)",
  228. (DWORD)(ABS(TPInfo.cbDestScan)) >=
  229. (DWORD)((TPInfo.cySrc + TPInfo.DestXStart + 7) >> 3),
  230. TPInfo.cbDestScan);
  231. //
  232. // Make sure we have the required transpose translate table. If we don't
  233. // get one built.
  234. //
  235. if (!(pdwTP8x8 = (LPDWORD)pTPInfo->pPDev->pTransPosTable)) {
  236. if (!(pdwTP8x8 = Build8x8TransPosTable())) {
  237. PLOTERR(("TransPos1BPP: Build 8x8 transpos table failed"));
  238. return(FALSE);
  239. }
  240. pTPInfo->pPDev->pTransPosTable = (LPVOID)pdwTP8x8;
  241. }
  242. //
  243. // set up all required parameters, and start TPData with 0s
  244. //
  245. pSrc = TPInfo.pSrc;
  246. RemainBits = (INT)(7 - TPInfo.DestXStart);
  247. cbNextDest = (INT)((TPInfo.cbDestScan > 0) ? 1 : -1);
  248. TPData.dw[0] =
  249. TPData.dw[1] = 0;
  250. while (TPInfo.cySrc--) {
  251. LPDWORD pdwTmp;
  252. LPBYTE pbTmp;
  253. //
  254. // Translate a byte to 8 bytes with each bit corresponding to each byte
  255. // each byte is shifted to the left by 1 before combining with the new
  256. // bit.
  257. //
  258. pdwTmp = pdwTP8x8 + ((UINT)*pSrc << 1);
  259. TPData.dw[0] = (TPData.dw[0] << 1) | *(pdwTmp + 0);
  260. TPData.dw[1] = (TPData.dw[1] << 1) | *(pdwTmp + 1);
  261. pSrc += TPInfo.cbSrcScan;
  262. //
  263. // Check to see if we are done with source scan lines. If this is the
  264. // case we need to possible shift the transposed scan lines by the
  265. // apropriate number based on RemainBits.
  266. //
  267. if (!TPInfo.cySrc) {
  268. //
  269. // We are done, check to see if we need to shift the resultant
  270. // transposed scan lines.
  271. //
  272. if (RemainBits) {
  273. TPData.dw[0] <<= RemainBits;
  274. TPData.dw[1] <<= RemainBits;
  275. RemainBits = 0;
  276. }
  277. }
  278. if (RemainBits--) {
  279. NULL;
  280. } else {
  281. //
  282. // Save the current result to the output destination scan buffer.
  283. // Unwind the processing, to give the compiler a chance to generate
  284. // some fast code, rather that relying on a while loop.
  285. //
  286. *(pbTmp = TPInfo.pDest ) = TPData.b[0];
  287. *(pbTmp += TPInfo.cbDestScan) = TPData.b[1];
  288. *(pbTmp += TPInfo.cbDestScan) = TPData.b[2];
  289. *(pbTmp += TPInfo.cbDestScan) = TPData.b[3];
  290. *(pbTmp += TPInfo.cbDestScan) = TPData.b[4];
  291. *(pbTmp += TPInfo.cbDestScan) = TPData.b[5];
  292. *(pbTmp += TPInfo.cbDestScan) = TPData.b[6];
  293. *(pbTmp + TPInfo.cbDestScan) = TPData.b[7];
  294. //
  295. // Reset RemainBits back to 7, TPData back to 0 and and advance to
  296. // the next destination
  297. //
  298. RemainBits = 7;
  299. TPData.dw[0] =
  300. TPData.dw[1] = 0;
  301. TPInfo.pDest += cbNextDest;
  302. }
  303. }
  304. //
  305. // Since we succeded in transposing the bitmap, the next source byte
  306. // location must be incremented or decremented by one.
  307. //
  308. // The cbNextDest is 1 if the bitmap is rotated to the right 90 degrees, so
  309. // we want to decrement by 1.
  310. //
  311. // The cbNextDest is -1 if the bitmap is rotated to the right 90 degrees, so
  312. // we want to increment by 1.
  313. //
  314. pTPInfo->pSrc -= cbNextDest;
  315. return(TRUE);
  316. }