00001
00002
00003
00004
00005
00006 #include "common.h"
00007 #include "rle.h"
00008
00009 static char const rcsid[] = "$Id: rle.c,v 1.6 2005/05/10 00:50:16 markd Exp $";
00010
00011 static int countSameAsStart(signed char *s, int max)
00012
00013 {
00014 signed char v = *s;
00015 int i;
00016 if (max > 127)
00017 max = 127;
00018 for (i=1; i<max; ++i)
00019 if (s[i] != v)
00020 break;
00021 return i;
00022 }
00023
00024 int rleCompress(void *vIn, int inSize, signed char *out)
00025
00026
00027 {
00028 signed char *in = vIn;
00029 signed char *endIn = in + inSize;
00030 signed char *s = in, *d = out;
00031 signed char *uncStart = in;
00032 int uncSize, sameCount;
00033 int sizeLeft;
00034
00035 while ((sizeLeft = (endIn - s)) != 0)
00036 {
00037 sameCount = countSameAsStart(s, sizeLeft);
00038 uncSize = s - uncStart;
00039 if (sameCount >= 3)
00040 {
00041 int uncSize = s - uncStart;
00042 while (uncSize > 0)
00043 {
00044 int size = uncSize;
00045 if (size > 127) size = 127;
00046 *d++ = size;
00047 memcpy(d, uncStart, size);
00048 d += size;
00049 uncSize -= size;
00050 uncStart += size;
00051 }
00052 *d++ = -sameCount;
00053 *d++ = *s;
00054 s += sameCount;
00055 uncStart = s;
00056 }
00057 else
00058 s += sameCount;
00059 }
00060 uncSize = s - uncStart;
00061 while (uncSize > 0)
00062 {
00063 int size = uncSize;
00064 if (size > 127) size = 127;
00065 *d++ = size;
00066 memcpy(d, uncStart, size);
00067 d += size;
00068 uncSize -= size;
00069 uncStart += size;
00070 }
00071 return d - out;
00072 }
00073
00074 void rleUncompress(signed char *in, int inSize, void *vOut, int outSize)
00075
00076 {
00077 int count;
00078 signed char *out = vOut;
00079 signed char *endOut = out + outSize;
00080 #ifndef NDEBUG
00081 signed char *endIn = in + inSize;
00082 #endif
00083
00084 while (out < endOut)
00085 {
00086 count = *in++;
00087 if (count > 0)
00088 {
00089 memcpy(out, in, count);
00090 in += count;
00091 out += count;
00092 }
00093 else
00094 {
00095 count = -count;
00096 memset(out, *in++, count);
00097 out += count;
00098 }
00099
00100 }
00101 assert(out == endOut && in == endIn);
00102 }
00103