⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lz77.c

📁 掌握如何用C来实现各种算法
💻 C
📖 第 1 页 / 共 2 页
字号:
*  Point to the buffer of compressed data.                                   *
*                                                                            *
*****************************************************************************/

*compressed = comp;

/*****************************************************************************
*                                                                            *
*  Return the number of bytes in the compressed data.                        *
*                                                                            *
*****************************************************************************/

return ((opos - 1) / 8) + 1;

}

/*****************************************************************************
*                                                                            *
*  ---------------------------- lz77_uncompress ---------------------------  *
*                                                                            *
*****************************************************************************/

int lz77_uncompress(const unsigned char *compressed, unsigned char
   **original) {

unsigned char      window[LZ77_WINDOW_SIZE],
                   buffer[LZ77_BUFFER_SIZE],
                   *orig,
                   *temp,
                   next;

int                offset,
                   length,
                   remaining,
                   hsize,
                   size,
                   ipos,
                   opos,
                   tpos,
                   state,
                   i;

/*****************************************************************************
*                                                                            *
*  Make the pointer to the original data not valid until later.              *
*                                                                            *
*****************************************************************************/

*original = orig = NULL;

/*****************************************************************************
*                                                                            *
*  Get the header information.                                               *
*                                                                            *
*****************************************************************************/

hsize = sizeof(int);
memcpy(&size, compressed, sizeof(int));

/*****************************************************************************
*                                                                            *
*  Initialize the sliding window and the look-ahead buffer.                  *
*                                                                            *
*****************************************************************************/

memset(window, 0, LZ77_WINDOW_SIZE);
memset(buffer, 0, LZ77_BUFFER_SIZE);

/*****************************************************************************
*                                                                            *
*  Uncompress the data.                                                      *
*                                                                            *
*****************************************************************************/

ipos = hsize * 8;
opos = 0;
remaining = size;

while (remaining > 0) {

   /**************************************************************************
   *                                                                         *
   *  Get the next bit in the compressed data.                               *
   *                                                                         *
   **************************************************************************/

   state = bit_get(compressed, ipos);
   ipos++;

   if (state == 1) {

      /***********************************************************************
      *                                                                      *
      *  Handle processing a phrase token.                                   *
      *                                                                      *
      ***********************************************************************/

      memset(&offset, 0, sizeof(int));

      for (i = 0; i < LZ77_WINOFF_BITS; i++) {

         tpos = (sizeof(int) * 8) - LZ77_WINOFF_BITS + i;
         bit_set((unsigned char *)&offset, tpos, bit_get(compressed, ipos));
         ipos++;

      }

      memset(&length, 0, sizeof(int));

      for (i = 0; i < LZ77_BUFLEN_BITS; i++) {

         tpos = (sizeof(int) * 8) - LZ77_BUFLEN_BITS + i;
         bit_set((unsigned char *)&length, tpos, bit_get(compressed, ipos));
         ipos++;

      }

      next = 0x00;

      for (i = 0; i < LZ77_NEXT_BITS; i++) {

         tpos = (sizeof(unsigned char) * 8) - LZ77_NEXT_BITS + i;
         bit_set((unsigned char *)&next, tpos, bit_get(compressed, ipos));
         ipos++;

      }

      /***********************************************************************
      *                                                                      *
      *  Ensure that the offset and length have the correct byte ordering    *
      *  for the system.                                                     *
      *                                                                      *
      ***********************************************************************/

      offset = ntohl(offset);
      length = ntohl(length);

      /***********************************************************************
      *                                                                      *
      *  Write the phrase from the window to the buffer of original data.    *
      *                                                                      *
      ***********************************************************************/

      i = 0;

      if (opos > 0) {

         if ((temp = (unsigned char *)realloc(orig, opos+length+1)) == NULL) {

            free(orig);
            return -1;

         }

         orig = temp;

         }

      else {

         if ((orig = (unsigned char *)malloc(length + 1)) == NULL)
            return -1;

      }

      while (i < length && remaining > 0) {

         orig[opos] = window[offset + i];
         opos++;

         /********************************************************************
         *                                                                   *
         *  Record each symbol in the look-ahead buffer until ready to       *
         *  update the sliding window.                                       *
         *                                                                   *
         ********************************************************************/

         buffer[i] = window[offset + i];
         i++;

         /********************************************************************
         *                                                                   *
         *  Adjust the total symbols remaining to account for each symbol    *
         *  consumed.                                                        *
         *                                                                   *
         ********************************************************************/

         remaining--;

      }

      /***********************************************************************
      *                                                                      *
      *  Write the unmatched symbol to the buffer of original data.          *
      *                                                                      *
      ***********************************************************************/

      if (remaining > 0) {

         orig[opos] = next;
         opos++;

         /********************************************************************
         *                                                                   *
         *  Also record this symbol in the look-ahead buffer.                *
         *                                                                   *
         ********************************************************************/

         buffer[i] = next;

         /********************************************************************
         *                                                                   *
         *  Adjust the total symbols remaining to account for the unmatched  *
         *  symbol.                                                          *
         *                                                                   *
         ********************************************************************/

         remaining--;

      }

      /***********************************************************************
      *                                                                      *
      *  Adjust the phrase length to account for the unmatched symbol.       *
      *                                                                      *
      ***********************************************************************/

      length++;

      }

   else {

      /***********************************************************************
      *                                                                      *
      *  Handle processing a symbol token.                                   *
      *                                                                      *
      ***********************************************************************/

      next = 0x00;

      for (i = 0; i < LZ77_NEXT_BITS; i++) {

         tpos = (sizeof(unsigned char) * 8) - LZ77_NEXT_BITS + i;
         bit_set((unsigned char *)&next, tpos, bit_get(compressed, ipos));
         ipos++;

      }

      /***********************************************************************
      *                                                                      *
      *  Write the symbol to the buffer of original data.                    *
      *                                                                      *
      ***********************************************************************/

      if (opos > 0) {

         if ((temp = (unsigned char *)realloc(orig, opos + 1)) == NULL) {

            free(orig);
            return -1;

         }

         orig = temp;

         }

      else {

         if ((orig = (unsigned char *)malloc(1)) == NULL)
            return -1;

      }

      orig[opos] = next;
      opos++;

      /***********************************************************************
      *                                                                      *
      *  Record the symbol in the look-ahead buffer until ready to update    *
      *  the sliding window.                                                 *
      *                                                                      *
      ***********************************************************************/

      if (remaining > 0)
         buffer[0] = next;

      /***********************************************************************
      *                                                                      *
      *  Adjust the total symbols remaining to account for the unmatched     *
      *  symbol.                                                             *
      *                                                                      *
      ***********************************************************************/

      remaining--;

      /***********************************************************************
      *                                                                      *
      *  Set the phrase length to account for the unmatched symbol.          *
      *                                                                      *
      ***********************************************************************/

      length = 1;

   }

   /**************************************************************************
   *                                                                         *
   *  Copy the look-ahead buffer into the sliding window.                    *
   *                                                                         *
   **************************************************************************/

   memmove(&window[0], &window[length], LZ77_WINDOW_SIZE - length);
   memmove(&window[LZ77_WINDOW_SIZE - length], &buffer[0], length);

}

/*****************************************************************************
*                                                                            *
*  Point to the buffer of original data.                                     *
*                                                                            *
*****************************************************************************/

*original = orig;

/*****************************************************************************
*                                                                            *
*  Return the number of bytes in the original data.                          *
*                                                                            *
*****************************************************************************/

return opos;

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -