From 3e64690f20260eb01ea440d745c177930fba6568 Mon Sep 17 00:00:00 2001 From: bernie Date: Wed, 4 Aug 2004 02:35:54 +0000 Subject: [PATCH] Import simple RLE algorithm. git-svn-id: https://src.develer.com/svnoss/bertos/trunk@103 38d2e660-2303-0410-9eaa-f027e97ec537 --- mware/rle.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++++ mware/rle.h | 27 +++++++++++ 2 files changed, 160 insertions(+) create mode 100755 mware/rle.c create mode 100755 mware/rle.h diff --git a/mware/rle.c b/mware/rle.c new file mode 100755 index 00000000..4655ab66 --- /dev/null +++ b/mware/rle.c @@ -0,0 +1,133 @@ +/*! + * \file + * + * + * \brief General-purpose run-length {en,de}coding algorithm (implementation) + * + * Original source code from http://www.compuphase.com/compress.htm + * + * \version $Id$ + * \author Bernardo Innocenti + */ + +/* + * $Log$ + * Revision 1.1 2004/08/04 02:35:54 bernie + * Import simple RLE algorithm. + * + */ + +#include "rle.h" + + +/*! + * Run-length encode \a len bytes from the \a input buffer + * to the \a output buffer. + */ +int rle(unsigned char *output, const unsigned char *input, int len) +{ + int count, index, i; + unsigned char first; + unsigned char *out; + + + out = output; + count = 0; + while (count < len) + { + index = count; + first = input[index++]; + + /* Scan for bytes identical to the first one */ + while ((index < len) && (index - count < 127) && (input[index] == first)) + index++; + + if (index - count == 1) + { + /* Failed to "replicate" the current byte. See how many to copy. + */ + while ((index < len) && (index - count < 127)) + { + /* Avoid a replicate run of only 2-bytes after a literal run. + * There is no gain in this, and there is a risc of loss if the + * run after the two identical bytes is another literal run. + * So search for 3 identical bytes. + */ + if ((input[index] == input[index - 1]) && + ((index > 1) && (input[index] == input[index - 2]))) + { + /* Reset the index so we can back up these three identical + * bytes in the next run. + */ + index -= 2; + break; + } + + index++; + } + + /* Output a run of uncompressed bytes: write length and values */ + *out++ = (unsigned char)(count - index); + for (i = count; i < index; i++) + *out++ = input[i]; + } + else + { + /* Output a compressed run: write length and value */ + *out++ = (unsigned char)(index - count); + *out++ = first; + } + + count = index; + } + + /* Output EOF marker */ + *out++ = 0; + + return (out - output); +} + + +/*! + * Run-length decode from the \a input buffer to the \a output + * buffer. + * + * \note The output buffer must be large enough to accomodate + * all decoded output. + */ +int unrle(unsigned char *output, const unsigned char *input) +{ + signed char count; + unsigned char *out; + unsigned char value; + + + out = output; + + for (;;) + { + count = (signed char)*input++; + if (count > 0) + { + /* replicate run */ + value = *input++; + while (count--) + *out++ = value; + } + else if (count < 0) + { + /* literal run */ + while (count++) + *out++ = *input++; + } + else + /* EOF */ + break; + } + + return (out - output); +} diff --git a/mware/rle.h b/mware/rle.h new file mode 100755 index 00000000..b23da7dd --- /dev/null +++ b/mware/rle.h @@ -0,0 +1,27 @@ +/*! + * \file + * + * + * \brief General-purpose run-length {en,de}coding algorithm (interface) + * + * \version $Id$ + * \author Bernardo Innocenti + */ + +/* + * $Log$ + * Revision 1.1 2004/08/04 02:35:54 bernie + * Import simple RLE algorithm. + * + */ +#ifndef RLE_H +#define RLE_H + +int rle(unsigned char *output, const unsigned char *input, int length); +int unrle(unsigned char *output, const unsigned char *input); + +#endif /* RLE_H */ -- 2.25.1