algorytm.org

Implementacja w C/C++

Baza Wiedzy
wersja offline serwisu przeznaczona na urządzenia z systemem Android
Darowizny
darowiznaWspomóż rozwój serwisu
Nagłówki RSS
Artykuły
Implementacje
Komentarze
Forum
Bookmarki






Sonda
Implementacji w jakim języku programowania poszukujesz?

Algorytm RLE (Run Length Encoding) - Implementacja w C/C++
Ocena użytkownikóww: *****  / 7
SłabyŚwietny
Nadesłany przez Tomasz Lubiński, 16 czerwca 2007 01:00
Kod przedstawiony poniżej przedstawia główną część rozwiązania problemu.
Pobierz pełne rozwiązanie.

Jeżeli nie odpowiada Ci sposób formatowania kodu przez autora skorzystaj z pretty printer'a i dostosuj go automatycznie do siebie.

rle.c:
// Kompresja RLE (Run Length Encoding)
// www.algorytm.org
// (c) 2007 by Tomasz Lubinski


#include "stdio.h"

/* kompresja RLE */
void compress(FILE *in, FILE *out)
{
   char cur, prev, tmp;
   unsigned char cnt = 0;
   int  cont;
   
   cont = fread(&cur, sizeof(char), 1, in);
   prev = cur + 1;
   while (cont == 1)
   {
      if (prev != cur)
      {
         if (cnt == 0)
         {
            /* znaki obok siebie rozne wrzuc do pliku wyjsciowego */
            fwrite(&cur, sizeof(char), 1, out);
         }
         else
         {
            /* skonczyla sie sekwencja powtarzajcych sie znakow */
            cnt--;
            fwrite(&prev, sizeof(char), 1, out);
            fwrite(&cnt, sizeof(char), 1, out);
            fwrite(&cur, sizeof(char), 1, out);            
            cnt = 0;
         }
      }
      else
      {
         /* liczbe powtarzajacych sie znakow zapisujemy na jednym bajcie
            wypisz sekwencje jezeli ma ona maksymalna dlugosc */         
         if (cnt == 255)
         {
            fwrite(&prev, sizeof(char), 1, out);
            fwrite(&cnt, sizeof(char), 1, out);
            cnt = 0;
            cont = fread(&cur, sizeof(char), 1, in);
            prev = cur + 1;
            continue;
         }
         else
         {
            /* licz powtarzajace sie znaki */         
            cnt++;  
         }
      }
      /* odczytaj kolejny znak z pliku wejsciowego */
      cont = fread(&tmp, sizeof(char), 1, in);
      if (cont == 1)
      {
         prev = cur;      
         cur = tmp;
      }
   }
   
   /* jezeli plik konczy sie sekwencja wypisz ja */
   if (prev == cur)
   {
      cnt--;
      fwrite(&prev, sizeof(char), 1, out);
      fwrite(&cnt, sizeof(char), 1, out);   
   }
}

/* dekompresja RLE */
void decompress(FILE *in, FILE *out)
{
   char cur, prev;
   unsigned char cnt = 0;
   int  cont, i;
   
   cont = fread(&cur, sizeof(char), 1, in);
   prev = cur + 1;
   while (cont == 1)
   {
      if (prev != cur)
      {
         /* znaki obok siebie rozne wrzuc do pliku wyjsciowego */
         fwrite(&cur, sizeof(char), 1, out);      
         prev = cur;
         /* odczytaj kolejny znak */         
         cont = fread(&cur, sizeof(char), 1, in);
      }   
      else
      {
         /* znaki obok siebie sa rowne - mamy sekwencje */
         /* odczytaj dlugosc sekwencji i wrzuc ja do pliku wyjsciowego */
         cont = fread(&cnt, sizeof(char), 1, in);
         for (i=0; i<=cnt; i++)
         {
            fwrite(&cur, sizeof(char), 1, out);
         }
         /* odczytaj kolejny znak */
         cont = fread(&cur, sizeof(char), 1, in);
         prev = cur + 1;         
      }
   }
}

/* pobierz dane od uzytkownika */
int main()
{
   int x;
   char inPath[1000];
   char outPath[1000];
   FILE *in, *out;
      
   printf("1 - kompresja\n");
   printf("2 - dekompresja\n");
   scanf("%d", &x);
   
   printf("Plik wejsciowy:\n");
   scanf("%s", inPath);
   
   printf("Plik wyjsciowy:\n");
   scanf("%s", outPath);   
   
   in = fopen(inPath, "rb");
   out = fopen(outPath, "wb");
   
   if (in == NULL){
      printf("Nie moge otworzyc pliku wejsciowego\n");
      return -1;
   }
   if (out == NULL){
      printf("Nie moge utworzyc pliku wyjsciowego\n");
      return -1;
   }   
   
   if (x == 1)
      compress(in, out);
   else
      decompress(in, out);
      
   fclose(in);
   fclose(out);

   return 0;
}
Dodaj komentarz