⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 codrle2.c

📁 著名压缩算法的实现
💻 C
字号:
/* Fichier: codrle2.c   Auteur: David Bourgin   Date de creation: 1/2/94   Date de derniere mise a jour: 24/7/95   Dessein: Exemple de codage RLE type 2 avec comme donnees a compresser le contenu d'un fichier.*/#include <stdio.h>/* Pour les routines printf,fgetc,fputc et rewind */#include <memory.h>/* Pour la routine memset */#include <stdlib.h>/* Pour la routine exit *//* Codes d'erreur renvoyes a l'appelant */#define NO_ERROR      0#define BAD_FILE_NAME 1#define BAD_ARGUMENT  2/* Constantes pratiques */#define FALSE 0#define TRUE  1/* Variables globales */FILE *f_source,*f_dest;                             /* Puisque fgetc=EOF uniquement apres un acces                                alors statut_octet_stocke vaut TRUE si un octet a ete engrange par fgetc                                ou FALSE s'il n'y aucun octet valide, deja lu et non traite dans val_octet_stocke */int statut_octet_stocke=FALSE;int val_octet_stocke;/* Pseudo procedures */#define debut_des_donnees()  (statut_octet_stocke=FALSE,(void)rewind(f_source))#define fin_des_donnees() (statut_octet_stocke?FALSE:!(statut_octet_stocke=((val_octet_stocke=fgetc(f_source))!=EOF)))#define lire_octet()  (statut_octet_stocke?statut_octet_stocke=FALSE,(unsigned char)val_octet_stocke:(unsigned char)fgetc(f_source))#define ecrire_octet(octet)  ((void)fputc((octet),f_dest))void ecrire_reprle2(octet_repere,octet_repete,nombre_repetition)/* Parametres en sortie: Aucun   Action: Ecrit dans le flux de sortie de compression le codage de nombre_repetition fois l'octet_repete.   octet_repere fait office de marqueur comme defini par la methode RLE 2   Erreurs: Une erreur d'entree/sortie peut perturber le deroulement de l'algorithme*/unsigned char octet_repere,octet_repete;unsigned int nombre_repetition;{ if (nombre_repetition<4)     if (octet_repete==octet_repere)        { ecrire_octet(octet_repere);          ecrire_octet(nombre_repetition-1);        }     else { register unsigned int i;            for (i=1;i<=nombre_repetition;i++)                ecrire_octet(octet_repete);          }  else { ecrire_octet(octet_repere);         ecrire_octet(nombre_repetition-1);         ecrire_octet(octet_repete);       }}void ecrire_non_reprle2(octet_repere,octet_non_repete)/* Parametres en sortie: Aucun   Action: Ecrit dans le flux de sortie de compression l'octet_non_repete   octet_repere fait office de marqueur comme defini par la methode RLE 2   Erreurs: Une erreur d'entree/sortie peut perturber le deroulement de l'algorithme*/unsigned char octet_repere,octet_non_repete;{ if (octet_non_repete==octet_repere)     { ecrire_octet(octet_repere);       ecrire_octet(0);     }  else ecrire_octet(octet_non_repete);}void codagerle2()/* Parametres en sortie: Aucun   Action: Compresse suivant la methode RLE type 2 tous les octets lus par la fonction lire_octet   Erreurs: Une erreur d'entree/sortie peut perturber le deroulement de l'algorithme*/{ unsigned char octet1,octet2,octet_repere;  unsigned int taille_trame;  register unsigned int i;  unsigned long int table_occurrences[256];  if (!fin_des_donnees())    /* Y a-t-il au moins 1 octet a analyser? */     {                       /* Initialiser le nombre d'occurrences de tous les octets a 0 */       (void)memset((char *)table_occurrences,0,sizeof(table_occurrences));                             /* Ceci equivaut a remplir table_occurrences de 0.                                C'est plus rapide que boucler 256 fois */                        /* Valider les occurrences de table_occurrences en fonction des donnees a compresser */       while (!fin_des_donnees())             { octet1=lire_octet();               table_occurrences[octet1]++;             }       octet_repere=0;       for (i=1;i<=255;i++)           if (table_occurrences[i]<table_occurrences[octet_repere])              octet_repere=i;       ecrire_octet(octet_repere);       debut_des_donnees();  /* Nouvelle analyse des donnees */       octet1=lire_octet();       taille_trame=1;       if (!fin_des_donnees())                             /* Y a-t-il au moins 2 octets a analyser? */          { octet2=lire_octet();            taille_trame=2;            do {             /* Debut de compression a proprement parle */                 if (octet1==octet2)                             /* N'a-t-on rencontre qu'une sequence d'octets identiques? */                    { while ((!fin_des_donnees())&&(octet1==octet2)&&(taille_trame<256))                            { octet2=lire_octet();                              taille_trame++;                            }                      if (octet1==octet2)                         { ecrire_reprle2(octet_repere,octet1,taille_trame);                           if (!fin_des_donnees())                              { octet1=lire_octet();                                taille_trame=1;                              }                           else taille_trame=0;                         }                      else { ecrire_reprle2(octet_repere,octet1,taille_trame-1);                             octet1=octet2;                             taille_trame=1;                           }                    }                 else {      /* Non, alors ne pas prendre en compte le dernier octet */                        ecrire_non_reprle2(octet_repere,octet1);                        octet1=octet2;                        taille_trame=1;                      }                 if (!fin_des_donnees())                    { octet2=lire_octet();                      taille_trame=2;                    }               }            while ((!fin_des_donnees())||(taille_trame>=2));          }       if (taille_trame==1)  /* Il restait un dernier octet a analyser */          ecrire_non_reprle2(octet_repere,octet1);     }}void aide()/* Parametres en sortie: Aucun   Action: Affiche l'aide du programme et termine son execution   Erreurs: Aucune*/{ printf("Cet utilitaire permet de compresser un fichier par la methode RLE type 2\n");  printf("telle qu'elle est exposee dans 'La Video et Les Imprimantes sur PC'\n");  printf("\nUsage: codrle2 source destination\n");  printf("source: Nom du fichier a compresser\n");  printf("destination: Nom du fichier compresse\n");}int main(argc,argv)/* Parametres en sortie: Renvoie un code d'erreur (0=Aucune)   Action: Procedure principale   Erreurs: Detectee, traitee et un code d'erreur est renvoye si necessaire*/int argc;char *argv[];{ if (argc!=3)     { aide();       exit(BAD_ARGUMENT);     }  else if ((f_source=fopen(argv[1],"rb"))==NULL)          { aide();            exit(BAD_FILE_NAME);          }       else if ((f_dest=fopen(argv[2],"wb"))==NULL)               { aide();                 exit(BAD_FILE_NAME);               }            else { codagerle2();                   fclose(f_source);                   fclose(f_dest);                 }  printf("Execution de codrle2 achevee.\n");  return (NO_ERROR);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -