📄 sflcomp.c
字号:
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 + -