Listing 4 (cujhuff3.c)

      /****************************************************
      *
      *        file d:\lsu\cujhuff3.c
      *
      ****************************************************/


#include "d:\lsu\cujhuff.h"


/*
         code_and_write_output_file(...

         Look at each byte in the input file.
         Code each byte using the item_array.coded.
         When the output buffer (packed bits) is on a byte
         boundary, then write it out to the output file
*/


code_and_write_output_file(item_array, in_file name,
                       out_file_name, file_header)
   char   in_file_name[],
         out_file_name[];
   struct item_struct item_array[];
   struct header_struct *file_header;
{
   char  in_buffer[IB_LENGTH],
        out_buffer[OB_LENGTH],
        r[80];

   int   coding,
        counter,
        in_file_desc,
        j,
        not_end_of_file,
        out_file_desc;

   long  bytes_read,
        bytes_written,
        i,
        in_counter,
        in_file_displacement,
        out_counter;


   open_files(in_file_name, out_file_name,
            &in_file_desc, &out_file_desc);

   lseek(in_file_desc, 0L, 0);
   file_header->in_file-length = lseek(in_file_desc, 0L, 2);
   lseek(in_file_desc, 0L, 0);

   output_file_header(file_header, out_file_desc);

   clear_input_buffer(in_buffer);
   clear_output_buffer(out_buffer);

   in_counter           = 0;
   out_counter          = 0;
   in_file_displacement = 0;
   not_end_of_file      = 1;
   counter              = 0;

   while(not_end_of_file){

      position_in_file_displacement(in_file_desc,
                               in_file_displacement);

      bytes_read = my_read(in_file_desc, in_buffer, IB_LENGTH);
/*printf("\n\t\tread %d bytes", bytes_read);*/

      if(bytes_read < IB_LENGTH)
         not_end_of_file = 0;

      i       = 0;
      coding  = 1;

        while(coding){

           if((counter % 100) == 0)
              printf("\n> Coding - counter=%d\n", counter);
           if((counter % 10) == 0)
              printf(".");
           counter++;
           code_byte(item_array, i, in_buffer, out_buffer,
                    &in_counter, &out_counter);
           i++;
/*printf("\n\n> in_counter=%ld out_counter=%ld\n",
in_counter, out_counter);*/

           /*************************************
           *
           *   The rest of this function looks
           *   at the output buffer and writes it
           *   out when the buffer is on a byte
           *   boundary.
           *
           *************************************/

          if( (out_counter/8 >= 100)         &&
              (out_counter % 8 == 0) ){
             printf("\n> Writing to output file");
/*printf("\n\t> out count = %d", out_counter/8);*/
             write_output(out_file_desc, out_buffer,
                                              out_counter/8);
             out_counter = 0;
             clear_output_buffer(out_buffer);
          }   /* ends if 100 bytes in out_buffer and on a byte
                 boundary */

          if(i == bytes_read){
             in_file_displacement = in_file_displacement + i;
             coding = 0;
          }   /* ends if the in_buffer is empty  */

       }   /* ends while coding */

   }    /* ends while not_end_of_file */

   printf("\n> Writing to output file");
   write_output(out_file_desc, out_buffer, out_counter/8);


   close(in_file_desc);
   close(out_file_desc);

}   /* ends code_and write_output_file */

/*
         open_files(...

         Open the input and output file.
*/

open_files(in_file_name, out_file_name, in_file_desc,
out_file_desc)
   char in_file_name[], out_file_name[];
   int        *in_file_desc, *out_file_desc;
{
   int a ,b;

   *out_file_desc = open(out_file_name, 0_RDWR | 0_CREAT |0_BINARY,
                      S_IWRITE);
   *in_file_desc  = open(in_file_name, 0_RDWR | 0_CREAT | 0_BINARY,
                      S_IWRITE);

}   /* ends open_files  */

/*
   output_file_header(...

   This function outputs the short file header
   to the beginning of the compressed file.

*/


output_file_header(file_header, out_file_desc)
   int    out_file_desc;
   struct header_struct *file_header;
{
       int     i;

       char    out_buffer[sizeof(struct header_struct)],
              *charptr,
              name[80];

       charptr = (char *)file_header;
       for(i=0; i<((sizeof(struct header_struct))); i++)
          out_buffer[i] = *charptr++;

       write_output(out_file_desc, out_buffer,
                  sizeof(struct header_struct));

}        /* ends output_item_array */


/*
         clear_input_buffer(in_buffer)

         This clears out the input buffer.
*/

clear_input_buffer(in_buffer)
   char in_buffer[];
{
   int i;
   for(i=0; i<IB_LENGTH; i++)
      in_buffer[i] = ' ';
}   /* ends clear_in_buffer */


/*
         clear_output_buffer(out_buffer)

         This clears out the output buffer.
*/

clear_output_buffer(out_buffer)
   char out_buffer[];
{
   int i;
   for(i=0; i<0B_LENGTH; i++)
       out_buffer[i] = 0x00;
}   /*  ends clear_out_buffer */


/*
         position_in_file_displacement(...

         This sets the pointer to the input file
         to the desired located specificied by
         in_file_discplacement.
*/

