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 README.devlib 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.4 2006/07/19 12:56:28 bernie
20 *#* Convert to new Doxygen style.
22 *#* Revision 1.3 2005/11/04 16:20:02 bernie
23 *#* Fix reference to README.devlib in header.
25 *#* Revision 1.2 2004/08/25 14:12:09 rasky
26 *#* Aggiornato il comment block dei log RCS
28 *#* Revision 1.1 2004/08/04 02:35:54 bernie
29 *#* Import simple RLE algorithm.
37 * Run-length encode \a len bytes from the \a input buffer
38 * to the \a output buffer.
40 int rle(unsigned char *output, const unsigned char *input, int len)
52 first = input[index++];
54 /* Scan for bytes identical to the first one */
55 while ((index < len) && (index - count < 127) && (input[index] == first))
58 if (index - count == 1)
60 /* Failed to "replicate" the current byte. See how many to copy.
62 while ((index < len) && (index - count < 127))
64 /* Avoid a replicate run of only 2-bytes after a literal run.
65 * There is no gain in this, and there is a risc of loss if the
66 * run after the two identical bytes is another literal run.
67 * So search for 3 identical bytes.
69 if ((input[index] == input[index - 1]) &&
70 ((index > 1) && (input[index] == input[index - 2])))
72 /* Reset the index so we can back up these three identical
73 * bytes in the next run.
82 /* Output a run of uncompressed bytes: write length and values */
83 *out++ = (unsigned char)(count - index);
84 for (i = count; i < index; i++)
89 /* Output a compressed run: write length and value */
90 *out++ = (unsigned char)(index - count);
97 /* Output EOF marker */
100 return (out - output);
105 * Run-length decode from the \a input buffer to the \a output
108 * \note The output buffer must be large enough to accomodate
109 * all decoded output.
111 int unrle(unsigned char *output, const unsigned char *input)
122 count = (signed char)*input++;
141 return (out - output);