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.

1509 lines
34 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. faxtiff.c
  5. Abstract:
  6. Functions to compress the bitmap bits using CCITT Group3 2-dimensional coding
  7. and output the resulting data as TIFF-F file.
  8. Environment:
  9. Windows XP fax driver, kernel mode
  10. Revision History:
  11. 01/23/96 -davidx-
  12. Created it.
  13. mm/dd/yy -author-
  14. description
  15. NOTE:
  16. Please refer to faxtiff.h for a description of
  17. the structure of our TIFF output file.
  18. --*/
  19. #include "faxdrv.h"
  20. #include "faxtiff.h"
  21. #include "faxtable.h"
  22. BOOL
  23. WriteData(
  24. PDEVDATA pdev,
  25. PVOID pbuf,
  26. DWORD cbbuf
  27. )
  28. /*++
  29. Routine Description:
  30. Output a buffer of data to the spooler
  31. Arguments:
  32. pdev - Points to our DEVDATA structure
  33. pbuf - Points to data buffer
  34. cbbuf - Number of bytes in the buffer
  35. Return Value:
  36. TRUE if successful, FALSE otherwise.
  37. --*/
  38. {
  39. DWORD cbwritten;
  40. //
  41. // Stop if the document has been cancelled.
  42. //
  43. if (pdev->flags & PDEV_CANCELLED)
  44. return FALSE;
  45. //
  46. // Send output to spooler directly
  47. //
  48. if (! WritePrinter(pdev->hPrinter, pbuf, cbbuf, &cbwritten) || cbbuf != cbwritten) {
  49. Error(("WritePrinter failed\n"));
  50. pdev->flags |= PDEV_CANCELLED;
  51. // Abort preview as well - just in case ...
  52. if (pdev->bPrintPreview)
  53. {
  54. Assert(pdev->pTiffPageHeader);
  55. pdev->pTiffPageHeader->bPreview = FALSE;
  56. pdev->bPrintPreview = FALSE;
  57. }
  58. return FALSE;
  59. }
  60. //
  61. // If print preview is enabled, send a copy to our preview page
  62. //
  63. if (pdev->bPrintPreview)
  64. {
  65. Assert(pdev->pTiffPageHeader);
  66. Assert(pdev->pbTiffPageFP ==
  67. ((LPBYTE) (pdev->pTiffPageHeader + 1)) + pdev->pTiffPageHeader->dwDataSize);
  68. //
  69. // Add the bits in if we don't overflow
  70. //
  71. if (pdev->pTiffPageHeader->dwDataSize + cbbuf >
  72. MAX_TIFF_PAGE_SIZE - sizeof(MAP_TIFF_PAGE_HEADER))
  73. {
  74. Error(("MAX_TIFF_PAGE_SIZE exeeded!\n"));
  75. //
  76. // Cancel print preview for this document
  77. //
  78. pdev->pTiffPageHeader->bPreview = FALSE;
  79. pdev->bPrintPreview = FALSE;
  80. }
  81. else
  82. {
  83. CopyMemory(pdev->pbTiffPageFP, pbuf, cbbuf);
  84. pdev->pbTiffPageFP += cbbuf;
  85. pdev->pTiffPageHeader->dwDataSize += cbbuf;
  86. }
  87. }
  88. pdev->fileOffset += cbbuf;
  89. return TRUE;
  90. }
  91. PDWORD
  92. CalcXposeMatrix(
  93. VOID
  94. )
  95. /*++
  96. Routine Description:
  97. Generate the transpose matrix for rotating landscape bitmaps
  98. Arguments:
  99. NONE
  100. Return Value:
  101. Pointer to the generated transpose matrix
  102. NULL if there is an error
  103. --*/
  104. {
  105. static DWORD templateData[16] = {
  106. /* 0000 */ 0x00000000,
  107. /* 0001 */ 0x00000001,
  108. /* 0010 */ 0x00000100,
  109. /* 0011 */ 0x00000101,
  110. /* 0100 */ 0x00010000,
  111. /* 0101 */ 0x00010001,
  112. /* 0110 */ 0x00010100,
  113. /* 0111 */ 0x00010101,
  114. /* 1000 */ 0x01000000,
  115. /* 1001 */ 0x01000001,
  116. /* 1010 */ 0x01000100,
  117. /* 1011 */ 0x01000101,
  118. /* 1100 */ 0x01010000,
  119. /* 1101 */ 0x01010001,
  120. /* 1110 */ 0x01010100,
  121. /* 1111 */ 0x01010101
  122. };
  123. PDWORD pdwXpose, pTemp;
  124. INT index;
  125. //
  126. // First check if the transpose matrix has been generated already
  127. //
  128. if (pdwXpose = MemAlloc(sizeof(DWORD) * 2 * (1 << BYTEBITS))) {
  129. for (index=0, pTemp=pdwXpose; index < (1 << BYTEBITS); index++, pTemp++) {
  130. pTemp[0] = templateData[index >> 4];
  131. pTemp[1 << BYTEBITS] = templateData[index & 0xf];
  132. }
  133. }
  134. return pdwXpose;
  135. }
  136. BOOL
  137. OutputPageBitmap(
  138. PDEVDATA pdev,
  139. PBYTE pBitmapData
  140. )
  141. /*++
  142. Routine Description:
  143. Output a completed page bitmap to the spooler
  144. Arguments:
  145. pdev - Points to our DEVDATA structure
  146. pBitmapData - Points to bitmap data
  147. Return Value:
  148. TRUE if successful, FALSE if there is an error
  149. --*/
  150. {
  151. LONG bmpWidth, bmpHeight;
  152. BOOL result;
  153. DWORD compressedBytes;
  154. Verbose(("Sending page %d...\n", pdev->pageCount));
  155. Assert(pdev->pCompBits == NULL);
  156. //
  157. // For portrait output, encode the entire bitmap in one shot
  158. // For landscape output, we need to rotate the bitmap here:
  159. // Generate the transpose matrix and allocate a
  160. // temporary buffer large enough to hold 8 scanlines
  161. //
  162. if (IsLandscapeMode(pdev)) {
  163. bmpWidth = pdev->imageSize.cy;
  164. bmpHeight = pdev->imageSize.cx;
  165. } else {
  166. bmpWidth = pdev->imageSize.cx;
  167. bmpHeight = pdev->imageSize.cy;
  168. }
  169. //
  170. // Initialize fax encodier
  171. //
  172. if (! InitFaxEncoder(pdev, bmpWidth, bmpHeight))
  173. return FALSE;
  174. if (! IsLandscapeMode(pdev)) {
  175. LONG dwordCount;
  176. PDWORD pBits;
  177. //
  178. // Invert the entire page bitmap in memory
  179. //
  180. Assert(bmpWidth % DWORDBITS == 0);
  181. dwordCount = (bmpWidth * bmpHeight) / DWORDBITS;
  182. pBits = (PDWORD) pBitmapData;
  183. while (dwordCount--)
  184. *pBits++ ^= 0xffffffff;
  185. //
  186. // Compress the page bitmap
  187. //
  188. result = EncodeFaxData(pdev, pBitmapData, bmpWidth, bmpHeight);
  189. //
  190. // Restore the original page bitmap
  191. //
  192. dwordCount = (bmpWidth * bmpHeight) / DWORDBITS;
  193. pBits = (PDWORD) pBitmapData;
  194. while (dwordCount--)
  195. *pBits++ ^= 0xffffffff;
  196. if (! result) {
  197. FreeCompBitsBuffer(pdev);
  198. return FALSE;
  199. }
  200. } else {
  201. register PDWORD pdwXposeHigh, pdwXposeLow;
  202. register DWORD dwHigh, dwLow;
  203. PBYTE pBuffer, pbCol;
  204. LONG deltaNew;
  205. //
  206. // Calculate the transpose matrix for fast bitmap rotation
  207. //
  208. if (!(pdwXposeHigh = CalcXposeMatrix()) || !(pBuffer = MemAllocZ(bmpWidth))) {
  209. MemFree(pdwXposeHigh);
  210. FreeCompBitsBuffer(pdev);
  211. return FALSE;
  212. }
  213. pdwXposeLow = pdwXposeHigh + (1 << BYTEBITS);
  214. //
  215. // During each iteration thru the following loop, we will process
  216. // one byte column and generate 8 rotated scanlines.
  217. //
  218. Assert(bmpHeight % BYTEBITS == 0);
  219. Assert(bmpWidth % DWORDBITS == 0);
  220. deltaNew = bmpWidth / BYTEBITS;
  221. pbCol = pBitmapData + (bmpHeight / BYTEBITS - 1);
  222. do {
  223. PBYTE pbWrite = pBuffer;
  224. PBYTE pbTemp = pbCol;
  225. LONG loopCount = deltaNew;
  226. while (loopCount--) {
  227. //
  228. // Rotate the next 8 bytes in the current column
  229. // Unroll the loop here in hopes of faster execution
  230. //
  231. dwHigh = pdwXposeHigh[*pbTemp];
  232. dwLow = pdwXposeLow[*pbTemp];
  233. pbTemp += pdev->lineOffset;
  234. dwHigh = (dwHigh << 1) | pdwXposeHigh[*pbTemp];
  235. dwLow = (dwLow << 1) | pdwXposeLow[*pbTemp];
  236. pbTemp += pdev->lineOffset;
  237. dwHigh = (dwHigh << 1) | pdwXposeHigh[*pbTemp];
  238. dwLow = (dwLow << 1) | pdwXposeLow[*pbTemp];
  239. pbTemp += pdev->lineOffset;
  240. dwHigh = (dwHigh << 1) | pdwXposeHigh[*pbTemp];
  241. dwLow = (dwLow << 1) | pdwXposeLow[*pbTemp];
  242. pbTemp += pdev->lineOffset;
  243. dwHigh = (dwHigh << 1) | pdwXposeHigh[*pbTemp];
  244. dwLow = (dwLow << 1) | pdwXposeLow[*pbTemp];
  245. pbTemp += pdev->lineOffset;
  246. dwHigh = (dwHigh << 1) | pdwXposeHigh[*pbTemp];
  247. dwLow = (dwLow << 1) | pdwXposeLow[*pbTemp];
  248. pbTemp += pdev->lineOffset;
  249. dwHigh = (dwHigh << 1) | pdwXposeHigh[*pbTemp];
  250. dwLow = (dwLow << 1) | pdwXposeLow[*pbTemp];
  251. pbTemp += pdev->lineOffset;
  252. dwHigh = (dwHigh << 1) | pdwXposeHigh[*pbTemp];
  253. dwLow = (dwLow << 1) | pdwXposeLow[*pbTemp];
  254. pbTemp += pdev->lineOffset;
  255. //
  256. // Invert black and white pixel polarity
  257. //
  258. dwHigh ^= 0xffffffff;
  259. dwLow ^= 0xffffffff;
  260. //
  261. // Distribute the resulting byte to 8 separate scanlines
  262. //
  263. *pbWrite = (BYTE) dwLow;
  264. pbWrite += deltaNew;
  265. *pbWrite = (BYTE) (dwLow >> BYTEBITS);
  266. pbWrite += deltaNew;
  267. *pbWrite = (BYTE) (dwLow >> BYTEBITS*2);
  268. pbWrite += deltaNew;
  269. *pbWrite = (BYTE) (dwLow >> BYTEBITS*3);
  270. pbWrite += deltaNew;
  271. *pbWrite = (BYTE) dwHigh;
  272. pbWrite += deltaNew;
  273. *pbWrite = (BYTE) (dwHigh >> BYTEBITS);
  274. pbWrite += deltaNew;
  275. *pbWrite = (BYTE) (dwHigh >> BYTEBITS*2);
  276. pbWrite += deltaNew;
  277. *pbWrite = (BYTE) (dwHigh >> BYTEBITS*3);
  278. pbWrite -= (deltaNew * BYTEBITS - deltaNew - 1);
  279. }
  280. //
  281. // Encode the next band of scanlines
  282. //
  283. if (! EncodeFaxData(pdev, pBuffer, bmpWidth, BYTEBITS)) {
  284. MemFree(pdwXposeHigh);
  285. MemFree(pBuffer);
  286. FreeCompBitsBuffer(pdev);
  287. return FALSE;
  288. }
  289. } while (pbCol-- != pBitmapData);
  290. MemFree(pdwXposeHigh);
  291. MemFree(pBuffer);
  292. }
  293. //
  294. // Output EOB (two EOLs) after the last scanline
  295. // and make sure the compressed data is WORD aligned
  296. //
  297. OutputBits(pdev, EOL_LENGTH, EOL_CODE);
  298. OutputBits(pdev, EOL_LENGTH, EOL_CODE);
  299. FlushBits(pdev);
  300. if ((compressedBytes = (DWORD)(pdev->pCompBufPtr - pdev->pCompBits)) & 1) {
  301. *pdev->pCompBufPtr++ = 0;
  302. compressedBytes++;
  303. }
  304. //
  305. // Output the IFD for the previous page and generate the IFD for the current page
  306. // Output the compressed bitmap data
  307. //
  308. result = WriteTiffIFD(pdev, bmpWidth, bmpHeight, compressedBytes) &&
  309. WriteTiffBits(pdev, pdev->pCompBits, compressedBytes);
  310. FreeCompBitsBuffer(pdev);
  311. return result;
  312. }
  313. INT
  314. FindWhiteRun(
  315. PBYTE pbuf,
  316. INT startBit,
  317. INT stopBit
  318. )
  319. /*++
  320. Routine Description:
  321. Find the next span of white pixels on the specified line
  322. Arguments:
  323. pbuf - Points to uncompressed pixel data for the current line
  324. startBit - Starting bit index
  325. stopBit - Last bit index
  326. Return Value:
  327. Length of the next run of white pixels
  328. --*/
  329. {
  330. static const BYTE WhiteRuns[256] = {
  331. 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
  332. 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
  333. 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  334. 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  335. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  336. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  337. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  338. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  339. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  340. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  341. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  342. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  343. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  344. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  345. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  346. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  347. };
  348. INT run, bits, n;
  349. pbuf += (startBit >> 3);
  350. if ((bits = stopBit-startBit) <= 0)
  351. return 0;
  352. //
  353. // Take care of the case where starting bit index is not a multiple of 8
  354. //
  355. if (n = (startBit & 7)) {
  356. run = WhiteRuns[(*pbuf << n) & 0xff];
  357. if (run > BYTEBITS-n)
  358. run = BYTEBITS-n;
  359. if (n+run < BYTEBITS)
  360. return run;
  361. bits -= run;
  362. pbuf++;
  363. } else
  364. run = 0;
  365. //
  366. // Look for consecutive DWORD value = 0
  367. //
  368. if (bits >= DWORDBITS * 2) {
  369. PDWORD pdw;
  370. //
  371. // Align to a DWORD boundary first
  372. //
  373. while ((ULONG_PTR) pbuf & 3) {
  374. if (*pbuf != 0)
  375. return run + WhiteRuns[*pbuf];
  376. run += BYTEBITS;
  377. bits -= BYTEBITS;
  378. pbuf++;
  379. }
  380. pdw = (PDWORD) pbuf;
  381. while (bits >= DWORDBITS && *pdw == 0) {
  382. pdw++;
  383. run += DWORDBITS;
  384. bits -= DWORDBITS;
  385. }
  386. pbuf = (PBYTE) pdw;
  387. }
  388. //
  389. // Look for consecutive BYTE value = 0
  390. //
  391. while (bits >= BYTEBITS) {
  392. if (*pbuf != 0)
  393. return run + WhiteRuns[*pbuf];
  394. pbuf++;
  395. run += BYTEBITS;
  396. bits -= BYTEBITS;
  397. }
  398. //
  399. // Count the number of white pixels in the last byte
  400. //
  401. if (bits > 0)
  402. run += WhiteRuns[*pbuf];
  403. return run;
  404. }
  405. INT
  406. FindBlackRun(
  407. PBYTE pbuf,
  408. INT startBit,
  409. INT stopBit
  410. )
  411. /*++
  412. Routine Description:
  413. Find the next span of black pixels on the specified line
  414. Arguments:
  415. pbuf - Points to uncompressed pixel data for the current line
  416. startBit - Starting bit index
  417. stopBit - Last bit index
  418. Return Value:
  419. Length of the next run of black pixels
  420. --*/
  421. {
  422. static const BYTE BlackRuns[256] = {
  423. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  424. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  425. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  426. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  427. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  428. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  429. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  430. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  431. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  432. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  433. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  434. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
  435. 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  436. 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  437. 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
  438. 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8
  439. };
  440. INT run, bits, n;
  441. pbuf += (startBit >> 3);
  442. if ((bits = stopBit-startBit) <= 0)
  443. return 0;
  444. //
  445. // Take care of the case where starting bit index is not a multiple of 8
  446. //
  447. if (n = (startBit & 7)) {
  448. run = BlackRuns[(*pbuf << n) & 0xff];
  449. if (run > BYTEBITS-n)
  450. run = BYTEBITS-n;
  451. if (n+run < BYTEBITS)
  452. return run;
  453. bits -= run;
  454. pbuf++;
  455. } else
  456. run = 0;
  457. //
  458. // Look for consecutive DWORD value = 0xffffffff
  459. //
  460. if (bits >= DWORDBITS * 2) {
  461. PDWORD pdw;
  462. //
  463. // Align to a DWORD boundary first
  464. //
  465. while ((ULONG_PTR) pbuf & 3) {
  466. if (*pbuf != 0xff)
  467. return run + BlackRuns[*pbuf];
  468. run += BYTEBITS;
  469. bits -= BYTEBITS;
  470. pbuf++;
  471. }
  472. pdw = (PDWORD) pbuf;
  473. while (bits >= DWORDBITS && *pdw == 0xffffffff) {
  474. pdw++;
  475. run += DWORDBITS;
  476. bits -= DWORDBITS;
  477. }
  478. pbuf = (PBYTE) pdw;
  479. }
  480. //
  481. // Look for consecutive BYTE value = 0xff
  482. //
  483. while (bits >= BYTEBITS) {
  484. if (*pbuf != 0xff)
  485. return run + BlackRuns[*pbuf];
  486. pbuf++;
  487. run += BYTEBITS;
  488. bits -= BYTEBITS;
  489. }
  490. //
  491. // Count the number of white pixels in the last byte
  492. //
  493. if (bits > 0)
  494. run += BlackRuns[*pbuf];
  495. return run;
  496. }
  497. VOID
  498. OutputRun(
  499. PDEVDATA pdev,
  500. INT run,
  501. PCODETABLE pCodeTable
  502. )
  503. /*++
  504. Routine Description:
  505. Output a single run (black or white) using the specified code table
  506. Arguments:
  507. pdev - Points to our DEVDATA structure
  508. run - Specifies the length of the run
  509. pCodeTable - Specifies the code table to use
  510. Return Value:
  511. NONE
  512. --*/
  513. {
  514. PCODETABLE pTableEntry;
  515. //
  516. // Use make-up code word for 2560 for any runs of at least 2624 pixels
  517. // This is currently not necessary for us since our scanlines always
  518. // have 1728 pixels.
  519. //
  520. while (run >= 2624) {
  521. pTableEntry = pCodeTable + (63 + (2560 >> 6));
  522. OutputBits(pdev, pTableEntry->length, pTableEntry->code);
  523. run -= 2560;
  524. }
  525. //
  526. // Use appropriate make-up code word if the run is longer than 63 pixels
  527. //
  528. if (run >= 64) {
  529. pTableEntry = pCodeTable + (63 + (run >> 6));
  530. OutputBits(pdev, pTableEntry->length, pTableEntry->code);
  531. run &= 0x3f;
  532. }
  533. //
  534. // Output terminating code word
  535. //
  536. OutputBits(pdev, pCodeTable[run].length, pCodeTable[run].code);
  537. }
  538. #ifdef USE1D
  539. VOID
  540. OutputEOL(
  541. PDEVDATA pdev
  542. )
  543. /*++
  544. Routine Description:
  545. Output EOL code at the beginning of each scanline
  546. Arguments:
  547. pdev - Points to our DEVDATA structure
  548. Return Value:
  549. NONE
  550. --*/
  551. {
  552. DWORD length, code;
  553. //
  554. // EOL code word always ends on a byte boundary
  555. //
  556. code = EOL_CODE;
  557. length = EOL_LENGTH + ((pdev->bitcnt - EOL_LENGTH) & 7);
  558. OutputBits(pdev, length, code);
  559. }
  560. BOOL
  561. EncodeFaxData(
  562. PDEVDATA pdev,
  563. PBYTE plinebuf,
  564. INT lineWidth,
  565. INT lineCount
  566. )
  567. /*++
  568. Routine Description:
  569. Compress the specified number of scanlines
  570. Arguments:
  571. pdev - Points to our DEVDATA structure
  572. plinebuf - Points to scanline data to be compressed
  573. lineWidth - Scanline width in pixels
  574. lineCount - Number of scanlines
  575. Return Value:
  576. TRUE if successful, FALSE if there is an error
  577. --*/
  578. {
  579. INT delta = lineWidth / BYTEBITS;
  580. INT bitIndex, run;
  581. while (lineCount--) {
  582. //
  583. // Make sure the compressed bitmap buffer doesn't overflow
  584. //
  585. if ((pdev->pCompBufPtr >= pdev->pCompBufMark) && !GrowCompBitsBuffer(pdev, delta))
  586. return FALSE;
  587. //
  588. // Output byte-aligned EOL code
  589. //
  590. OutputEOL(pdev);
  591. //
  592. // Use 1-dimensional encoding scheme
  593. //
  594. bitIndex = 0;
  595. while (TRUE) {
  596. //
  597. // Code white run
  598. //
  599. run = FindWhiteRun(plinebuf, bitIndex, lineWidth);
  600. OutputRun(pdev, run, WhiteRunCodes);
  601. if ((bitIndex += run) >= lineWidth)
  602. break;
  603. //
  604. // Code black run
  605. //
  606. run = FindBlackRun(plinebuf, bitIndex, lineWidth);
  607. OutputRun(pdev, run, BlackRunCodes);
  608. if ((bitIndex += run) >= lineWidth)
  609. break;
  610. }
  611. //
  612. // Move on to the next scanline
  613. //
  614. plinebuf += delta;
  615. }
  616. return TRUE;
  617. }
  618. #else //!USE1D
  619. BOOL
  620. EncodeFaxData(
  621. PDEVDATA pdev,
  622. PBYTE plinebuf,
  623. INT lineWidth,
  624. INT lineCount
  625. )
  626. /*++
  627. Routine Description:
  628. Compress the specified number of scanlines
  629. Arguments:
  630. pdev - Points to our DEVDATA structure
  631. plinebuf - Points to scanline data to be compressed
  632. lineWidth - Scanline width in pixels
  633. lineCount - Number of scanlines
  634. Return Value:
  635. TRUE if successful, FALSE if there is an error
  636. --*/
  637. {
  638. INT delta = lineWidth / BYTEBITS;
  639. INT a0, a1, a2, b1, b2, distance;
  640. PBYTE prefline = pdev->prefline;
  641. Assert(lineWidth % BYTEBITS == 0);
  642. while (lineCount--) {
  643. //
  644. // Make sure the compressed bitmap buffer doesn't overflow
  645. //
  646. if ((pdev->pCompBufPtr >= pdev->pCompBufMark) && !GrowCompBitsBuffer(pdev, delta))
  647. return FALSE;
  648. //
  649. // Use 2-dimensional encoding scheme
  650. //
  651. a0 = 0;
  652. a1 = GetBit(plinebuf, 0) ? 0 : NextChangingElement(plinebuf, 0, lineWidth, 0);
  653. b1 = GetBit(prefline, 0) ? 0 : NextChangingElement(prefline, 0, lineWidth, 0);
  654. while (TRUE) {
  655. b2 = (b1 >= lineWidth) ? lineWidth :
  656. NextChangingElement(prefline, b1, lineWidth, GetBit(prefline, b1));
  657. if (b2 < a1) {
  658. //
  659. // Pass mode
  660. //
  661. OutputBits(pdev, PASSCODE_LENGTH, PASSCODE);
  662. a0 = b2;
  663. } else if ((distance = a1 - b1) <= 3 && distance >= -3) {
  664. //
  665. // Vertical mode
  666. //
  667. OutputBits(pdev, VertCodes[distance+3].length, VertCodes[distance+3].code);
  668. a0 = a1;
  669. } else {
  670. //
  671. // Horizontal mode
  672. //
  673. a2 = (a1 >= lineWidth) ? lineWidth :
  674. NextChangingElement(plinebuf, a1, lineWidth, GetBit(plinebuf, a1));
  675. OutputBits(pdev, HORZCODE_LENGTH, HORZCODE);
  676. if (a1 != 0 && GetBit(plinebuf, a0)) {
  677. OutputRun(pdev, a1-a0, BlackRunCodes);
  678. OutputRun(pdev, a2-a1, WhiteRunCodes);
  679. } else {
  680. OutputRun(pdev, a1-a0, WhiteRunCodes);
  681. OutputRun(pdev, a2-a1, BlackRunCodes);
  682. }
  683. a0 = a2;
  684. }
  685. if (a0 >= lineWidth)
  686. break;
  687. a1 = NextChangingElement(plinebuf, a0, lineWidth, GetBit(plinebuf, a0));
  688. b1 = NextChangingElement(prefline, a0, lineWidth, !GetBit(plinebuf, a0));
  689. b1 = NextChangingElement(prefline, b1, lineWidth, GetBit(plinebuf, a0));
  690. }
  691. //
  692. // Move on to the next scanline
  693. //
  694. prefline = plinebuf;
  695. plinebuf += delta;
  696. }
  697. //
  698. // Remember the last line as a reference
  699. //
  700. CopyMemory(pdev->prefline, prefline, delta);
  701. return TRUE;
  702. }
  703. #endif //!USE1D
  704. //
  705. // IFD entries we generate for each page
  706. //
  707. WORD FaxIFDTags[NUM_IFD_ENTRIES] = {
  708. TIFFTAG_NEWSUBFILETYPE,
  709. TIFFTAG_IMAGEWIDTH,
  710. TIFFTAG_IMAGEHEIGHT,
  711. TIFFTAG_BITSPERSAMPLE,
  712. TIFFTAG_COMPRESSION,
  713. TIFFTAG_PHOTOMETRIC,
  714. TIFFTAG_FILLORDER,
  715. TIFFTAG_STRIPOFFSETS,
  716. TIFFTAG_SAMPLESPERPIXEL,
  717. TIFFTAG_ROWSPERSTRIP,
  718. TIFFTAG_STRIPBYTECOUNTS,
  719. TIFFTAG_XRESOLUTION,
  720. TIFFTAG_YRESOLUTION,
  721. #ifdef USE1D
  722. TIFFTAG_G3OPTIONS,
  723. #else
  724. TIFFTAG_G4OPTIONS,
  725. #endif
  726. TIFFTAG_RESUNIT,
  727. TIFFTAG_PAGENUMBER,
  728. TIFFTAG_SOFTWARE,
  729. TIFFTAG_CLEANFAXDATA,
  730. };
  731. static FAXIFD FaxIFDTemplate = {
  732. 0,
  733. NUM_IFD_ENTRIES,
  734. {
  735. { TIFFTAG_NEWSUBFILETYPE, TIFFTYPE_LONG, 1, SUBFILETYPE_PAGE },
  736. { TIFFTAG_IMAGEWIDTH, TIFFTYPE_LONG, 1, 0 },
  737. { TIFFTAG_IMAGEHEIGHT, TIFFTYPE_LONG, 1, 0 },
  738. { TIFFTAG_BITSPERSAMPLE, TIFFTYPE_SHORT, 1, 1 },
  739. #ifdef USE1D
  740. { TIFFTAG_COMPRESSION, TIFFTYPE_SHORT, 1, COMPRESSION_G3FAX },
  741. #else
  742. { TIFFTAG_COMPRESSION, TIFFTYPE_SHORT, 1, COMPRESSION_G4FAX },
  743. #endif
  744. { TIFFTAG_PHOTOMETRIC, TIFFTYPE_SHORT, 1, PHOTOMETRIC_WHITEIS0 },
  745. #ifdef USELSB
  746. { TIFFTAG_FILLORDER, TIFFTYPE_SHORT, 1, FILLORDER_LSB },
  747. #else
  748. { TIFFTAG_FILLORDER, TIFFTYPE_SHORT, 1, FILLORDER_MSB },
  749. #endif
  750. { TIFFTAG_STRIPOFFSETS, TIFFTYPE_LONG, 1, 0 },
  751. { TIFFTAG_SAMPLESPERPIXEL, TIFFTYPE_SHORT, 1, 1 },
  752. { TIFFTAG_ROWSPERSTRIP, TIFFTYPE_LONG, 1, 0 },
  753. { TIFFTAG_STRIPBYTECOUNTS, TIFFTYPE_LONG, 1, 0 },
  754. { TIFFTAG_XRESOLUTION, TIFFTYPE_RATIONAL, 1, 0 },
  755. { TIFFTAG_YRESOLUTION, TIFFTYPE_RATIONAL, 1, 0 },
  756. #ifdef USE1D
  757. { TIFFTAG_G3OPTIONS, TIFFTYPE_LONG, 1, G3_ALIGNEOL },
  758. #else
  759. { TIFFTAG_G4OPTIONS, TIFFTYPE_LONG, 1, 0 },
  760. #endif
  761. { TIFFTAG_RESUNIT, TIFFTYPE_SHORT, 1, RESUNIT_INCH },
  762. { TIFFTAG_PAGENUMBER, TIFFTYPE_SHORT, 2, 0 },
  763. { TIFFTAG_SOFTWARE, TIFFTYPE_ASCII, sizeof(FAX_DRIVER_NAME_A)+1, 0 },
  764. { TIFFTAG_CLEANFAXDATA, TIFFTYPE_SHORT, 1, 0 },
  765. },
  766. 0,
  767. DRIVER_SIGNATURE,
  768. TIFFF_RES_X,
  769. 1,
  770. TIFFF_RES_Y,
  771. 1,
  772. FAX_DRIVER_NAME_A
  773. };
  774. BOOL
  775. OutputDocTrailer(
  776. PDEVDATA pdev
  777. )
  778. /*++
  779. Routine Description:
  780. Output document trailer information to the spooler
  781. Arguments:
  782. pdev - Points to our DEVDATA structure
  783. Return Value:
  784. TRUE if successful, FALSE if there is an error
  785. --*/
  786. {
  787. PFAXIFD pFaxIFD = pdev->pFaxIFD;
  788. if (pFaxIFD == NULL || pdev->pageCount == 0)
  789. return TRUE;
  790. //
  791. // Output the IFD for the last page of the document
  792. //
  793. pFaxIFD->nextIFDOffset = pFaxIFD->filler = 0;
  794. return WriteData(pdev, pFaxIFD, sizeof(FAXIFD));
  795. }
  796. BOOL
  797. WriteTiffIFD(
  798. PDEVDATA pdev,
  799. LONG bmpWidth,
  800. LONG bmpHeight,
  801. DWORD compressedBytes
  802. )
  803. /*++
  804. Routine Description:
  805. Output the IFD for the previous page and generate the IFD for the current page
  806. Arguments:
  807. pdev - Points to our DEVDATA structure
  808. bmpWidth, bmpHeight - Width and height of the bitmap image
  809. compressedBytes - Size of compressed bitmap data
  810. Return Value:
  811. TRUE if successful, FALSE otherwise
  812. NOTE:
  813. Please refer to faxtiff.h for a description of
  814. the structure of our TIFF output file.
  815. --*/
  816. {
  817. PFAXIFD pFaxIFD = pdev->pFaxIFD;
  818. ULONG_PTR offset;
  819. BOOL result = TRUE;
  820. //
  821. // Create the IFD data structure if necessary
  822. //
  823. if (pFaxIFD == NULL) {
  824. if (! (pFaxIFD = MemAlloc(sizeof(FAXIFD))))
  825. return FALSE;
  826. pdev->pFaxIFD = pFaxIFD;
  827. memcpy(pFaxIFD, &FaxIFDTemplate, sizeof(FAXIFD));
  828. #if DBG
  829. for (offset=0; offset < NUM_IFD_ENTRIES; offset++) {
  830. Assert(pFaxIFD->ifd[offset].tag == FaxIFDTags[offset]);
  831. }
  832. #endif
  833. }
  834. if (pdev->pageCount <= 1) {
  835. //
  836. // If this is the very first page, there is no previous IFD.
  837. // Output the TIFF file header instead.
  838. //
  839. TIFFFILEHEADER *pTiffFileHeader;
  840. pdev->fileOffset = 0;
  841. if (pTiffFileHeader = MemAlloc(sizeof(TIFFFILEHEADER))) {
  842. pTiffFileHeader->magic1 = TIFF_MAGIC1;
  843. pTiffFileHeader->magic2 = TIFF_MAGIC2;
  844. pTiffFileHeader->signature = DRIVER_SIGNATURE;
  845. pTiffFileHeader->firstIFD = sizeof(TIFFFILEHEADER) +
  846. compressedBytes +
  847. offsetof(FAXIFD, wIFDEntries);
  848. result = WriteData(pdev, pTiffFileHeader, sizeof(TIFFFILEHEADER));
  849. MemFree(pTiffFileHeader);
  850. } else {
  851. Error(("Memory allocation failed\n"));
  852. result = FALSE;
  853. }
  854. } else {
  855. //
  856. // Not the first page of the document
  857. // Output the IFD for the previous page
  858. //
  859. pFaxIFD->nextIFDOffset = pdev->fileOffset + compressedBytes + sizeof(FAXIFD) +
  860. offsetof(FAXIFD, wIFDEntries);
  861. result = WriteData(pdev, pFaxIFD, sizeof(FAXIFD));
  862. }
  863. //
  864. // Generate the IFD for the current page
  865. //
  866. offset = pdev->fileOffset;
  867. pFaxIFD->ifd[IFD_PAGENUMBER].value = MAKELONG(pdev->pageCount-1, 0);
  868. pFaxIFD->ifd[IFD_IMAGEWIDTH].value = bmpWidth;
  869. pFaxIFD->ifd[IFD_IMAGEHEIGHT].value = bmpHeight;
  870. pFaxIFD->ifd[IFD_ROWSPERSTRIP].value = bmpHeight;
  871. pFaxIFD->ifd[IFD_STRIPBYTECOUNTS].value = compressedBytes;
  872. pFaxIFD->ifd[IFD_STRIPOFFSETS].value = (ULONG)offset;
  873. offset += compressedBytes;
  874. pFaxIFD->ifd[IFD_XRESOLUTION].value = (ULONG)offset + offsetof(FAXIFD, xresNum);
  875. pFaxIFD->ifd[IFD_YRESOLUTION].value = (ULONG)offset + offsetof(FAXIFD, yresNum);
  876. pFaxIFD->ifd[IFD_SOFTWARE].value = (ULONG)offset + offsetof(FAXIFD, software);
  877. pFaxIFD->yresNum = (pdev->dm.dmPublic.dmYResolution == FAXRES_VERTDRAFT) ?
  878. TIFFF_RES_Y_DRAFT :
  879. TIFFF_RES_Y;
  880. return result;
  881. }
  882. BOOL
  883. WriteTiffBits(
  884. PDEVDATA pdev,
  885. PBYTE pCompBits,
  886. DWORD compressedBytes
  887. )
  888. /*++
  889. Routine Description:
  890. Output the compressed bitmap data to the spooler
  891. Arguments:
  892. pdev - Points to our DEVDATA structure
  893. pCompBits - Points to a buffer containing compressed bitmap data
  894. compressedBytes - Size of compressed bitmap data
  895. Return Value:
  896. TRUE if successful, FALSE if there is an error
  897. --*/
  898. #define OUTPUT_BUFFER_SIZE 4096
  899. {
  900. PBYTE pBuffer;
  901. DWORD bytesToWrite;
  902. #ifndef USERMODE_DRIVER
  903. //
  904. // Since we allocated the compressed bitmap data buffer from
  905. // the user mode memory space, we couldn't passed it directly
  906. // to EngWritePrinter.
  907. //
  908. // Here we allocate a temporary buffer from kernel mode memory
  909. // space and output the compressed data one buffer at a time.
  910. //
  911. if (! (pBuffer = MemAlloc(OUTPUT_BUFFER_SIZE))) {
  912. Error(("Memory allocation failed\n"));
  913. return FALSE;
  914. }
  915. while (compressedBytes > 0) {
  916. bytesToWrite = min(compressedBytes, OUTPUT_BUFFER_SIZE);
  917. CopyMemory(pBuffer, pCompBits, bytesToWrite);
  918. if (! WriteData(pdev, pBuffer, bytesToWrite)) {
  919. MemFree(pBuffer);
  920. return FALSE;
  921. }
  922. pCompBits += bytesToWrite;
  923. compressedBytes -= bytesToWrite;
  924. }
  925. MemFree(pBuffer);
  926. return TRUE;
  927. #else
  928. //
  929. // just dump the data in OUTPUT_BUFFER_SIZE increments
  930. //
  931. pBuffer = pCompBits;
  932. while (compressedBytes > 0) {
  933. bytesToWrite = min(compressedBytes, OUTPUT_BUFFER_SIZE);
  934. if (! WriteData(pdev, pBuffer, bytesToWrite) ) {
  935. return FALSE;
  936. }
  937. pBuffer += bytesToWrite;
  938. compressedBytes -= bytesToWrite;
  939. }
  940. return TRUE;
  941. #endif
  942. }
  943. BOOL
  944. GrowCompBitsBuffer(
  945. PDEVDATA pdev,
  946. LONG scanlineSize
  947. )
  948. /*++
  949. Routine Description:
  950. Enlarge the buffer for holding the compressed bitmap data
  951. Arguments:
  952. pdev - Points to our DEVDATA structure
  953. scanlineSize - Number of uncompressed bytes per scanline
  954. Return Value:
  955. TRUE if successful, FALSE if memory allocation fails
  956. --*/
  957. {
  958. DWORD oldBufferSize;
  959. PBYTE pNewBuffer;
  960. //
  961. // Allocate a new buffer which is one increment larger than existing one
  962. //
  963. oldBufferSize = pdev->pCompBits ? pdev->compBufSize : 0;
  964. pdev->compBufSize = oldBufferSize + pdev->compBufInc;
  965. if (! (pNewBuffer = MemAlloc(pdev->compBufSize))) {
  966. Error(("MemAlloc failed\n"));
  967. FreeCompBitsBuffer(pdev);
  968. return FALSE;
  969. }
  970. if (pdev->pCompBits) {
  971. //
  972. // Growing an existing buffer
  973. //
  974. Warning(("Growing compressed bitmap buffer: %d -> %d\n", oldBufferSize, pdev->compBufSize));
  975. memcpy(pNewBuffer, pdev->pCompBits, oldBufferSize);
  976. pdev->pCompBufPtr = pNewBuffer + (pdev->pCompBufPtr - pdev->pCompBits);
  977. MemFree(pdev->pCompBits);
  978. pdev->pCompBits = pNewBuffer;
  979. } else {
  980. //
  981. // First time allocation
  982. //
  983. pdev->pCompBufPtr = pdev->pCompBits = pNewBuffer;
  984. }
  985. //
  986. // Set a high-water mark to about 4 scanlines before the end of the buffer
  987. //
  988. pdev->pCompBufMark = pdev->pCompBits + (pdev->compBufSize - 4*scanlineSize);
  989. return TRUE;
  990. }
  991. VOID
  992. FreeCompBitsBuffer(
  993. PDEVDATA pdev
  994. )
  995. /*++
  996. Routine Description:
  997. Free the buffer for holding the compressed bitmap data
  998. Arguments:
  999. pdev - Points to our DEVDATA structure
  1000. Return Value:
  1001. NONE
  1002. --*/
  1003. {
  1004. if (pdev->pCompBits) {
  1005. MemFree(pdev->prefline);
  1006. MemFree(pdev->pCompBits);
  1007. pdev->pCompBits = pdev->pCompBufPtr = NULL;
  1008. pdev->compBufSize = 0;
  1009. }
  1010. }
  1011. BOOL
  1012. InitFaxEncoder(
  1013. PDEVDATA pdev,
  1014. LONG bmpWidth,
  1015. LONG bmpHeight
  1016. )
  1017. /*++
  1018. Routine Description:
  1019. Initialize the fax encoder
  1020. Arguments:
  1021. pdev - Points to our DEVDATA structure
  1022. bmpWidth, bmpHeight - Width and height of the bitmap
  1023. Return Value:
  1024. TRUE if successful, FALSE if there is an error
  1025. --*/
  1026. {
  1027. //
  1028. // Calculate the increment in which to enlarge the compressed bits buffer:
  1029. // about 1/4 of the uncompressed bitmap buffer
  1030. //
  1031. bmpWidth /= BYTEBITS;
  1032. pdev->compBufInc = bmpWidth * bmpHeight / 4;
  1033. //
  1034. // Allocate the initial buffer
  1035. //
  1036. if (! (pdev->prefline = MemAllocZ(bmpWidth)) ||
  1037. ! GrowCompBitsBuffer(pdev, bmpWidth))
  1038. {
  1039. MemFree(pdev->prefline);
  1040. return FALSE;
  1041. }
  1042. //
  1043. // Perform other initialization of fax encoder
  1044. //
  1045. pdev->bitdata = 0;
  1046. pdev->bitcnt = DWORDBITS;
  1047. return TRUE;
  1048. }