lib/rle.c

Go to the documentation of this file.
00001 /* rle - byte oriented run length encoding. 
00002  *
00003  * This file is copyright 2002 Jim Kent, but license is hereby
00004  * granted for all use - public, private or commercial. */
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 /* Count number of signed chars that are the same as first. */
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 /* Compress in to out.  Out should be at least inSize * 1.5. 
00026  * Returns compressed size. */
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 /* Uncompress in to out. */
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 

Generated on Tue Dec 25 18:39:31 2007 for blat by  doxygen 1.5.2