BeRTOS
|
00001 00041 #include "rle.h" 00042 00043 00048 int rle(unsigned char *output, const unsigned char *input, int len) 00049 { 00050 int count, index, i; 00051 unsigned char first; 00052 unsigned char *out; 00053 00054 00055 out = output; 00056 count = 0; 00057 while (count < len) 00058 { 00059 index = count; 00060 first = input[index++]; 00061 00062 /* Scan for bytes identical to the first one */ 00063 while ((index < len) && (index - count < 127) && (input[index] == first)) 00064 index++; 00065 00066 if (index - count == 1) 00067 { 00068 /* Failed to "replicate" the current byte. See how many to copy. 00069 */ 00070 while ((index < len) && (index - count < 127)) 00071 { 00072 /* Avoid a replicate run of only 2-bytes after a literal run. 00073 * There is no gain in this, and there is a risc of loss if the 00074 * run after the two identical bytes is another literal run. 00075 * So search for 3 identical bytes. 00076 */ 00077 if ((input[index] == input[index - 1]) && 00078 ((index > 1) && (input[index] == input[index - 2]))) 00079 { 00080 /* Reset the index so we can back up these three identical 00081 * bytes in the next run. 00082 */ 00083 index -= 2; 00084 break; 00085 } 00086 00087 index++; 00088 } 00089 00090 /* Output a run of uncompressed bytes: write length and values */ 00091 *out++ = (unsigned char)(count - index); 00092 for (i = count; i < index; i++) 00093 *out++ = input[i]; 00094 } 00095 else 00096 { 00097 /* Output a compressed run: write length and value */ 00098 *out++ = (unsigned char)(index - count); 00099 *out++ = first; 00100 } 00101 00102 count = index; 00103 } 00104 00105 /* Output EOF marker */ 00106 *out++ = 0; 00107 00108 return (out - output); 00109 } 00110 00111 00119 int unrle(unsigned char *output, const unsigned char *input) 00120 { 00121 signed char count; 00122 unsigned char *out; 00123 unsigned char value; 00124 00125 00126 out = output; 00127 00128 for (;;) 00129 { 00130 count = (signed char)*input++; 00131 if (count > 0) 00132 { 00133 /* replicate run */ 00134 value = *input++; 00135 while (count--) 00136 *out++ = value; 00137 } 00138 else if (count < 0) 00139 { 00140 /* literal run */ 00141 while (count++) 00142 *out++ = *input++; 00143 } 00144 else 00145 /* EOF */ 00146 break; 00147 } 00148 00149 return (out - output); 00150 }