RLE code needs to accept array input 
Author Message
 RLE code needs to accept array input

Here's a little RLE compression code in C (obviously).  I'm trying to get it
to accept input from an array of unsigned chars rather than a disk file but
I'm lost.  Perhaps someone would care to help me puzzle it out.
The data input point seems to be load_block( ) or perhaps fill_block( ).
The code was downloaded from http://www.*-*-*.com/
is freeware/pub domain.  I have tried to contact Mr. Bourgin but, so far, no
luck.
I really appreciate suggestions but a working code example would really make
my day...
Thanks,
Roger

/* File: codrle4.c
   Author: David Bourgin
   Creation date: 1/2/94
   Last update: 24/7/95
   Purpose: Example of RLE type 4 encoding with a file source to compress.
*/

#include <stdio.h>
/* For routines printf,fputc,fread and fwrite */
#include <memory.h>
/* For routine memcpy */
#include <stdlib.h>
/* For routine exit */

/* Error codes sent to the caller */
#define NO_ERROR      0
#define BAD_FILE_NAME 1
#define BAD_ARGUMENT  2

/* Useful constants */
#define FALSE 0
#define TRUE  1

#define MAX_FRAME_SIZE 65

/* Global variables */
FILE *source_file,*dest_file;

unsigned int index=0,
             buffer_read_size=0;
unsigned char buffer_read[8224+2*65];

typedef struct { unsigned int array_size;
                 unsigned char *array_val;
               } t_tab;
#define ARRAY_SIZE(array)  ((array).array_size)
#define ARRAY_VAL(array)  ((array).array_val)
#define ARE_EQUAL(array1,array2)
((ARRAY_SIZE(array1)==ARRAY_SIZE(array2))&&(!memcmp(ARRAY_VAL(array1),ARRAY_
VAL(array2),ARRAY_SIZE(array1))))

/* Pseudo procedures */
#define load_block()  {
buffer_read_size=fread(buffer_read,1,sizeof(buffer_read),source_file);
index=0; }
#define move_index(i)  (index=(i))
#define size_remaining_to_read()  (buffer_read_size-index)
#define read_array(array,nb_to_read)  { ARRAY_SIZE(array)=(nb_to_read);\
                                        ARRAY_VAL(array)=
&(buffer_read[index]);\
                                        index += (nb_to_read);\
                                      }
#define write_byte(x)  ((void)fputc((unsigned char)(x),dest_file))
#define write_word(x)  { write_byte((x) >> 8); write_byte((x) & 0xFF); }
#define write_array(array)
((void)fwrite(ARRAY_VAL(array),1,ARRAY_SIZE(array),dest_file))
#define fill_block()  {
(void)memcpy(buffer_read,&(buffer_read[index]),size_remaining_to_read());\

buffer_read_size=fread(&(buffer_read[size_remaining_to_read()]),1,sizeof(buf
fer_read)-size_remaining_to_read(),source_file)+size_remaining_to_read();\
                        index=0;\
                      }

void rle4look_for_occurr(basic_index,frame_nb,frame_size,
                         repetition_ok)
