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.

193 lines
4.6 KiB

  1. /*==============================================================================
  2. This module provides DCX rendering support for viewing faxes.
  3. 19-Jan-94 RajeevD Integrated into IFAX viewer.
  4. ==============================================================================*/
  5. #ifdef VIEWDCX
  6. #include <memory.h>
  7. #include "viewrend.hpp"
  8. #include "dcxcodec.h"
  9. //==============================================================================
  10. DCXVIEW::DCXVIEW (DWORD nType)
  11. {
  12. nTypeOut = nType;
  13. lpCodec = NULL;
  14. bufIn.wLengthBuf = 8000;
  15. bufIn.lpbBegBuf = (LPBYTE) GlobalAllocPtr (0, bufIn.wLengthBuf);
  16. }
  17. //==============================================================================
  18. DCXVIEW::~DCXVIEW ()
  19. {
  20. if (lpCodec)
  21. GlobalFreePtr (lpCodec);
  22. if (bufIn.lpbBegBuf)
  23. GlobalFreePtr (bufIn.lpbBegBuf);
  24. }
  25. //==============================================================================
  26. BOOL DCXVIEW::Init (LPVOID lpFilePath, LPVIEWINFO lpvi, LPWORD lpwBandSize)
  27. {
  28. DWORD dwOffset;
  29. PCX_HDR pcx;
  30. UINT cbCodec;
  31. if (!this || !bufIn.lpbBegBuf)
  32. return_error (("VIEWREND could not allocate context!\r\n"));
  33. if (!Open (lpFilePath, 0))
  34. return_error (("VIEWREND could not open spool file!\r\n"));
  35. if (!Seek (sizeof(DWORD), SEEK_BEG))
  36. return_error (("VIEWREND could not seek to first page offset!\r\n"));
  37. if (!Read (&dwOffset, sizeof(dwOffset)))
  38. return_error (("VIEWREND could not read first page offset\r\n"));
  39. if (!Seek (dwOffset, SEEK_BEG))
  40. return_error (("VIEWREND could not seek to first page!\r\n"));
  41. if (!Read (&pcx, sizeof(pcx)))
  42. return_error (("VIEWREND could read header of first page!\r\n"));
  43. // Fill VIEWINFO.
  44. lpvi->cPage = 0;
  45. while (SetPage(lpvi->cPage))
  46. lpvi->cPage++;
  47. switch (pcx.xRes)
  48. {
  49. case 640:
  50. // Assume square aspect ratio
  51. lpvi->xRes = 200;
  52. lpvi->yRes = 200;
  53. break;
  54. default:
  55. lpvi->xRes = pcx.xRes;
  56. lpvi->yRes = pcx.yRes;
  57. break;
  58. }
  59. lpvi->yMax = pcx.yMax - pcx.yMin;
  60. // Set up codec.
  61. fcp.nTypeIn = DCX_DATA;
  62. fcp.nTypeOut = HRAW_DATA;
  63. fcp.cbLine = (pcx.xMax - pcx.xMin + 1) / 8;
  64. // Query codec.
  65. cbCodec = DcxCodecInit (NULL, &fcp);
  66. if (!cbCodec)
  67. return_error (("VIEWREND could not init codec!\r\n"));
  68. // Initialize codec.
  69. lpCodec = GlobalAllocPtr (0, cbCodec);
  70. if (!lpCodec)
  71. return_error (("VIEWREND could not allocate codec!\r\n"));
  72. cbBand = *lpwBandSize;
  73. return SetPage (0);
  74. }
  75. //==============================================================================
  76. BOOL DCXVIEW::SetPage (UINT iPage)
  77. {
  78. DWORD dwOffset[2];
  79. DEBUGCHK (iPage < 1024);
  80. // Get offset of current and next page.
  81. Seek (sizeof(DWORD) * (iPage + 1), SEEK_BEG);
  82. Read (dwOffset, sizeof(dwOffset));
  83. if (!dwOffset[0])
  84. return FALSE;
  85. if (!dwOffset[1])
  86. {
  87. Seek (0, SEEK_END);
  88. dwOffset[1] = Tell();
  89. }
  90. // Seek to page.
  91. dwOffset[0] += sizeof(PCX_HDR);
  92. if (!Seek (dwOffset[0], SEEK_BEG))
  93. return_error (("VIEWREND could not seek to page %d!",iPage));
  94. cbPage = dwOffset[1] - dwOffset[0];
  95. // Initialize codec.
  96. DcxCodecInit (lpCodec, &fcp);
  97. bufIn.Reset();
  98. fEndPage = FALSE;
  99. return TRUE;
  100. }
  101. //==============================================================================
  102. BOOL DCXVIEW::GetBand (LPBITMAP lpbmBand)
  103. {
  104. FC_STATUS fcs;
  105. BUFFER bufOut;
  106. DEBUGCHK (lpbmBand && lpbmBand->bmBits);
  107. // Fill descriptor.
  108. lpbmBand->bmType = 0;
  109. lpbmBand->bmWidth = 8 * fcp.cbLine;
  110. lpbmBand->bmWidthBytes = fcp.cbLine;
  111. lpbmBand->bmPlanes = 1;
  112. lpbmBand->bmBitsPixel = 1;
  113. // Trap end of page.
  114. if (fEndPage)
  115. {
  116. lpbmBand->bmHeight = 0;
  117. return TRUE;
  118. }
  119. // Set up output buffer.
  120. bufOut.lpbBegBuf = (LPBYTE) lpbmBand->bmBits;
  121. bufOut.wLengthBuf = cbBand;
  122. bufOut.Reset();
  123. bufOut.dwMetaData = LRAW_DATA;
  124. do
  125. {
  126. // Fetch input buffer?
  127. if (!bufIn.wLengthData)
  128. {
  129. // Reset buffer.
  130. bufIn.lpbBegData = bufIn.lpbBegBuf;
  131. if ((DWORD) bufIn.wLengthBuf < cbPage)
  132. bufIn.wLengthData = bufIn.wLengthBuf;
  133. else
  134. bufIn.wLengthData = (WORD) cbPage;
  135. // Read DCX data.
  136. if (!Read (bufIn.lpbBegData, bufIn.wLengthData))
  137. return_error (("VIEWREND could not read DCX buffer!\r\n"));
  138. cbPage -= bufIn.wLengthData;
  139. }
  140. // Decode the DCX data.
  141. fcs = DcxCodecConvert (lpCodec, &bufIn, &bufOut);
  142. // Check for end of page.
  143. if (!cbPage)
  144. {
  145. fEndPage = TRUE;
  146. break;
  147. }
  148. }
  149. while (fcs == FC_INPUT_EMPTY);
  150. // Bit reverse if needed.
  151. if (nTypeOut == LRAW_DATA)
  152. BitReverseBuf (&bufOut);
  153. // Calculate output height.
  154. lpbmBand->bmHeight = bufOut.wLengthData / fcp.cbLine;
  155. return TRUE;
  156. }
  157. #endif // VIEWDCX