position_in_file_displacement(in_file_desc, in_file_displacement)
   int in_file_desc;
   long in_file_displacement;
{
   long position;
   position = lseek(in_file_desc, 0L, 0);
   position = lseek(in_file_desc, in_file_displacement, 0);

}   /*  ends position_in_file_displacement  */
/*
         code_byte(...

         This function looks at the input file byte and
         sets the bits in the output buffer.
*/

code_byte(item_array, byte, in_buffer, out_buffer, in_counter,
out_counter)
   char   in_buffer[], out_buffer[];
   long   byte;
   long   *in_counter, *out_counter;
   struct item_struct item_array[];
{
   char out_code[CODE_LENGTH];
   int  i;

   find_output_code(item_array, out_code, in_buffer[byte]);
   *in_counter = *in_counter + 1;

           /*****************************************
           *
           *   Set the output code to either ONE or
           *   ZERO.
           *
           ******************************************/

   for(i=0; i<CODE_LENGTH; i++){
      if(out_code[i] == ONE){
         set_bit_to_1(out_counter, out_buffer);
         *out_counter = *out_counter + 1;
      }  /* ends if out_code == ONE */

      if(out_code[i] == ZERO){
         clear_bit_to_0(out_counter, out_buffer);
         *out_counter = *out_counter + 1;
      }   /* ends if out_code == ZERO */
   }           /* ends loop over i             */
}            /* ends code_byte             */


/*

            find_output_code(...

            Search through the item_array to find the correct
            character and its code.
*/


find_output_code(item_array, out_code, in_character)
   struct item_struct item_array[];
   char out_code[];
   char in_character;
{
   int i, j, searching;

   i = 0;
   searching = 1;
   while(searching){
      if(item_array[i].character == in_character){
         searching = 0;
         for(j=0; j<CODE_LENGTH; j++){
            out_code[j] = item_array[i].coded[j];
         }   /* ends loop over j          */
      }       /* ends if there is a match  */
      else
         i++;
   }               /* ends while searching        */
}               /* ends find_output_code         */


/*
            set_bit_to_1(out_counter, out_buffer)

            This function sets the specified bit in the output

            buffer to a 1.
*/


set_bit_to_1(out_counter, out_buffer)
   long *out_counter;
   char out_buffer[];
{
   int  bit_in_byte,
       byte_in_buffer;
   char temp;
   bit_in_byte          = *out counter % 8;
   byte_in_buffer = *out_counter / 8;
   switch(bit_in_byte){ 
      case 0:
        temp = out_buffer[byte_in_buffer] | SET_BIT_ZERO;
        break;
      case 1:
        temp = out_buffer[byte_in_buffer] | SET_BIT_ONE;
        break;
      case 2:
        temp = out_buffer[byte_in_buffer] | SET_BIT_TWO;
        break;
      case 3:
        temp = out_buffer[byte_in_buffer] | SET_BIT_THREE;
        break;
      case 4:
        temp = out_buffer[byte_in_buffer] | SET_BIT_FOUR;
        break;
      case 5:
        temp = out_buffer[byte_in_buffer] | SET_BIT_FIVE;
        break;
      case 6:
        temp = out_buffer[byte_in_buffer] | SET_BIT_SIX;
        break;
      case 7:
        temp = out_buffer[byte_in_buffer] | SET_BIT_SEVEN;
        break;
   }  /* ends switch            */
   out_buffer[byte_in_buffer] = temp;
}      /* ends set_bit_to_1 */


/*
          clear_bit_to_0(out_counter, out_buffer)

          This function sets the specified bit in the
          output buffer to 0.
*/


clear_bit_to_0(out_counter, out_buffer)
   long *out_counter;
   char out_buffer[];
{
   int  bit_in_byte,
       byte_in_buffer;
   char temp;

   bit_in_byte = *out_counter % 8;
   byte_in_buffer = *out_counter / 8;

   switch(bit_in_byte){
      case 0:
        temp = out_buffer[byte_in_buffer] & CLEAR_BIT_ZERO;
        break;
      case 1:
        temp = out_buffer[byte_in_buffer] & CLEAR_BIT_ONE;
        break;
      case 2:
        temp = out_buffer[byte_in_buffer] & CLEAR_BIT_TWO;
        break;
      case 3:
        temp = out_buffer[byte_in_buffer] & CLEAR_BIT_THREE;
        break;
      case 4:
        temp = out_buffer[byte_in_buffer] & CLEAR_BIT_FOUR;
        break;
      case 5:
        temp = out_buffer[byte_in_buffer] & CLEAR_BIT_FIVE;
        break;
      case 6:
        temp = out_buffer[byte_in_buffer] & CLEAR_BIT_SIX;
        break;
      case 7:
        temp = out_buffer[byte_in_buffer] & CLEAR_BIT_SEVEN;
        break;
   }   /* ends switch */
   out_buffer[byte_in_buffer] = temp;
}   /* ends clear_bit_to_0 */

/*
         write_output(...

         This function writes the output buffer to the
         output file.
*/

write_output(out_file desc, out_buffer, number_of_bytes)
   char out_buffer[];
   int out_file_desc;
   long number_of_bytes;
{
   int bytes_written;

   bytes_written = write(out_file_desc, out_buffer,
number_of_bytes);
/*printf("\n> wrote %d bytes", bytes_written);*/

}  /* ends write_output  */

/* End of File */