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.

268 lines
7.2 KiB

  1. /*==============================================================================
  2. This code module handles HRAW<==>DCX conversions.
  3. DATE NAME COMMENTS
  4. 13-Apr-93 RajeevD Adapted to C++ from WFW.
  5. 05-Oct-93 RajeevD Moved out of faxcodec.dll
  6. ==============================================================================*/
  7. #include <ifaxos.h>
  8. #include <memory.h>
  9. #include <dcxcodec.h>
  10. #ifdef DEBUG
  11. DBGPARAM dpCurSettings = {"DCXCODEC"};
  12. #endif
  13. // Context Object
  14. typedef struct FAR DCX : public FC_PARAM
  15. {
  16. LPBYTE lpbSave;
  17. UINT cbSave;
  18. LPBYTE lpbIn, lpbOut;
  19. UINT cbIn, cbOut;
  20. UINT ibLine;
  21. BYTE bVal, bRun;
  22. void Init (LPFC_PARAM lpfcParam)
  23. {
  24. _fmemcpy (this, lpfcParam, sizeof(FC_PARAM));
  25. ibLine = 0;
  26. bRun = 0;
  27. cbSave = 0;
  28. lpbSave = (LPBYTE) (this + 1);
  29. }
  30. FC_STATUS Convert (LPBUFFER, LPBUFFER);
  31. void RawToDcx (void);
  32. void DcxToRaw (void);
  33. }
  34. FAR *LPDCX;
  35. //==============================================================================
  36. FC_STATUS DCX::Convert
  37. (LPBUFFER lpbufIn, LPBUFFER lpbufOut)
  38. {
  39. // Trap end of page.
  40. if (!lpbufIn || lpbufIn->dwMetaData == END_OF_PAGE)
  41. return FC_INPUT_EMPTY;
  42. // Get buffer parameters.
  43. lpbIn = lpbufIn->lpbBegData;
  44. cbIn = lpbufIn->wLengthData;
  45. lpbOut = lpbufOut->EndData();
  46. // Restore raw overflow.
  47. if (cbSave)
  48. {
  49. DEBUGCHK (nTypeOut == HRAW_DATA);
  50. _fmemcpy (lpbOut, lpbSave, cbSave);
  51. lpbOut += cbSave;
  52. }
  53. // Calculate output buffer.
  54. cbOut = (UINT)(lpbufOut->EndBuf() - lpbOut);
  55. // Execute the conversion.
  56. nTypeOut == DCX_DATA ? RawToDcx() : DcxToRaw();
  57. // Adjust buffers.
  58. lpbufIn->lpbBegData = lpbIn;
  59. lpbufIn->wLengthData = (USHORT)cbIn;
  60. lpbufOut->wLengthData = (USHORT)(lpbOut - lpbufOut->lpbBegData);
  61. // Save raw overflow.
  62. if (nTypeOut == HRAW_DATA)
  63. {
  64. cbSave = lpbufOut->wLengthData % cbLine;
  65. lpbufOut->wLengthData -= (USHORT)cbSave;
  66. _fmemcpy (lpbSave, lpbufOut->EndData(), cbSave);
  67. }
  68. // Return status.
  69. return cbIn? FC_OUTPUT_FULL : FC_INPUT_EMPTY;
  70. }
  71. /*==============================================================================
  72. This procedure decodes HRAW bitmaps from DCX. In a DCX encoding, if the two
  73. high bits of a byte are set, the remainder of the byte indicates the number of
  74. times the following byte is to be repeated. The procedure returns when either
  75. the input is empty, or the output is full. Unlike the consumers and producers
  76. in the t4core.asm, it does not automatically return at the first EOL.
  77. ==============================================================================*/
  78. void DCX::DcxToRaw (void)
  79. {
  80. // Loop until input is empty or output is full.
  81. while (1)
  82. {
  83. if (bRun >= 0xC0) // Has the run been decoded?
  84. {
  85. if (!cbIn) return; // Check if input is empty.
  86. if (ibLine >= cbLine) // If at end of line,
  87. ibLine = 0; // wrap the position.
  88. bVal = ~(*lpbIn++); // Fetch the value of the run.
  89. cbIn--;
  90. bRun -= 0xC0; // Decode the run length.
  91. }
  92. #if 0 // transparent version
  93. // Write out the run.
  94. while (bRun)
  95. {
  96. *lpbOut++ = bVal;
  97. cbOut--;
  98. ibLine++;
  99. bRun--;
  100. }
  101. #else // optimized version
  102. if (bRun)
  103. {
  104. // Write out the run.
  105. BYTE bLen = min (bRun, cbOut);
  106. _fmemset (lpbOut, bVal, bLen);
  107. // Adjust the output parameters.
  108. bRun -= bLen;
  109. lpbOut += bLen;
  110. cbOut -= bLen;
  111. ibLine += bLen;
  112. // Check if output is full.
  113. if (!cbOut) return;
  114. }
  115. #endif // optimize switch
  116. if (!cbIn) return; // Fetch the next byte.
  117. if (ibLine >= cbLine) // If at end of line,
  118. ibLine = 0; // wrap the position.
  119. if (*lpbIn >= 0xC0) // If the byte is a run length, set up.
  120. bRun = *lpbIn++;
  121. else // Otherwise the byte is a single value.
  122. { bRun = 1; bVal = ~(*lpbIn++);}
  123. cbIn--;
  124. } // while (1)
  125. }
  126. /*==============================================================================
  127. This procedure encodes HRAW bitmaps for DCX. In a DCX encoding, if the two
  128. high bits of a byte are set, the remainder of the byte indicates the number of
  129. times the following byte is to be repeated. The procedure returns when either
  130. the input is empty or the output is full. Unlike its brethren in T4, it does
  131. not return automatically at EOL.
  132. ==============================================================================*/
  133. void DCX::RawToDcx (void)
  134. {
  135. BYTE bVal, bRun;
  136. // Convert until input is empty or output is full.
  137. // The output is full if only one byte is available
  138. // because one input byte may produce two output bytes.
  139. while (cbIn && cbOut > 1)
  140. {
  141. if (ibLine >= cbLine) ibLine = 0; // If EOL, wrap the position.
  142. // Get an input byte.
  143. bVal = *lpbIn++;
  144. cbIn--;
  145. bRun = 1;
  146. ibLine++;
  147. // Scan for a run until one of the following occurs:
  148. // (1) There are no more input bytes to be consumed.
  149. // (2) The end of the current line has been reached.
  150. // (3) The run length has reached the maximum of 63.
  151. // (4) The first byte does not match the current one.
  152. #if 0 // Transparent Version.
  153. while (/*1*/ cbIn // Check first to avoid GP faults!
  154. && /*4*/ bVal == *lpbIn
  155. && /*2*/ ibLine < cbLine
  156. && /*3*/ bRun < 63
  157. )
  158. { lpbIn++; cbIn--; bRun++; ibLine++; }
  159. #else // Optimized Version
  160. // If the next byte matches, scan for a run.
  161. // This test has been unrolled from the loop.
  162. if (cbIn && bVal == *lpbIn)
  163. {
  164. BYTE ubMaxRest, ubRest;
  165. // Calculate the maximum number of bytes remaining.
  166. ubMaxRest = min (cbIn, 62);
  167. ubMaxRest = min (ubMaxRest, cbLine - ibLine);
  168. // Scan for a run.
  169. ubRest = 0;
  170. while (bVal == *lpbIn && ubRest < ubMaxRest)
  171. {lpbIn++; ubRest++;}
  172. // Adjust state.
  173. cbIn -= ubRest;
  174. ibLine += ubRest;
  175. bRun = ++ubRest;
  176. }
  177. #endif // End of Compile Switch
  178. bVal = ~bVal; // Flip black and white.
  179. // Does the value need to be escaped,
  180. // or is there non-trival run of bytes?
  181. if (bVal >= 0xC0 || bRun>1)
  182. { // Yes, encode the run length.
  183. // (Possibly 1 for bVal>=0xC0).
  184. *lpbOut++ = bRun + 0xC0;
  185. cbOut--;
  186. }
  187. *lpbOut++ = bVal; // Encode the value.
  188. cbOut--;
  189. } // while (1)
  190. }
  191. //==============================================================================
  192. // C Export Wrappers
  193. //==============================================================================
  194. #ifndef WIN32
  195. BOOL WINAPI LibMain
  196. (HANDLE hInst, WORD wSeg, WORD wHeap, LPSTR lpszCmd)
  197. { return 1; }
  198. extern "C" {int WINAPI WEP (int nParam);}
  199. #pragma alloc_text(INIT_TEXT,WEP)
  200. int WINAPI WEP (int nParam)
  201. { return 1; }
  202. #endif
  203. //==============================================================================
  204. UINT WINAPI DcxCodecInit
  205. (LPVOID lpContext, LPFC_PARAM lpfcParam)
  206. {
  207. UINT cbContext = sizeof(DCX);
  208. if (lpfcParam->nTypeOut == HRAW_DATA)
  209. cbContext += lpfcParam->cbLine;
  210. if (lpContext)
  211. ((LPDCX) lpContext)->Init (lpfcParam);
  212. return cbContext;
  213. }
  214. //==============================================================================
  215. FC_STATUS WINAPI DcxCodecConvert
  216. (LPVOID lpContext, LPBUFFER lpbufIn, LPBUFFER lpbufOut)
  217. {
  218. return ((LPDCX) lpContext)->Convert (lpbufIn, lpbufOut);
  219. }