/* Returned parameters: 'frame_nb', 'frame_size' and 'repetition_ok' are
modified
   Action: Looks in the byte buffer if there's a frame repetition from
'basic_index' position
   where size and repetition are respectively in 'frame_size' and
'frame_nb'.
   Whenever a repetition is met, 'repetition_ok' returns 'TRUE' otherwise
'repetition_ok' returns 'FALSE'
   Errors: Whenever there are no multiple frames then 'frame_nb' won't be
modified
*/
unsigned int basic_index,*frame_nb,*frame_size;
int *repetition_ok;
{ int array_equality;
  t_tab array1,array2;

  *frame_size=1;
  *repetition_ok=FALSE;
  move_index(basic_index);
  while
((*frame_size<=MAX_FRAME_SIZE)&&(size_remaining_to_read()>=(*frame_size <<
1))&&(!*repetition_ok))
        { read_array(array1,*frame_size);
          read_array(array2,*frame_size);
          if (array_equality=ARE_EQUAL(array1,array2))
             { *frame_nb=2;
               while ((size_remaining_to_read()>=*frame_size)

&&(((*frame_nb<16449)&&(*frame_size==1))||((*frame_nb<257)&&(*frame_size>1))
)
                      &&(array_equality))
                     { if ((*frame_size>2)||(*frame_nb>2))
                          { if (*repetition_ok)
                               move_index(*frame_size);
                            else { *repetition_ok=TRUE;
                                   if (basic_index)
                                      return;
                                   move_index((*frame_nb-1)*(*frame_size));
                                 }
                            fill_block();
                            move_index(*frame_size);
                          }
                       read_array(array2,*frame_size);
                       if (array_equality=ARE_EQUAL(array1,array2))
                          (*frame_nb)++;
                     }
               if ((*frame_size>2)||(*frame_nb>2))
                  { if (basic_index)
                       { *repetition_ok=TRUE;
                         return;
                       }
                    if (*repetition_ok)
                       {  if (array_equality)
                             { move_index(*frame_size);
                               fill_block();
                             }
                       }
                    else { *repetition_ok=TRUE;
                           move_index((*frame_nb-1)*(*frame_size));
                           fill_block();
                         }
                    (*frame_size)--;
                  }
                             /* Specifies to the caller there was a
repetition */
             }
          (*frame_size)++;
          move_index(basic_index);
        }

Quote:
}

void rle4encoding()
/* Returned parameters: None
   Action: Compresses with RLE type 4 method all bytes read by the function
read_byte
   Errors: An input/output error could disturb the running of the program
*/
{ t_tab frame;
  unsigned int frame_nb1,frame_size1,frame_nb2,frame_size2;
  int repetition_valid;

  load_block();
  while (size_remaining_to_read())
        { rle4look_for_occurr(0,&frame_nb1,&frame_size1,&repetition_valid);
          if (repetition_valid)
                             /* Was there a repetition? */
             { if (frame_size1==1)
                             /* Frame of 1 byte? */
                  { if (frame_nb1<66)
                             /* Frame with a byte but less than 66 times? */
                       write_byte(frame_nb1-2);
                    else write_word(frame_nb1+16318);
                  }
               else {        /* Frame with several bytes */
                      write_byte(frame_size1+126);
                      write_byte(frame_nb1-2);
                    }
             }
          else { frame_size1=0;
                 do {        /* Tests until where there's no repetition */
                      frame_size1++;

rle4look_for_occurr(frame_size1,&frame_nb2,&frame_size2,&repetition_valid);
                    }
                 while
((size_remaining_to_read())&&(frame_size1<8224)&&(!repetition_valid));
                 if (frame_size1<33)
                             /* Non repetition of a frame with less than 33
Bytes */
                    write_byte(frame_size1+191);
                 else write_word(frame_size1+57311);
               }
          move_index(0);
          read_array(frame,frame_size1);
          write_array(frame);
          fill_block();      /* All new analysis must start at 0 in the
buffer */
        }

Quote:
}

