rle.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                           rle.cpp  -  description
00003                              -------------------
00004     begin                : Thu Dec 9 2004
00005     copyright            : (C) 2004 by VooDooMan
00006     email                : vdmfun@hotmail.com
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010 
00011 VooDoo cIRCle - an IRC (ro)bot
00012 Copyright (C) by http://www.chilkatsoft.com/ChilkatDx/ck_rle.htm
00013 Copyright (C) 2004 by Marian VooDooMan Meravy (vdmfun@hotmail.com)
00014                    (re-coded from object version)
00015 
00016 This program is free software; you can redistribute it and/or
00017 modify it under the terms of the GNU General Public License
00018 as published by the Free Software Foundation; either version 2
00019 of the License, or (at your option) any later version.
00020 
00021 This program is distributed in the hope that it will be useful,
00022 but WITHOUT ANY WARRANTY; without even the implied warranty of
00023 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00024 GNU General Public License for more details.
00025 
00026 You should have received a copy of the GNU General Public License
00027 along with this program; if not, write to the Free Software
00028 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00029 
00030 ****************************************************************************/
00031 
00032 /*!
00033     \file
00034     \brief Implements RLE compress algorithm
00035 */
00036 
00037 #include "params.h"
00038 
00039 /*!
00040     \author Unknown author on the net :)
00041     \brief Compresses the buffer with LRE alghorytm
00042     \param buf Buffer to compress
00043     \param len Length of the buffer
00044     \param compressedLen Returns compressed length
00045     \return Returns compressed buffer
00046 */
00047 unsigned char* rle_compress(unsigned char *buf, int len, int &compressedLen)
00048 {
00049     int i;
00050     // Make the output buffer bigger in case the compressed
00051     // data is actually larger!
00052     int outBufSize = len+(len*4)/3;
00053     unsigned char *out = new unsigned char[outBufSize];
00054     unsigned char *outPtr = out;
00055 
00056     unsigned char byte1;
00057     unsigned char byte2;
00058     unsigned char frame_size;
00059     unsigned char array[129];
00060 
00061     while (len)
00062     {
00063     byte1 = *buf;
00064     buf++;
00065     len--;
00066     frame_size = 1;
00067 
00068     if (len)
00069         {
00070         byte2 = *buf;
00071         buf++;
00072         len--;
00073             frame_size = 2;
00074             do 
00075         {
00076         if (byte1 == byte2)
00077                     { 
00078             while (len && (byte1 == byte2) && (frame_size < 129))
00079                         { 
00080             byte2 = *buf;
00081             buf++;
00082             len--;
00083                         frame_size++;
00084                         }
00085 
00086             if (byte1 == byte2)
00087             { 
00088             *outPtr = frame_size+126;
00089             outPtr++;
00090             *outPtr = byte1;
00091             outPtr++;
00092             if (len)
00093                 {
00094                 byte1=*buf;
00095                 buf++;
00096                 len--;
00097                 frame_size = 1;
00098                 }
00099             else
00100                 {
00101                 frame_size = 0;
00102                 }
00103                         }
00104             else  
00105                        { 
00106                *outPtr = 125+frame_size;
00107                outPtr++;
00108                *outPtr = byte1;
00109                outPtr++;
00110                byte1 = byte2;
00111                frame_size = 1;
00112                        }
00113 
00114             if (len)
00115             { 
00116             byte2 = *buf;
00117             buf++;
00118             len--;
00119             frame_size = 2;
00120             }
00121                     }
00122         else        /* Prepare the array of comparisons
00123                    where will be stored all the identical bytes */
00124             { 
00125             *array = byte1;
00126             array[1] = byte2;
00127             while (len && (array[frame_size-2] != array[frame_size-1]) && (frame_size  < 128))
00128             { 
00129             array[frame_size] = *buf;
00130             buf++;
00131             len--;
00132             frame_size++;
00133             }
00134 
00135             /* Do we meet a sequence of all different bytes followed by identical byte? */
00136                     if (array[frame_size-2] == array[frame_size-1])
00137             { 
00138             /* Yes, then don't count the two last bytes */
00139             *outPtr = frame_size-3;
00140             outPtr++;
00141 
00142             for (i=0; i<frame_size-2; i++)
00143                 {
00144                 *outPtr = array[i];
00145                 outPtr++;
00146                 }
00147 
00148             byte1 = array[frame_size-2];
00149             byte2 = byte1;
00150             frame_size = 2;
00151             }
00152                     else 
00153             {
00154             *outPtr = frame_size-1;
00155             outPtr++;
00156 
00157             for (i=0; i<frame_size; i++)
00158                 {
00159                 *outPtr = array[i];
00160                 outPtr++;
00161                 }
00162 
00163             if (!len)
00164                 {
00165                 frame_size = 0;
00166                 }
00167             else
00168                 {
00169                 byte1 = *buf;
00170                 buf++;
00171                 len--;
00172                 if (!len)
00173                 {
00174                 frame_size = 1;
00175                 }
00176                 else
00177                 {
00178                 byte2 = *buf;
00179                 buf++;
00180                 len--;
00181                 frame_size = 2;
00182                 }
00183                 }
00184             }
00185             }
00186         }
00187         while (len || (frame_size >= 2));
00188 
00189         if (frame_size == 1)
00190         {
00191         *outPtr = 0;
00192         outPtr++;
00193         *outPtr = byte1;
00194         outPtr++;
00195         }
00196         }
00197     }
00198 
00199     compressedLen = outPtr-out;
00200     return out;
00201 }
00202 
00203 /*!
00204     \author Unknown author on the net :)
00205     \brief De-compresses the buffer with LRE alghorytm
00206     \param buf Buffer to decompress
00207     \param len Length of the buffer
00208     \param out Output buffer
00209     \param uncompressLen Returns uncompressed length
00210     \return Returns zero for no error, -1 for buffer too short
00211     \retval 0 No error
00212     \retval -1 Buffer too short
00213 */
00214 int rle_decompress(unsigned char *buf, int len, unsigned char *out, int &uncompressLen)
00215 {
00216     unsigned char header;
00217     unsigned char *outPtr = out;
00218     unsigned char i;
00219     int outSize = 0;
00220 
00221     while (len)
00222     {
00223     header = *buf;
00224     buf++;
00225     len--;
00226 
00227     if (!(header & 128))
00228         {
00229         // There are header+1 different bytes.
00230         for (i=0; i<=header; i++)
00231         {
00232         if (outSize >= uncompressLen) return -1;
00233         *outPtr = *buf;
00234         outPtr++;
00235         outSize++;
00236         buf++;
00237         len--;
00238         }
00239         }
00240     else
00241         {
00242         const unsigned int n = (header & 127) + 2;
00243         for (i=0; i<n; i++)
00244         {
00245         if (outSize >= uncompressLen) return -1;
00246         *outPtr = *buf;
00247         outPtr++;
00248         outSize++;
00249         }
00250         buf++;
00251         len--;
00252         }
00253     }
00254 
00255     uncompressLen = outSize;
00256     return 0;
00257 }

Generated on Sun Jul 10 03:23:01 2005 for VooDoo cIRCle by doxygen 1.4.3

Hosted by SourceForge.net Logo