| iMatix home page | << | < | > | >> |
SFL Version 2.11 |
#include "sflcomp.h" word compress_rle ( byte *src, byte *dst, word src_size)
Takes a block of uncompressed data in src, compresses it using a RLE algorithm and places the result in dst. To decompress the data, use the expand rle () 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:
[01-7F][data...] | String of uncompressed data, 1 to 127 bytes. |
[83-FF][byte] | Run of 3 to 127 identical bytes. |
[80][len][byte] | Run of 128 to 255 identical bytes. |
[81][lo][hi][byte] | Run of 256 to 2^16 identical bytes. |
[82][len] | Run of 3 to 255 spaces. |
[00][len] | Run of 3 to 255 binary zeroes. |
{ 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 */ /* Three identical bytes signals the start of a run */ if (cur_byte == src [src_scan] && cur_byte == src [src_scan + 1] && (src_scan + 1 < 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++; 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) { /* We compress short runs of spaces and nulls separately */ if (length < 256 && cur_byte == 0) { 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 */ }
| << | < | > | >> | Copyright © 1996-2000 iMatix Corporation |