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

📄 sflcomp.c

📁 短小精悍的C语言标准函数库。提供450个以上的可移植的算法和工具代码。
💻 C
📖 第 1 页 / 共 3 页
字号:
                dst [dst_size++] = 0x00;
                dst [dst_size++] = (byte) length;
              }
            else
            if (length < 256 && cur_byte == ' ')
              {
                dst [dst_size++] = 0x82;
                dst [dst_size++] = (byte) length;
              }
            else
            if (length < 128)
              {
                dst [dst_size++] = (byte) length | 0x80;
                dst [dst_size++] = cur_byte;
              }
            else
            if (length < 256)           /*  Short run 128-255 bytes          */
              {
                dst [dst_size++] = 0x80;
                dst [dst_size++] = (byte) length;
                dst [dst_size++] = cur_byte;
              }
            else                        /*  Long run 256-2^16 bytes          */
              {
                dst [dst_size++] = 0x81;
                dst [dst_size++] = (byte) (length & 0xff);
                dst [dst_size++] = (byte) (length >> 8);
                dst [dst_size++] = cur_byte;
              }
          }
        else
          {
            if (!header)                /*  Start new unpacked string if     */
              {                         /*    necessary                      */
                header = &dst [dst_size++];
                length = 0;
              }
            dst [dst_size++] = cur_byte;
            if (++length == 127)        /*  Each string can be up to 127     */
              {                         /*    bytes long (high bit cleared)  */
                *header = (byte) length;
                header  = NULL;
              }
          }
      }
    if (header)                         /*  If we have a previous unpacked   */
      {                                 /*    string, close it               */
        *header = (byte) length;
        header  = NULL;
      }
    return (dst_size);                  /*  Return compressed data size      */
}


/*  ---------------------------------------------------------------------[<]-
    Function: expand_rle

    Synopsis: Expands a block of data previously compressed using the
    compress_rle() function.  The compressed block is passed in src; the
    expanded result in dst.  Dst must be large enough to accomodate the
    largest possible decompressed block.  Returns the size of the expanded
    data.
    ---------------------------------------------------------------------[>]-*/

word
expand_rle (
    const byte *src,
    byte *dst,
    word src_size)
{
    word
        dst_size,                       /*  Size of expanded data            */
        src_scan,                       /*  Scan through source data         */
        length;                         /*  Size of the run or string        */
    byte
        cur_byte;                       /*  Next byte to process             */

    src_scan = 0;
    dst_size = 0;
    while (src_scan < src_size)
      {
        cur_byte = src [src_scan++];

        /*  1 to 127 is uncompressed string of 1 to 127 bytes                */
        if (cur_byte > 0 && cur_byte < 128)
          {
            length = (word) cur_byte;
            memcpy (dst + dst_size, src + src_scan, length);
            src_scan += length;
            dst_size += length;
          }
        else                            /*  Run of 3 or more bytes           */
          {
            switch (cur_byte)
              {
                case 0x00:              /*  Run of 3-255 zeroes              */
                    length   = src [src_scan++];
                    cur_byte = 0;
                    break;
                case 0x82:              /*  Run of 3-255 spaces              */
                    length   = src [src_scan++];
                    cur_byte = ' ';
                    break;
                case 0x80:              /*  Short run 128-255 bytes          */
                    length   = src [src_scan++];
                    cur_byte = src [src_scan++];
                    break;
                case 0x81:              /*  Long run 256-2^16 bytes          */
                    length   = src [src_scan++];
                    length  += src [src_scan++] << 8;
                    cur_byte = src [src_scan++];
                    break;
                default:                /*  Run of 3 to 127 bytes            */
                    length = cur_byte & 127;
                    cur_byte = src [src_scan++];
              }
            memset (dst + dst_size, cur_byte, length);
            dst_size += length;
          }
      }
    return (dst_size);                  /*  Return expanded data size        */
}


/*  ---------------------------------------------------------------------[<]-
    Function: compress_nulls

    Synopsis: Similar to compress_rle(), but optimised towards compression
    of binary zeroes.  Use this when you are certain that the sparse areas
    are set to binary zeroes.  You must use expand_nulls () to decompress
    a block compressed with this function.  Returns the size of the
    compressed data.  The dst buffer should be 10% larger than the src
    buffer.  The src buffer must be at least src_size + 1 bytes long.  It
    may be modified.  The compressed data contains these strings:
    <Table>
    [01-7F][data...]        String of uncompressed data, 1 to 127 bytes.
    [82-FF]                 Run of 2 to 127 binary zeroes.
    [81][80-FF]             Run of 128 to 255 binary zeroes.
    [80][lo][hi]            Run of 256 to 2^16 binary zeroes.
    [00][len][byte]         Run of 4 to 255 identical bytes.
    [00][00][lo][hi][byte]  Run of 256 to 2^16 identical bytes.
    </Table>
    ---------------------------------------------------------------------[>]-*/

