home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / listings / v_10_02 / 1002064a < prev    next >
Text File  |  1991-12-12  |  11KB  |  460 lines

  1.  
  2.  
  3.       
  4.        /****************************************************
  5.        *
  6.        *       file d:\lsu\cujhuff3.c
  7.        *
  8.        ****************************************************/
  9.  
  10.  
  11. #include "d:\lsu\cujhuff.h"
  12.  
  13.  
  14.  
  15.  
  16. /*   
  17.           code_and_write_output_file(...
  18.  
  19.           Look at each byte in the input file.
  20.           Code each byte using the item_array.coded.
  21.           When the output buffer (packed bits) is on a byte
  22.           boundary, then write it out to the output file
  23. */
  24.  
  25.  
  26. code_and_write_output_file(item_array, in_file_name, 
  27.                            out_file_name, file_header)
  28.    char   in_file_name[],
  29.           out_file_name[];
  30.    struct item_struct item_array[];
  31.    struct header_struct *file_header;
  32. {
  33.    char  in_buffer[IB_LENGTH],
  34.          out_buffer[OB_LENGTH],
  35.          r[80];
  36.  
  37.    int   coding,
  38.          counter,
  39.          in_file_desc,
  40.          j,
  41.          not_end_of_file,
  42.          out_file_desc;
  43.  
  44.    long  bytes_read,
  45.          bytes_written,
  46.          i,
  47.          in_counter,
  48.          in_file_displacement,
  49.          out_counter;
  50.  
  51.  
  52.    open_files(in_file_name, out_file_name,
  53.               &in_file_desc, &out_file_desc);
  54.  
  55.    lseek(in_file_desc, 0L, 0);
  56.    file_header->in_file_length = lseek(in_file_desc, 0L, 2);
  57.    lseek(in_file_desc, 0L, 0);
  58.  
  59.    output_file_header(file_header, out_file_desc);
  60.  
  61.  
  62.    clear_input_buffer(in_buffer);
  63.    clear_output_buffer(out_buffer);
  64.  
  65.    in_counter           = 0;
  66.    out_counter          = 0;
  67.    in_file_displacement = 0;
  68.    not_end_of_file      = 1;
  69.    counter              = 0;
  70.  
  71.    while(not_end_of_file){
  72.  
  73.       position_in_file_displacement(in_file_desc,
  74.                                     in_file_displacement);
  75.  
  76.       bytes_read = my_read(in_file_desc, in_buffer, IB_LENGTH);
  77. /*printf("\n\t\tread %d bytes", bytes_read);*/
  78.  
  79.       if(bytes_read < IB_LENGTH)
  80.          not_end_of_file = 0;
  81.  
  82.       i       = 0;
  83.       coding  = 1;
  84.  
  85.          while(coding){
  86.  
  87.             if((counter % 100) == 0)
  88.                printf("\n> Coding - counter=%d\n", counter);
  89.             if((counter % 10) == 0)
  90.                printf(".");
  91.             counter++;
  92.             code_byte(item_array, i, in_buffer, out_buffer,
  93.                       &in_counter, &out_counter);
  94.             i++;
  95. /*printf("\n\n> in_counter=%ld out_counter=%ld\n", 
  96. in_counter, out_counter);*/
  97.                           
  98.                          /**************************************
  99.                          *
  100.                          *   The rest of this function looks
  101.                          *   at the output buffer and writes it
  102.                          *   out when the buffer is on a byte
  103.                          *   boundary.
  104.                          *
  105.                          ***************************************/
  106.  
  107.             if( (out_counter/8 >= 100)           &&
  108.                 (out_counter % 8 == 0) ){
  109.                printf("\n> Writing to output file");
  110. /*printf("\n\t> out count = %d", out_counter/8);*/
  111.                write_output(out_file_desc, out_buffer,
  112. out_counter/8);
  113.                out_counter = 0;
  114.                clear_output_buffer(out_buffer);
  115.             }  /* ends if 100 bytes in out_buffer and on a byte
  116. boundary */
  117.  
  118.             if(i == bytes_read){
  119.                in_file_displacement = in_file_displacement + i;
  120.                coding = 0;
  121.  
  122.             }  /* ends if the in_buffer is empty  */
  123.  
  124.          }  /* ends while coding  */
  125.  
  126.    }  /*  ends while not_end_of_file  */
  127.  
  128.    printf("\n> Writing to output file");
  129.    write_output(out_file_desc, out_buffer, out_counter/8);
  130.  
  131.    close(in_file_desc);
  132.    close(out_file_desc);
  133.  
  134. }  /* ends code_and_write_output_file  */
  135.  
  136.  
  137.  
  138.  
  139.  
  140. /*    
  141.          open_files(...
  142.  
  143.          Open the input and output file.
  144. */
  145.  
  146. open_files(in_file_name, out_file_name, in_file_desc,
  147. out_file_desc)
  148.    char in_file_name[], out_file_name[];
  149.    int        *in_file_desc, *out_file_desc;
  150. {
  151.    int a ,b;
  152.  
  153.    *out_file_desc = open(out_file_name, O_RDWR | O_CREAT |
  154. O_BINARY,
  155.                          S_IWRITE);
  156.    *in_file_desc  = open(in_file_name, O_RDWR | O_CREAT | O_BINARY,
  157.                          S_IWRITE);
  158.  
  159. }  /*  ends open_files        */
  160.  
  161.  
  162.  
  163.  
  164.  
  165.  
  166. /*
  167.    output_file_header(...
  168.  
  169.    This function outputs the short file header
  170.    to the beginning of the compressed file.
  171.  
  172. */
  173.  
  174.  
  175. output_file_header(file_header, out_file_desc)
  176.    int    out_file_desc;
  177.    struct header_struct *file_header;
  178. {
  179.         int     i;
  180.  
  181.         char    out_buffer[sizeof(struct header_struct)],
  182.  
  183.                 *charptr,
  184.                 name[80];
  185.  
  186.         charptr = (char *)file_header;
  187.         for(i=0; i<((sizeof(struct header_struct))); i++)
  188.            out_buffer[i] = *charptr++;
  189.  
  190.         write_output(out_file_desc, out_buffer, 
  191.                      sizeof(struct header_struct));
  192.  
  193. }       /* ends output_item_array  */
  194.  
  195.  
  196.  
  197.  
  198.  
  199. /*    
  200.          clear_input_buffer(in_buffer)
  201.  
  202.          This clears out the input buffer.
  203. */
  204.  
  205. clear_input_buffer(in_buffer)
  206.    char in_buffer[];
  207. {
  208.    int i;
  209.    for(i=0; i<IB_LENGTH; i++)
  210.       in_buffer[i] = ' ';
  211. }  /* ends clear_in_buffer  */
  212.  
  213.  
  214.  
  215.  
  216. /*    
  217.          clear_output_buffer(out_buffer)
  218.  
  219.          This clears out the output buffer.
  220. */
  221.  
  222. clear_output_buffer(out_buffer)
  223.    char out_buffer[];
  224. {
  225.    int i;
  226.    for(i=0; i<OB_LENGTH; i++)
  227.       out_buffer[i] = 0x00;
  228. }  /*  ends clear_out_buffer  */
  229.  
  230.  
  231.  
  232.  
  233.  
  234.  
  235. /*    
  236.           position_in_file_displacement(...
  237.  
  238.           This sets the pointer to the input file
  239.           to the desired located specificied by
  240.           in_file_discplacement.
  241. */
  242.  
  243.  
  244. position_in_file_displacement(in_file_desc, in_file_displacement)
  245.    int  in_file_desc;
  246.    long in_file_displacement;
  247. {
  248.    long position;
  249.    position = lseek(in_file_desc, 0L, 0);
  250.    position = lseek(in_file_desc, in_file_displacement, 0);
  251.  
  252. }  /*  ends position_in_file_displacement  */
  253.  
  254.  
  255.  
  256.  
  257. /*    
  258.          code_byte(...
  259.  
  260.          This function looks at the input file byte and
  261.          sets the bits in the output buffer.
  262. */
  263.  
  264. code_byte(item_array, byte, in_buffer, out_buffer, in_counter,
  265. out_counter)
  266.    char   in_buffer[], out_buffer[];
  267.    long   byte;
  268.    long   *in_counter, *out_counter;
  269.    struct item_struct item_array[];
  270. {
  271.    char out_code[CODE_LENGTH];
  272.    int  i;
  273.  
  274.    find_output_code(item_array, out_code, in_buffer[byte]);
  275.    *in_counter = *in_counter + 1;
  276.  
  277.             /*****************************************
  278.             *
  279.             *   Set the output code to either ONE or
  280.             *   ZERO.
  281.             *
  282.             ******************************************/
  283.  
  284.    for(i=0; i<CODE_LENGTH; i++){
  285.       if(out_code[i] == ONE){
  286.          set_bit_to_1(out_counter, out_buffer);
  287.          *out_counter = *out_counter + 1;
  288.       }  /* ends if out_code == ONE */
  289.  
  290.       if(out_code[i] == ZERO){
  291.          clear_bit_to_0(out_counter, out_buffer);
  292.          *out_counter = *out_counter + 1;
  293.       }  /* ends if out_code == ZERO */
  294.    }         /* ends loop over i             */
  295. }         /*  ends code_byte             */
  296.  
  297.  
  298.  
  299.  
  300. /*   
  301.            find_output_code(...
  302.  
  303.            Search through the item_array to find the correct
  304.  
  305.            character and its code.
  306. */
  307.  
  308.  
  309. find_output_code(item_array, out_code, in_character)
  310.    struct item_struct item_array[];
  311.    char   out_code[];
  312.    char   in_character;
  313. {
  314.    int i, j, searching;
  315.  
  316.    i = 0;
  317.    searching = 1;
  318.    while(searching){
  319.       if(item_array[i].character == in_character){
  320.          searching = 0;
  321.          for(j=0; j<CODE_LENGTH; j++){
  322.             out_code[j] = item_array[i].coded[j];
  323.          }  /* ends loop over j          */
  324.       }     /* ends if there is a match  */
  325.       else
  326.          i++;
  327.    }            /* ends while searching         */
  328. }            /* ends find_output_code         */
  329.  
  330.  
  331.  
  332.  
  333. /*   
  334.            set_bit_to_1(out_counter, out_buffer)
  335.  
  336.            This function sets the specified bit in the output
  337.            buffer to a 1.
  338. */
  339.  
  340.  
  341. set_bit_to_1(out_counter, out_buffer)
  342.    long *out_counter;
  343.    char out_buffer[];
  344. {
  345.    int  bit_in_byte,
  346.         byte_in_buffer;
  347.    char temp;
  348.    bit_in_byte          = *out_counter % 8;
  349.    byte_in_buffer = *out_counter / 8;
  350.    switch(bit_in_byte){
  351.       case 0:
  352.         temp = out_buffer[byte_in_buffer] | SET_BIT_ZERO;
  353.         break;
  354.       case 1:
  355.         temp = out_buffer[byte_in_buffer] | SET_BIT_ONE;
  356.         break;
  357.       case 2:
  358.         temp = out_buffer[byte_in_buffer] | SET_BIT_TWO;
  359.         break;
  360.       case 3:
  361.         temp = out_buffer[byte_in_buffer] | SET_BIT_THREE;
  362.         break;
  363.       case 4:
  364.         temp = out_buffer[byte_in_buffer] | SET_BIT_FOUR;
  365.  
  366.         break;
  367.       case 5:
  368.         temp = out_buffer[byte_in_buffer] | SET_BIT_FIVE;
  369.         break;
  370.       case 6:
  371.         temp = out_buffer[byte_in_buffer] | SET_BIT_SIX;
  372.         break;
  373.       case 7:
  374.         temp = out_buffer[byte_in_buffer] | SET_BIT_SEVEN;
  375.         break;
  376.    }  /* ends switch           */
  377.    out_buffer[byte_in_buffer] = temp;
  378. }     /* ends set_bit_to_1 */
  379.  
  380.  
  381.  
  382.  
  383.  
  384.  
  385. /*  
  386.            clear_bit_to_0(out_counter, out_buffer)
  387.  
  388.            This function sets the specified bit in the
  389.            output buffer to 0.
  390. */
  391.  
  392.  
  393. clear_bit_to_0(out_counter, out_buffer)
  394.    long *out_counter;
  395.    char out_buffer[];
  396. {
  397.    int  bit_in_byte,
  398.         byte_in_buffer;
  399.    char temp;
  400.  
  401.    bit_in_byte    = *out_counter % 8;
  402.    byte_in_buffer = *out_counter / 8;
  403.  
  404.    switch(bit_in_byte){
  405.       case 0:
  406.         temp = out_buffer[byte_in_buffer] & CLEAR_BIT_ZERO;
  407.         break;
  408.       case 1:
  409.         temp = out_buffer[byte_in_buffer] & CLEAR_BIT_ONE;
  410.         break;
  411.       case 2:
  412.         temp = out_buffer[byte_in_buffer] & CLEAR_BIT_TWO;
  413.         break;
  414.       case 3:
  415.         temp = out_buffer[byte_in_buffer] & CLEAR_BIT_THREE;
  416.         break;
  417.       case 4:
  418.         temp = out_buffer[byte_in_buffer] & CLEAR_BIT_FOUR;
  419.         break;
  420.       case 5:
  421.         temp = out_buffer[byte_in_buffer] & CLEAR_BIT_FIVE;
  422.         break;
  423.       case 6:
  424.         temp = out_buffer[byte_in_buffer] & CLEAR_BIT_SIX;
  425.         break;
  426.  
  427.       case 7:
  428.         temp = out_buffer[byte_in_buffer] & CLEAR_BIT_SEVEN;
  429.         break;
  430.    }  /* ends switch */
  431.    out_buffer[byte_in_buffer] = temp;
  432. }  /* ends clear_bit_to_0 */
  433.  
  434.  
  435.  
  436.  
  437.  
  438.  
  439.  
  440. /*    
  441.           write_output(...
  442.  
  443.           This function writes the output buffer to the
  444.           output file.
  445. */
  446.  
  447. write_output(out_file_desc, out_buffer, number_of_bytes)
  448.    char out_buffer[];
  449.    int  out_file_desc;
  450.    long number_of_bytes;
  451. {
  452.    int bytes_written;
  453.  
  454.    bytes_written = write(out_file_desc, out_buffer,
  455. number_of_bytes);
  456. /*printf("\n> wrote %d bytes", bytes_written);*/
  457.  
  458. }  /*  ends write_output  */
  459. /* End of File */
  460.