Rle.h 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. /*
  2. * Copyright (C) =USTC= Fu Li
  3. *
  4. * Author : Fu Li
  5. * Create : 2000-9-6
  6. * Home : http://www.crazy-bit.com/
  7. * Mail : crazybit@263.net
  8. * History :
  9. */
  10. #ifndef __PCL_COMPRESS__2000_09_06__H__
  11. #define __PCL_COMPRESS__2000_09_06__H__
  12. #include "../FColor.h"
  13. //=============================================================================
  14. /**
  15. * Compress helper class.
  16. */
  17. class FCCompress
  18. {
  19. public:
  20. /**
  21. * pOutBuffer must at least double size than pInBuffer.
  22. * @return return bytes of written to pOutBuffer.
  23. */
  24. static int RLE_PCX_Encode (const BYTE* pInBuffer, int nInSize, BYTE* pOutBuffer) ;
  25. /**
  26. * pOutBuffer must large enough.
  27. * @return return bytes of written to pOutBuffer.
  28. */
  29. static int RLE_PCX_Decode (const BYTE* pInBuffer, int nInSize, BYTE* pOutBuffer) ;
  30. /**
  31. * pOutBuffer must at least double size than pInBuffer.
  32. * @param iColorBit : bpp - 8, 16, 24, 32
  33. * @param iNumPixel : pixel width of image line
  34. * @return return current pOutBuffer position.
  35. */
  36. static BYTE* RLE_TGA_EncodeLine (const BYTE* pInBuffer, int iColorBit, int iNumPixel, BYTE* pOutBuffer) ;
  37. /**
  38. * pOutBuffer must large enough.
  39. * @param iColorBit : bpp - 8, 16, 24, 32
  40. * @param iNumPixel : pixel width of image line
  41. * @return return current pInBuffer position.
  42. */
  43. static BYTE* RLE_TGA_DecodeLine (const BYTE* pInBuffer, int iColorBit, int iNumPixel, BYTE* pOutBuffer) ;
  44. };
  45. //=============================================================================
  46. // inline Implement
  47. //=============================================================================
  48. inline int FCCompress::RLE_PCX_Encode (const BYTE* pInBuffer, int nInSize, BYTE* pOutBuffer)
  49. {
  50. const BYTE * pOutStart = pOutBuffer ;
  51. while (nInSize-- > 0)
  52. {
  53. const BYTE byData = *pInBuffer++ ;
  54. BYTE cCount = 1 ;
  55. while ( (cCount < 0x3F) && (nInSize != 0) )
  56. if (*pInBuffer != byData) // Stat. the repeat BYTE
  57. break ;
  58. else
  59. {
  60. cCount++ ; pInBuffer++ ; nInSize-- ;
  61. }
  62. if (cCount == 1) // unique
  63. {
  64. if ( byData >= 0xC0 ) // Data >= 0xC0
  65. {
  66. *pOutBuffer++ = 0xC1 ;
  67. *pOutBuffer++ = byData ;
  68. }
  69. else
  70. *pOutBuffer++ = byData ; // Data < 0xC0, write directly
  71. }
  72. else // repeat
  73. {
  74. *pOutBuffer++ = 0xC0 | cCount ;
  75. *pOutBuffer++ = byData ;
  76. }
  77. }
  78. return (int)(pOutBuffer - pOutStart) ;
  79. }
  80. //-----------------------------------------------------------------------------
  81. inline int FCCompress::RLE_PCX_Decode (const BYTE* pInBuffer, int nInSize, BYTE* pOutBuffer)
  82. {
  83. const BYTE * pOutStart = pOutBuffer ;
  84. while (nInSize-- > 0)
  85. {
  86. const BYTE byData = *pInBuffer++ ; // read byte and move ptr to next
  87. if ( byData >= 0xC0 )
  88. {
  89. // error : the inbuffer has been exhausted.
  90. if (nInSize <= 0)
  91. {
  92. assert(false) ; goto rleOver;
  93. }
  94. BYTE cNum = byData & 0x3F ; // repeat current byte Num
  95. ::memset (pOutBuffer, *pInBuffer++, cNum) ; // memset func will check "Num" =? 0
  96. pOutBuffer += cNum ;
  97. nInSize-- ;
  98. }
  99. else
  100. *pOutBuffer++ = byData ;
  101. }
  102. rleOver:
  103. return (int)(pOutBuffer - pOutStart) ;
  104. }
  105. //-----------------------------------------------------------------------------
  106. inline BYTE* FCCompress::RLE_TGA_EncodeLine (const BYTE* InBuffer, int iColorBit, int iNumPixel, BYTE* OutBuffer)
  107. {
  108. iColorBit /= 8 ; // convert to bytes : 1,2,3,4
  109. while (iNumPixel > 0)
  110. {
  111. DWORD Data = 0, Next = 0, Count = 1 ;
  112. FCColor::CopyPixel (&Data, InBuffer, iColorBit) ; // first pixel
  113. InBuffer += iColorBit ; iNumPixel-- ;
  114. while ((Count < 0x80) && (iNumPixel > 0)) // Stat. the repeat pixel
  115. {
  116. FCColor::CopyPixel (&Next, InBuffer, iColorBit) ; // next pixel
  117. if (Next != Data)
  118. break ;
  119. InBuffer += iColorBit ; iNumPixel-- ; Count++ ;
  120. }
  121. *OutBuffer++ = 0x80 | (BYTE)--Count ;
  122. FCColor::CopyPixel (OutBuffer, &Data, iColorBit) ;
  123. OutBuffer += iColorBit ;
  124. }
  125. return OutBuffer ;
  126. }
  127. //-----------------------------------------------------------------------------
  128. inline BYTE* FCCompress::RLE_TGA_DecodeLine (const BYTE* InBuffer, int iColorBit, int iNumPixel, BYTE* OutBuffer)
  129. {
  130. iColorBit /= 8 ; // convert to bytes : 1,2,3,4
  131. while (iNumPixel > 0)
  132. {
  133. const BYTE byData = *InBuffer++ ; // Next Byte
  134. if (byData & 0x80) // Data >= 0x80
  135. {
  136. const int nNum = (byData & 0x7F) + 1 ; // number of repeat pixel
  137. iNumPixel -= nNum ;
  138. for (int i=0 ; i < nNum ; i++, OutBuffer += iColorBit)
  139. FCColor::CopyPixel (OutBuffer, InBuffer, iColorBit) ;
  140. InBuffer += iColorBit ;
  141. }
  142. else
  143. {
  144. // copy directly
  145. const int n = byData + 1, // non-repeat pixel
  146. nByte = n * iColorBit ; // calculate copy bytes
  147. iNumPixel -= n ;
  148. ::memcpy (OutBuffer, InBuffer, nByte) ;
  149. OutBuffer += nByte ;
  150. InBuffer += nByte ;
  151. }
  152. }
  153. assert (iNumPixel == 0) ;
  154. return const_cast<BYTE*>(InBuffer) ;
  155. }
  156. #endif