void help()
/* Returned parameters: None
   Action: Displays the help of the program and then stops its running
   Errors: None
*/
{ printf("This utility enables you to compress a file by using RLE type 4
method\n");
  printf("as given in 'La Video et Les Imprimantes sur PC'\n");
  printf("\nUse: codrle4 source target\n");
  printf("source: Name of the file to compress\n");
  printf("target: Name of the compressed file\n");

Quote:
}

int main(argc,argv)
/* Returned parameters: Returns an error code (0=None)
   Action: Main procedure
   Errors: Detected, handled and an error code is returned, if any
*/
int argc;
char *argv[];
{ if (argc!=3)
     { help();
       exit(BAD_ARGUMENT);
     }
  else if ((source_file=fopen(argv[1],"rb"))==NULL)
          { help();
            exit(BAD_FILE_NAME);
          }
       else if ((dest_file=fopen(argv[2],"wb"))==NULL)
               { help();
                 exit(BAD_FILE_NAME);
               }
            else { rle4encoding();
                   fclose(source_file);
                   fclose(dest_file);
                 }
  printf("Execution of codrle4 completed.\n");
  return (NO_ERROR);
Quote:
}



Tue, 01 Apr 2003 08:48:20 GMT  
 RLE code needs to accept array input

wrote in comp.lang.c:

Quote:
> Here's a little RLE compression code in C (obviously).  I'm trying to get it
> to accept input from an array of unsigned chars rather than a disk file but
> I'm lost.  Perhaps someone would care to help me puzzle it out.
> The data input point seems to be load_block( ) or perhaps fill_block( ).
> The code was downloaded from http://dogma.net/DataCompression/RLE.shtml and
> is freeware/pub domain.  I have tried to contact Mr. Bourgin but, so far, no
> luck.
> I really appreciate suggestions but a working code example would really make
> my day...
> Thanks,
> Roger

        [snip]

Ugh, this code is so heavily macro'ed as to be difficult to read.

See the encode.c file from my chapter of the book, C Unleashed, which
you can find at this location:

http://home.att.net/~jackklein/C_Unleashed/code_list.html

Jack Klein
--
Home: http://jackklein.home.att.net



Tue, 01 Apr 2003 13:30:30 GMT  
 RLE code needs to accept array input


Quote:

> Here's a little RLE compression code in C (obviously).  I'm trying to
> get it to accept input from an array of unsigned chars rather than a
> disk file but I'm lost.  Perhaps someone would care to help me puzzle
> it out. The data input point seems to be load_block( ) or perhaps
> fill_block( ).
> The code was downloaded from
>            http://dogma.net/DataCompression/RLE.shtml and
> is freeware/pub domain.  I have tried to contact Mr. Bourgin but, so
> far, no luck. I really appreciate suggestions but a working code
> example would really make my day...

> /* File: codrle4.c
>    Author: David Bourgin
>    Creation date: 1/2/94
>    Last update: 24/7/95
>    Purpose: Example of RLE type 4 encoding with a file source to
compress.
> */

> #include <stdio.h>
> /* For routines printf,fputc,fread and fwrite */
> #include <memory.h>
> /* For routine memcpy */

non-standard header. Should be string.h

<massive snip>

I can't be bothered to wade through this but I note that the data input
seems to be via fread(). Replace fread() with something that has a
similar external interface.

typedef struct
{
    char *start;
    char *curr;  /* start of next read */
    int length;

Quote:
} MFILE;

/* copy data from the memory based stream MFILE to ptr */
int mread (char *ptr, unsigned element_size, int count, MFILE *stream);

or if you can disentangle the code replace the fread() target with a
simple pointer and replace the fread() call with an assignment of that
pointer to the memory to be operated on. The second is slightly more
dogy as there is more one fread() call. I suspect one of them is
designed just to get more data when the algorithm runs out halfway
through.

--
"Beware of bugs in the above code; I have only proved it correct,
not tried it."
                      Donald Knuth

Sent via Deja.com http://www.deja.com/
Before you buy.



Tue, 01 Apr 2003 03:00:00 GMT  
 
 [ 3 post ] 

 Relevant Pages 

1. RLE compression code needed

2. Need Grid Control that accepts user inputs (like spreadsheet)

3. Need DIB RLE Specs, please help

4. Please Help: Accepting Characters as Input

5. Accepting input as a password from Console in C#

6. Please Help: Accepting Characters as Input

7. How to write a C/C++ program that can accept input from a pipe

8. Some Expert level complications, Re: To accept input from PIPE by a program

9. To accept input from PIPE by a program

10. Accepting input from cursor keys...

11. Accepting input from cursor keys...

12. Can compiler accept c-source from standard input?

 

 
Powered by phpBB® Forum Software