4 * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
5 * Copyright 1999, 2000, 2001 Bernardo Innocenti <bernie@develer.com>
6 * This file is part of DevLib - See devlib/README for information.
9 * \brief General-purpose run-length {en,de}coding algorithm (implementation)
11 * Original source code from http://www.compuphase.com/compress.htm
14 * \author Bernardo Innocenti <bernie@develer.com>
19 *#* Revision 1.2 2004/08/25 14:12:09 rasky
20 *#* Aggiornato il comment block dei log RCS
22 *#* Revision 1.1 2004/08/04 02:35:54 bernie
23 *#* Import simple RLE algorithm.
31 * Run-length encode \a len bytes from the \a input buffer
32 * to the \a output buffer.
34 int rle(unsigned char *output, const unsigned char *input, int len)
46 first = input[index++];
48 /* Scan for bytes identical to the first one */
49 while ((index < len) && (index - count < 127) && (input[index] == first))
52 if (index - count == 1)
54 /* Failed to "replicate" the current byte. See how many to copy.
56 while ((index < len) && (index - count < 127))
58 /* Avoid a replicate run of only 2-bytes after a literal run.
59 * There is no gain in this, and there is a risc of loss if the
60 * run after the two identical bytes is another literal run.
61 * So search for 3 identical bytes.
63 if ((input[index] == input[index - 1]) &&
64 ((index > 1) && (input[index] == input[index - 2])))
66 /* Reset the index so we can back up these three identical
67 * bytes in the next run.
76 /* Output a run of uncompressed bytes: write length and values */
77 *out++ = (unsigned char)(count - index);
78 for (i = count; i < index; i++)
83 /* Output a compressed run: write length and value */
84 *out++ = (unsigned char)(index - count);
91 /* Output EOF marker */
94 return (out - output);
99 * Run-length decode from the \a input buffer to the \a output
102 * \note The output buffer must be large enough to accomodate
103 * all decoded output.
105 int unrle(unsigned char *output, const unsigned char *input)
116 count = (signed char)*input++;
135 return (out - output);