lzw.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:9k
源码类别:

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. #include <hlxclib/memory.h>
  36. #include <string.h>
  37. #include "lzw.h"
  38. #include "hxheap.h"
  39. #ifdef _DEBUG
  40. #undef HX_THIS_FILE
  41. static char HX_THIS_FILE[] = __FILE__;
  42. #endif
  43. LZWCodec::LZWCodec()
  44. {
  45.     /* Initialize all member variables */
  46.     m_bFresh                   = TRUE;
  47.     m_bPostClearCode           = FALSE;
  48.     m_lCodeSize                = 0;
  49.     m_lSetCodeSize             = 0;
  50.     m_lMaxCode                 = 0;
  51.     m_lMaxCodeSize             = 0;
  52.     m_lFirstCode               = 0;
  53.     m_lOldCode                 = 0;
  54.     m_lClearCode               = 0;
  55.     m_lEndCode                 = 0;
  56.     m_pCurByte                 = NULL;
  57.     m_lCurBit                  = 0;
  58.     m_lBytesInBuffer           = -1;
  59.     m_bFinished                = FALSE;
  60.     m_bSuspended               = TRUE;
  61.     m_bAllCompressedDataCopied = FALSE;
  62.     m_pCompressedBuffer        = NULL;
  63.     m_lCompressedBufferSize    = 0;
  64.     m_lCompressedBytesCopied   = 0;
  65.     /* Clear the tables */
  66.     ClearTables();
  67.     /* Reset the stack */
  68.     m_plStackPtr = m_lStack;
  69. };
  70. LZWCodec::~LZWCodec()
  71. {
  72.     if (m_pCompressedBuffer)
  73.     {
  74.         delete [] m_pCompressedBuffer;
  75.         m_pCompressedBuffer = NULL;
  76.     }
  77. };
  78. HX_RESULT LZWCodec::SetCompressedBufferSize(INT32 lSize)
  79. {
  80.     /* Check for input error conditions */
  81.     if (lSize < 1)
  82.     {
  83.         return HXR_INVALID_PARAMETER;
  84.     }
  85.     /* Allocate space for the compressed buffer */
  86.     if (m_pCompressedBuffer)
  87.     {
  88.         delete [] m_pCompressedBuffer;
  89.         m_pCompressedBuffer = NULL;
  90.     }
  91.     m_pCompressedBuffer = new BYTE [lSize];
  92.     if (!m_pCompressedBuffer)
  93.     {
  94.         return HXR_OUTOFMEMORY;
  95.     }
  96.     /* Set the size */
  97.     m_lCompressedBufferSize  = lSize;
  98.     m_lCompressedBytesCopied = 0;
  99.     /* Initialize the state variables */
  100.     m_pCurByte                 = m_pCompressedBuffer;
  101.     m_lBytesInBuffer           = -1;
  102.     m_bAllCompressedDataCopied = FALSE;
  103.     m_bSuspended               = TRUE;
  104.     return HXR_OK;
  105. }
  106. HX_RESULT LZWCodec::InitDecompress(INT32 lMinCodeBits)
  107. {
  108.     /* Check for input error conditions */
  109.     if (lMinCodeBits < 1 || lMinCodeBits >  kMaxLZWBits)
  110.     {
  111.         return HXR_INVALID_PARAMETER;
  112.     }
  113.     /* Set up code size parameters */
  114.     m_lSetCodeSize = lMinCodeBits;
  115.     m_lCodeSize    = m_lSetCodeSize + 1;
  116.     m_lClearCode   = 1 << m_lSetCodeSize;
  117.     m_lEndCode     = m_lClearCode + 1;
  118.     m_lMaxCodeSize = m_lClearCode << 1;
  119.     m_lMaxCode     = m_lClearCode + 2;
  120.     /* This says to look for clear codes */
  121.     m_bFresh = TRUE;
  122.     /* Clear out all table entries */
  123.     ClearTables();
  124.     /* Reset the stack pointer */
  125.     m_plStackPtr = m_lStack;
  126.     return HXR_OK;
  127. }
  128. HX_RESULT LZWCodec::AppendCompressedBuffer(BYTE *pBuffer, INT32 lBufLen)
  129. {
  130.     /* Check for input error conditions */
  131.     if (pBuffer == NULL || lBufLen < 1)
  132.     {
  133.         return HXR_INVALID_PARAMETER;
  134.     }
  135.     /* Make sure we're not called after we should be */
  136.     if (m_bAllCompressedDataCopied == TRUE)
  137.     {
  138.         return HXR_OK;
  139.     }
  140.     /* Make sure we don't copy off the end of the buffer */
  141.     INT32 lBytesToCopy;
  142.     if (m_lCompressedBytesCopied + lBufLen <= m_lCompressedBufferSize)
  143.     {
  144.         lBytesToCopy = lBufLen;
  145.     }
  146.     else
  147.     {
  148.         lBytesToCopy = m_lCompressedBufferSize - m_lCompressedBytesCopied;
  149.     }
  150.     /* Do the copy */
  151.     memcpy(&m_pCompressedBuffer[m_lCompressedBytesCopied], pBuffer, lBytesToCopy); /* Flawfinder: ignore */
  152.     /* Update the member variables */
  153.     m_lCompressedBytesCopied += lBufLen;
  154.     m_lBytesInBuffer         += lBufLen;
  155.     m_bSuspended              = FALSE;
  156.     /* Check if we've received all data */
  157.     if (m_lCompressedBytesCopied >= m_lCompressedBufferSize)
  158.     {
  159.         m_bAllCompressedDataCopied = TRUE;
  160.     }
  161.     return HXR_OK;
  162. }
  163. HX_RESULT LZWCodec::LZWReadByte(INT32 &rlSymbol)
  164. {
  165.     /* Are we still suspended? */
  166.     if (m_bSuspended == TRUE)
  167.     {
  168.         rlSymbol = -1;
  169.         return HXR_OK;
  170.     }
  171.     INT32 lCode;
  172.     /* If this flag is set, it means skip all clear codes at the current point */
  173.     if (m_bFresh == TRUE)
  174.     {
  175.         do
  176.         {
  177.             lCode = GetCode();
  178.             if (lCode < 0)
  179.             {
  180.                 rlSymbol     = -1;
  181.                 m_bSuspended = TRUE;
  182.                 return HXR_OK;
  183.             }
  184.             m_lFirstCode = m_lOldCode = lCode;
  185.         }
  186.         while (m_lFirstCode == m_lClearCode);
  187.         m_bFresh = FALSE;
  188.         rlSymbol = m_lFirstCode;
  189.         return HXR_OK;
  190.     }
  191.     /* If we're currently copying off the stack, then return the stack values */
  192.     if (m_plStackPtr > m_lStack)
  193.     {
  194.         rlSymbol = *--m_plStackPtr;
  195.         return HXR_OK;
  196.     }
  197.     /* Read values until we're done or we suspend */
  198.     while (1)
  199.     {
  200.         /* Get a code */
  201.         lCode = GetCode();
  202.         if (lCode < 0)
  203.         {
  204.             rlSymbol     = -1;
  205.             m_bSuspended = TRUE;
  206.             return HXR_OK;
  207.         }
  208.         /* Is this a code just after a clear code? */
  209.         if (m_bPostClearCode == TRUE)
  210.         {
  211.             m_bPostClearCode = FALSE;
  212.             m_lFirstCode     = m_lOldCode = rlSymbol = lCode;
  213.             return HXR_OK;
  214.         }
  215.         /* We got a valid code, so now take action based on that code */
  216.         if (lCode == m_lClearCode)
  217.         {
  218.             /* We got a clear code, so we clear the tables and reset everything */
  219.             ClearTables();
  220.             m_lCodeSize    = m_lSetCodeSize + 1;
  221.             m_lMaxCodeSize = m_lClearCode << 1;
  222.             m_lMaxCode     = m_lClearCode + 2;
  223.             m_plStackPtr   = m_lStack;
  224.             /* Set the flag which says we just got a clear code */
  225.             m_bPostClearCode = TRUE;
  226.         }
  227.         else if (lCode == m_lEndCode)
  228.         {
  229.             rlSymbol     = lCode;
  230.             m_bFinished  = TRUE;
  231.             m_bSuspended = FALSE;
  232.             return HXR_OK;
  233.         }
  234.         else
  235.         {
  236.             INT32 lInCode = lCode;
  237.             if (lCode >= m_lMaxCode)
  238.             {
  239.                 *m_plStackPtr++ = m_lFirstCode;
  240.                 lCode           = m_lOldCode;
  241.             }
  242.             INT32* pStackLimit = &m_lStack[0] + (kMaxLZWVal << 1);
  243.             while (lCode >= m_lClearCode)
  244.             {
  245.                 if (m_plStackPtr >= pStackLimit)
  246.                 {
  247.                     // We've blown our code stack, so we have a corrupt
  248.                     // GIF image. In this case, we need to error out.
  249.                     return HXR_FAIL;
  250.                 }
  251.                 *m_plStackPtr++ = m_lTable[1][lCode];
  252.                 if (lCode == m_lTable[0][lCode])
  253.                 {
  254.                     /* Tables have a circular reference in them - corrupt file */
  255.                     return HXR_FAILED;
  256.                 }
  257.                 lCode = m_lTable[0][lCode];
  258.             }
  259.             *m_plStackPtr++ = m_lFirstCode = m_lTable[1][lCode];
  260.             lCode = m_lMaxCode;
  261.             if (lCode < kMaxLZWVal)
  262.             {
  263.                 m_lTable[0][lCode] = m_lOldCode;
  264.                 m_lTable[1][lCode] = m_lFirstCode;
  265.                 m_lMaxCode++;
  266.                 if (m_lMaxCode     >= m_lMaxCodeSize &&
  267.                     m_lMaxCodeSize <  kMaxLZWVal)
  268.                 {
  269.                     m_lMaxCodeSize <<= 1;
  270.                     m_lCodeSize++;
  271.                 }
  272.             }
  273.             m_lOldCode = lInCode;
  274.             if (m_plStackPtr > m_lStack)
  275.             {
  276.                 rlSymbol = *--m_plStackPtr;
  277.                 return HXR_OK;
  278.             }
  279.         }
  280.     }
  281.     rlSymbol = 0;
  282.     return HXR_OK;
  283. }