word
compress_nulls (
    byte *src,
    byte *dst,
    word src_size)
{
    word
        dst_size,                       /*  Size of compressed data          */
        src_scan,                       /*  Scan through source data         */
        run_end,                        /*  Points to end of run of bytes    */
        length = 0;                     /*  Size of the run or string        */
    byte
        cur_byte,                       /*  Next byte to process             */
        *header;                        /*  Header of unpacked string        */
    Bool
        have_run;                       /*  TRUE when we have a run          */

    src_scan = 0;                       /*  Start at beginning of source     */
    dst_size = 0;                       /*  No output yet                    */
    header   = NULL;                    /*  No open unpacked string          */
    while (src_scan < src_size)
      {
        cur_byte = src [src_scan++];
        have_run = FALSE;               /*  Unless we find a run             */

        /*  Two identical bytes may signal the start of a run                */
        if (cur_byte == src [src_scan]
        &&  src_scan < src_size)
          {
            /*  Stick-in a sentinel character to ensure that the run ends    */
            src [src_size] = !cur_byte;
            run_end = src_scan;         /*  src_scan <= src_size             */
            while (src [run_end] == cur_byte)
                run_end++;

            /*  A run is 4+ identical bytes or 2+ nulls                      */
            if ((run_end - src_scan > 2) || cur_byte == 0)
              {
                have_run = TRUE;
                if (header)             /*  If we have a previous unpacked   */
                  {                     /*    string, close it               */
                    *header = (byte) length;
                    header  = NULL;
                  }
                length = run_end - src_scan + 1;
                src_scan = run_end;
              }
          }
        if (have_run)
          {
            if (cur_byte == 0)
              {
                if (length < 128)       /*  2-127 binary zeroes              */
                    dst [dst_size++] = (byte) (length | 0x80);
                else
                if (length < 256)       /*  128-256 binary zeroes            */
                  {
                    dst [dst_size++] = 0x81;
                    dst [dst_size++] = (byte) length;
                  }
                else                    /*  256-2^15 binary zeroes           */
                  {
                    dst [dst_size++] = 0x80;
                    dst [dst_size++] = (byte) (length & 0xff);
                    dst [dst_size++] = (byte) (length >> 8);
                  }
              }
            else
            if (length < 256)           /*  Short run 4-255 bytes            */
              {
                dst [dst_size++] = 0x00;
                dst [dst_size++] = (byte) length;
                dst [dst_size++] = cur_byte;
              }
            else                        /*  Long run 256-2^16 bytes          */
              {
                dst [dst_size++] = 0x00;
                dst [dst_size++] = 0x00;
                dst [dst_size++] = (byte) (length & 0xff);
                dst [dst_size++] = (byte) (length >> 8);
                dst [dst_size++] = cur_byte;
              }
          }
        else
          {
            if (!header)                /*  Start new unpacked string if     */
              {                         /*    necessary                      */
                header = &dst [dst_size++];
                length = 0;
              }
            dst [dst_size++] = cur_byte;
            if (++length == 127)        /*  Each string can be up to 127     */
              {                         /*    bytes long (high bit cleared)  */
                *header = (byte) length;
                header  = NULL;
              }
          }
      }
    if (header)                         /*  If we have a previous unpacked   */
      {                                 /*    string, close it               */
        *header = (byte) length;
        header  = NULL;
      }
    return (dst_size);                  /*  Return compressed data size      */
}


/*  ---------------------------------------------------------------------[<]-
    Function: expand_nulls

    Synopsis: Expands a block of data previously compressed using the
    compress_nulls() function. The compressed block is passed in src; the
    expanded result in dst.  Dst must be large enough to accomodate the
    largest possible decompressed block.  Returns the size of the expanded
    data.
    ---------------------------------------------------------------------[>]-*/

word
expand_nulls (
    const byte *src,
    byte *dst,
    word src_size)
{
    word
        dst_size,                       /*  Size of expanded data            */
        src_scan,                       /*  Scan through source data         */
        length;                         /*  Size of the run or string        */
    byte
        cur_byte;                       /*  Next byte to process             */

    src_scan = 0;
    dst_size = 0;
    while (src_scan < src_size)
      {
        cur_byte = src [src_scan++];

        /*  1 to 127 is uncompressed string of 1 to 127 bytes                */
        if (cur_byte > 0 && cur_byte < 128)
          {
            length = (word) cur_byte;
            memcpy (dst + dst_size, src + src_scan, length);
            src_scan += length;
            dst_size += length;

⌨️ 快捷键说明

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