123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- /*
- * Copyright (C) =USTC= Fu Li
- *
- * Author : Fu Li
- * Create : 2000-9-6
- * Home : http://www.crazy-bit.com/
- * Mail : crazybit@263.net
- * History :
- */
- #ifndef __PCL_COMPRESS__2000_09_06__H__
- #define __PCL_COMPRESS__2000_09_06__H__
- #include "../FColor.h"
- //=============================================================================
- /**
- * Compress helper class.
- */
- class FCCompress
- {
- public:
- /**
- * pOutBuffer must at least double size than pInBuffer.
- * @return return bytes of written to pOutBuffer.
- */
- static int RLE_PCX_Encode (const BYTE* pInBuffer, int nInSize, BYTE* pOutBuffer) ;
- /**
- * pOutBuffer must large enough.
- * @return return bytes of written to pOutBuffer.
- */
- static int RLE_PCX_Decode (const BYTE* pInBuffer, int nInSize, BYTE* pOutBuffer) ;
- /**
- * pOutBuffer must at least double size than pInBuffer.
- * @param iColorBit : bpp - 8, 16, 24, 32
- * @param iNumPixel : pixel width of image line
- * @return return current pOutBuffer position.
- */
- static BYTE* RLE_TGA_EncodeLine (const BYTE* pInBuffer, int iColorBit, int iNumPixel, BYTE* pOutBuffer) ;
- /**
- * pOutBuffer must large enough.
- * @param iColorBit : bpp - 8, 16, 24, 32
- * @param iNumPixel : pixel width of image line
- * @return return current pInBuffer position.
- */
- static BYTE* RLE_TGA_DecodeLine (const BYTE* pInBuffer, int iColorBit, int iNumPixel, BYTE* pOutBuffer) ;
- };
- //=============================================================================
- // inline Implement
- //=============================================================================
- inline int FCCompress::RLE_PCX_Encode (const BYTE* pInBuffer, int nInSize, BYTE* pOutBuffer)
- {
- const BYTE * pOutStart = pOutBuffer ;
- while (nInSize-- > 0)
- {
- const BYTE byData = *pInBuffer++ ;
- BYTE cCount = 1 ;
- while ( (cCount < 0x3F) && (nInSize != 0) )
- if (*pInBuffer != byData) // Stat. the repeat BYTE
- break ;
- else
- {
- cCount++ ; pInBuffer++ ; nInSize-- ;
- }
- if (cCount == 1) // unique
- {
- if ( byData >= 0xC0 ) // Data >= 0xC0
- {
- *pOutBuffer++ = 0xC1 ;
- *pOutBuffer++ = byData ;
- }
- else
- *pOutBuffer++ = byData ; // Data < 0xC0, write directly
- }
- else // repeat
- {
- *pOutBuffer++ = 0xC0 | cCount ;
- *pOutBuffer++ = byData ;
- }
- }
- return (int)(pOutBuffer - pOutStart) ;
- }
- //-----------------------------------------------------------------------------
- inline int FCCompress::RLE_PCX_Decode (const BYTE* pInBuffer, int nInSize, BYTE* pOutBuffer)
- {
- const BYTE * pOutStart = pOutBuffer ;
- while (nInSize-- > 0)
- {
- const BYTE byData = *pInBuffer++ ; // read byte and move ptr to next
- if ( byData >= 0xC0 )
- {
- // error : the inbuffer has been exhausted.
- if (nInSize <= 0)
- {
- assert(false) ; goto rleOver;
- }
- BYTE cNum = byData & 0x3F ; // repeat current byte Num
- ::memset (pOutBuffer, *pInBuffer++, cNum) ; // memset func will check "Num" =? 0
- pOutBuffer += cNum ;
- nInSize-- ;
- }
- else
- *pOutBuffer++ = byData ;
- }
- rleOver:
- return (int)(pOutBuffer - pOutStart) ;
- }
- //-----------------------------------------------------------------------------
- inline BYTE* FCCompress::RLE_TGA_EncodeLine (const BYTE* InBuffer, int iColorBit, int iNumPixel, BYTE* OutBuffer)
- {
- iColorBit /= 8 ; // convert to bytes : 1,2,3,4
- while (iNumPixel > 0)
- {
- DWORD Data = 0, Next = 0, Count = 1 ;
- FCColor::CopyPixel (&Data, InBuffer, iColorBit) ; // first pixel
- InBuffer += iColorBit ; iNumPixel-- ;
- while ((Count < 0x80) && (iNumPixel > 0)) // Stat. the repeat pixel
- {
- FCColor::CopyPixel (&Next, InBuffer, iColorBit) ; // next pixel
- if (Next != Data)
- break ;
- InBuffer += iColorBit ; iNumPixel-- ; Count++ ;
- }
- *OutBuffer++ = 0x80 | (BYTE)--Count ;
- FCColor::CopyPixel (OutBuffer, &Data, iColorBit) ;
- OutBuffer += iColorBit ;
- }
- return OutBuffer ;
- }
- //-----------------------------------------------------------------------------
- inline BYTE* FCCompress::RLE_TGA_DecodeLine (const BYTE* InBuffer, int iColorBit, int iNumPixel, BYTE* OutBuffer)
- {
- iColorBit /= 8 ; // convert to bytes : 1,2,3,4
- while (iNumPixel > 0)
- {
- const BYTE byData = *InBuffer++ ; // Next Byte
- if (byData & 0x80) // Data >= 0x80
- {
- const int nNum = (byData & 0x7F) + 1 ; // number of repeat pixel
- iNumPixel -= nNum ;
- for (int i=0 ; i < nNum ; i++, OutBuffer += iColorBit)
- FCColor::CopyPixel (OutBuffer, InBuffer, iColorBit) ;
- InBuffer += iColorBit ;
- }
- else
- {
- // copy directly
- const int n = byData + 1, // non-repeat pixel
- nByte = n * iColorBit ; // calculate copy bytes
- iNumPixel -= n ;
- ::memcpy (OutBuffer, InBuffer, nByte) ;
- OutBuffer += nByte ;
- InBuffer += nByte ;
- }
- }
- assert (iNumPixel == 0) ;
- return const_cast<BYTE*>(InBuffer) ;
- }
- #endif
|