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.

160 lines
4.1 KiB

  1. /*
  2. * drc.c - Support Delta Row Compression
  3. */
  4. #include "pdev.h"
  5. // Support DRC
  6. /*
  7. * PutDRCData
  8. */
  9. static PBYTE
  10. PutDRCData(
  11. PBYTE pData,
  12. DWORD dwOffset,
  13. DWORD dwSize,
  14. PBYTE pOut,
  15. PBYTE pOutEnd)
  16. {
  17. DWORD dwCount, dwOff;
  18. while (dwSize > 0) {
  19. dwCount = min(dwSize, 8);
  20. // offset
  21. if (dwOffset > 30) {
  22. if (pOut >= pOutEnd)
  23. return NULL;
  24. *pOut++ = (BYTE)(((dwCount - 1) << 5) + 31);
  25. dwOffset -= 31;
  26. while (dwOffset >= 255) {
  27. dwOff = min(dwOffset, 255);
  28. if (pOut >= pOutEnd)
  29. return NULL;
  30. *pOut++ = (BYTE)dwOff;
  31. dwOffset -= dwOff;
  32. }
  33. if (pOut >= pOutEnd)
  34. return NULL;
  35. *pOut++ = (BYTE)dwOffset;
  36. } else {
  37. if (pOut >= pOutEnd)
  38. return NULL;
  39. *pOut++ = (BYTE)(((dwCount - 1) << 5) + dwOffset);
  40. }
  41. dwOffset = 0;
  42. // data
  43. if (&pOut[dwCount] >= pOutEnd)
  44. return NULL;
  45. CopyMemory(pOut, pData, dwCount);
  46. pOut += dwCount;
  47. pData += dwCount;
  48. dwSize -= dwCount;
  49. }
  50. return pOut;
  51. }
  52. /*
  53. * OEMCompression
  54. */
  55. INT APIENTRY
  56. OEMCompression(
  57. PDEVOBJ pdevobj,
  58. PBYTE pInBuf,
  59. PBYTE pOutBuf,
  60. DWORD dwInLen,
  61. DWORD dwOutLen)
  62. {
  63. PLIPSPDEV pOEM = (PLIPSPDEV)pdevobj->pdevOEM;
  64. PBYTE pPre, pIn, pInEnd, pOut, pOutEnd, pStart, pBegin;
  65. PBYTE pPre0, pIn0, pOutHead, pOut0, pOutEnd0;
  66. DWORD dwI, dwLen, dwSize, dwOffset, dwCount;
  67. INT rc;
  68. #ifdef LBP_2030
  69. if (pOEM->fcolor == COLOR) // DRC can't support on 8color mode.
  70. return -1;
  71. #endif
  72. // NTRAID#NTBUG9-571824-2002/03/09-yasuho-:
  73. // Possible buffer overrun if integer overflow was occured.
  74. if (pOEM->dwBmpWidth == 0 || pOEM->dwBmpHeight == 0 ||
  75. pOEM->dwBmpWidth > dwInLen || pOEM->dwBmpHeight > dwInLen ||
  76. (pOEM->dwBmpWidth * pOEM->dwBmpHeight) != dwInLen)
  77. return -1;
  78. // Do DRC compression
  79. rc = -1;
  80. pPre = NULL;
  81. pIn = pInBuf;
  82. pOut = pOutBuf;
  83. pOutEnd = &pOut[dwOutLen];
  84. for (dwI = 0; dwI < pOEM->dwBmpHeight; dwI++) {
  85. pStart = pBegin = pIn;
  86. pInEnd = &pIn[pOEM->dwBmpWidth];
  87. pOutHead = pOut;
  88. while (pIn < pInEnd) {
  89. if (pPre == NULL) {
  90. if (*pIn == 0) {
  91. pIn++;
  92. continue;
  93. }
  94. } else if (*pPre == *pIn) {
  95. pPre++, pIn++;
  96. continue;
  97. }
  98. pIn0 = pIn;
  99. if (pPre == NULL) {
  100. do {
  101. pIn++;
  102. } while (pIn < pInEnd && *pIn);
  103. } else {
  104. do {
  105. pPre++, pIn++;
  106. } while (pIn < pInEnd && *pPre != *pIn);
  107. }
  108. dwOffset = (DWORD)(pIn0 - pStart);
  109. dwSize = (DWORD)(pIn - pIn0);
  110. if (!(pOut = PutDRCData(pIn0, dwOffset, dwSize, pOut, pOutEnd)))
  111. goto out;
  112. pStart = pIn;
  113. }
  114. // Insert length of raster data
  115. if (pOut == pOutHead) {
  116. // identical
  117. if (pOut >= pOutEnd)
  118. goto out;
  119. *pOut++ = 0;
  120. } else {
  121. dwSize = (DWORD)(pOut - pOutHead);
  122. dwCount = (dwSize / 255) + 1;
  123. if (&pOut[dwCount] >= pOutEnd)
  124. goto out;
  125. pPre0 = pOut;
  126. pOut0 = pOut = &pOut[dwCount];
  127. while (pPre0 >= pOutHead)
  128. *--pOut0 = *--pPre0;
  129. pOut0 = pOutHead;
  130. while (dwSize >= 255) {
  131. dwLen = min(dwSize, 255);
  132. *pOut0++ = (BYTE)dwLen;
  133. dwSize -= dwLen;
  134. }
  135. *pOut0++ = (BYTE)dwSize;
  136. }
  137. // set to previous raster
  138. pPre = pBegin;
  139. }
  140. rc = (INT)(pOut - pOutBuf);
  141. out:
  142. return rc;
  143. }