📄 codrle2.c
字号:
/* File: codrle2.c Author: David Bourgin Creation date: 1/2/94 Last update: 24/7/95 Purpose: Example of RLE type 2 encoding with a file source to compress.*/#include <stdio.h>/* For routines printf,fgetc,fputc and rewind */#include <memory.h>/* For routine memset */#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/* Global variables */FILE *source_file,*dest_file; /* Being that fgetc=EOF only after an access then 'byte_stored_status' is 'TRUE' if a byte has been stored by 'fgetc' or 'FALSE' if there's no valid byte not already read and not handled in 'val_byte_stored' */int byte_stored_status=FALSE;int val_byte_stored;/* Pseudo procedures */#define beginning_of_data() (byte_stored_status=FALSE,(void)rewind(source_file))#define end_of_data() (byte_stored_status?FALSE:!(byte_stored_status=((val_byte_stored=fgetc(source_file))!=EOF)))#define read_byte() (byte_stored_status?byte_stored_status=FALSE,(unsigned char)val_byte_stored:(unsigned char)fgetc(source_file))#define write_byte(byte) ((void)fputc((byte),dest_file))void rle2write_rep(header_byte,repeated_byte,repetition_number)/* Returned parameters: None Action: Writes in the output compression stream the encoding of 'repetition_number' times 'repeated_byte'. 'header_byte' is used as marker as defined in RLE 2 method Errors: An input/output error could disturb the running of the program*/unsigned char header_byte,repeated_byte;unsigned int repetition_number;{ if (repetition_number<4) if (repeated_byte==header_byte) { write_byte(header_byte); write_byte(repetition_number-1); } else { register unsigned int i; for (i=1;i<=repetition_number;i++) write_byte(repeated_byte); } else { write_byte(header_byte); write_byte(repetition_number-1); write_byte(repeated_byte); }}void rle2write_non_rep(header_byte,non_repeated_byte)/* Returned parameters: None Action: Writes in the output compression stream the encoding of 'non_repeated_byte' 'header_byte' is used as marker as defined in RLE 2 method Errors: An input/output error could disturb the running of the program*/unsigned char header_byte,non_repeated_byte;{ if (non_repeated_byte==header_byte) { write_byte(header_byte); write_byte(0); } else write_byte(non_repeated_byte);}void rle2encoding()/* Returned parameters: None Action: Compresses with RLE type 2 method all bytes read by the function read_byte Errors: An input/output error could disturb the running of the program*/{ unsigned char byte1,byte2,header_byte; unsigned int frame_size; register unsigned int i; unsigned long int lookup_table[256]; if (!end_of_data()) /* Is there at least a byte to analyze? */ { /* Sets up the occurrence numbers of all bytes to 0 */ (void)memset((char *)lookup_table,0,sizeof(lookup_table)); /* This is the same to fill 'lookup_table' to 0. It's fastest than to loop 256 times */ while (!end_of_data())/* Valids the occurrences in 'lookup_table' in regard to the data to compress */ { byte1=read_byte(); lookup_table[byte1]++; } header_byte=0; for (i=1;i<=255;i++) if (lookup_table[i]<lookup_table[header_byte]) header_byte=i; write_byte(header_byte); beginning_of_data(); /* New data analysis */ byte1=read_byte(); frame_size=1; if (!end_of_data()) /* Are there at least two bytes? */ { byte2=read_byte(); frame_size=2; do { /* Real beginning of the compression */ if (byte1==byte2) /* Do we meet only a sequence of identical bytes? */ { while ((!end_of_data())&&(byte1==byte2)&&(frame_size<256)) { byte2=read_byte(); frame_size++; } if (byte1==byte2) { rle2write_rep(header_byte,byte1,frame_size); if (!end_of_data()) { byte1=read_byte(); frame_size=1; } else frame_size=0; } else { rle2write_rep(header_byte,byte1,frame_size-1); byte1=byte2; frame_size=1; } } else { /* No, then don't handle the last byte */ rle2write_non_rep(header_byte,byte1); byte1=byte2; frame_size=1; } if (!end_of_data()) { byte2=read_byte(); frame_size=2; } } while ((!end_of_data())||(frame_size>=2)); } if (frame_size==1) /* Was there a last byte to analyze? */ rle2write_non_rep(header_byte,byte1); }}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 2 method\n"); printf("as given in 'La Video et Les Imprimantes sur PC'\n"); printf("\nUse: codrle2 source target\n"); printf("source: Name of the file to compress\n"); printf("target: Name of the compressed file\n");}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 { rle2encoding(); fclose(source_file); fclose(dest_file); } printf("Execution of codrle2 completed.\n"); return (NO_ERROR);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -