Thread: Help with runlength coding

  1. #1
    Registered User
    Join Date
    Feb 2008
    Posts
    146

    Help with runlength coding

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <malloc.h>
    #include <assert.h>
    
    #define         INPUTFILENAME           "input.rle"
    #define         OUTPUTFILENAME          "output.rle"
    #define         TEMPFILENAME            "rle.tmp"
    
    FILE    *f;
    long     fsize;
    
    /////////////////////////////////
    //  Return file size in bytes  //
    /////////////////////////////////
    long filesize(FILE *f)
    {
      long pos, fsize;
    
      pos = ftell(f);
      fseek(f, 0L, SEEK_END);
      fsize = ftell(f);
      fseek(f, pos, SEEK_SET);
    
      return fsize;
    }
    
    /////////////////////////////////////////////////////////
    //  Read input file to memory to speed up compression  //
    /////////////////////////////////////////////////////////
    char *rle_readinputstream(char *inputstream)
    {
      char *stream;
    
      f = fopen(inputstream,"r+b");
      assert(f != NULL);
      fsize = filesize(f);
    
      stream = (char *)calloc(fsize, sizeof(char));
      assert(stream != NULL);
    
      fread(stream, fsize, 1, f);
      fclose(f);
    
      return stream;
    }
    
    ///////////////////////////////////////////////////////
    //  Encode input stream and write it to output file  //
    ///////////////////////////////////////////////////////
    void rle_encode(char *stream)
    {
      int   k;
      char  byte, freq;
    
      f = fopen(TEMPFILENAME,"w+b");
      assert(f != NULL);
    
      k = 0;
      while (k < fsize) {
        byte = stream[k];
        freq = 0;
    
        while (stream[k++] == byte && freq < 63) freq++;
        --k;
    
        if (freq == 1 && byte < 0xC0)
          fwrite(&byte, sizeof(byte), 1, f);
        else {
          freq |= 0xC0;
          fwrite(&freq, sizeof(char), 1, f);
          fwrite(&byte, sizeof(char), 1, f);
        }
    
      }
    
      fclose(f);
    
    }
    
    
    ///////////////////////////////////////////////////////
    //  Decode input stream and write it to output file  //
    ///////////////////////////////////////////////////////
    void rle_decode(char *stream)
    {
      int   k, l;
      char  byte, freq;
    
      f = fopen(OUTPUTFILENAME,"w+b");
      assert(f != NULL);
    
      k = 0;
      while (k < fsize) {
    
        byte = stream[k++];
    
        if ((byte & 0xC0) == 0xC0) {
          freq = byte & 0x3F;
          byte = stream[k++];
        }
        else freq = 1;
    
        for (l = 0; l < freq; l++)
          fwrite(&byte, sizeof(byte), 1, f);
    
    
      }
    
      fclose(f);
    }
    
    ////////////////////
    //  Main program  //
    ////////////////////
    void main()
    {
      char *stream;
    
      printf("RLE compression\n");
      printf("Copyright (c) 1997 by Matjaz Trtnik\n");
    
      stream = rle_readinputstream(INPUTFILENAME);
      rle_encode(stream);
    
      stream = rle_readinputstream(TEMPFILENAME);
      rle_decode(stream);
    }
    This code does runlength coding ...but as it uses 2 MSB's as indicator of counter it can only code .txt files...what should i do if Iwant to do it for any other type of data as well.


    Thanks,
    Edesign
    Last edited by edesign; 03-23-2008 at 11:53 AM.

  2. #2
    Registered User
    Join Date
    Feb 2008
    Posts
    146
    I thought of it and now I have decided to to make a buffer having information that this particular byte is count and rest is value..and mention this at the end of the file...for that I have modified the encode function as follows..writing all the data & then info...

    Code:
    void rle_encode(char *stream)
    {
      long int k;
      int *p;
      int j,cntf,i;
      char  byte, freq;
    
      f = fopen(TEMPFILENAME,"wb");
      assert(f != NULL);
    
      k = 0;
      i = 0;
      while (k < fsize) {
        byte = stream[k];
        freq = 0;
    	j=k;
    
    	while (stream[k++] == byte && freq < 255) {
    		freq++;
    	}
        --k;
    	if(freq>0)
    	{
    		p[cntf]=j;
    		cntf++;
    		fwrite(&freq, sizeof(char), 1, f);
    		fwrite(&byte, sizeof(char), 1, f);
    	}
    	else 
    	{
          fwrite(&byte, sizeof(byte), 1, f);
        }
    
      }
      for(int h=0;h<cntf;h++)
    	  fwrite(p[h],sizeof(p[h]),1,f);
      fwrite(&cntf,sizeof(cntf),1,f);
    
      fclose(f);
    }
    This is how I modified it for my purpose, p has to hold value of byte number which holds count & not data..but I don't know how I can do that...[because..int *p can't be used as I used it..but I don't know how I can accomplish this..]

    at last I have mentioned total no of bytes which holds info about byte numbers..so decoder can identify them
    Last edited by edesign; 03-23-2008 at 12:25 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 9
    Last Post: 03-20-2009, 05:22 PM
  2. Coding Guideline ....!!
    By imfeelingfortun in forum Tech Board
    Replies: 8
    Last Post: 10-08-2006, 07:09 AM
  3. Before Coding
    By cyberCLoWn in forum C++ Programming
    Replies: 16
    Last Post: 12-15-2003, 02:26 AM
  4. Coding Contest....
    By Koshare in forum A Brief History of Cprogramming.com
    Replies: 46
    Last Post: 10-14-2001, 04:32 PM