Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Алгоритмы > Алгоритм сжатия данных RLE


Автор: NEt_Hunter 24.7.2007, 11:48
Вопрос по поводу алгоритма сжатия данных RLE, опубликованный тут же по адресу http://forum.vingrad.ru/forum/topic-37776.html#st_15_view_0

Сам код:

Код

#include <stdio.h>
#include <string.h>
#include <errno.h>

void usage(void)
{

 printf("Sintaksis: compress.exe filename1 COMPRESS|DECOMPRESS filename2\n");
 printf("fayl1 - imya isxodnoqo fayla\n");
 printf("fayl2 - imya sjatoqo fayla\n");
 printf("\nNaprimer: compress.exe compress.bmp COMPRESS compress.rle\n");
}

FILE *input, *output;

void compress(void)
{
 unsigned char c1,c,length;
 unsigned long int rcounter=0,wcounter=0;

 fread(&c1,sizeof(char),1,input);
 do
 {
   c=c1;
   length=0;
   do
   {
     fread(&c1,sizeof(char),1,input);
     length++;
     rcounter++;
   } while (!feof(input) && c1==c && length!=255);

   fwrite(&c,sizeof(char),1,output);
   fwrite(&length,sizeof(char),1,output);
   wcounter++;
 } while (!feof(input));
 printf("%ld byte(s) sjato\n",rcounter);
 printf("ratio: %d\n",wcounter/rcounter);
}

void decompress(void)
{
 unsigned char c,length;
 unsigned long int rcounter=0,wcounter=0;

 fread(&c,sizeof(char),1,input);
 do
 {
   fread(&length,sizeof(char),1,input);
   for(int i=0;i<length;i++)
   {
     fwrite(&c,sizeof(char),1,output);
     wcounter++;
   }
   fread(&c,sizeof(char),1,input);
   rcounter+=2;
 } while (!feof(input));
 printf("%ld byte(s) rasjato\n",wcounter);
 printf("ratio: %d\n",wcounter/rcounter);
}

void main(int argc, char **argv)
{

 printf("Proqramma kompressii i dekompressii - Ayaz 684 R1\n\n");

 if (argc!=4)
 {
   usage();
   return;
 }
 if ((input=fopen(argv[1],"rb"))==NULL)
 {
   // Oshibka v otkritii fayla
   printf("! ERR03: can't open source file :(\n");
   return;
 };
 if ((output=fopen(argv[3],"wb"))==NULL)
 {
   // Oshibka v otkritii fayla
   fclose(input);
   printf("! ERR04: Ne udayetsa otkrit sjatiy fayl :(\n");
   return;
 };
 if (stricmp(argv[2],"COMPRESS")==0) compress();else
 if (stricmp(argv[2],"DECOMPRESS")==0) decompress();else
 {

   printf("! ERR02: Oshibka :)\n");
   fclose(input);
   fclose(output);
   return;
 }
 fclose(input);
 fclose(output);
}


Например, пусть задана такая последовательность данных, что подлежит сжатию: 
1 1 1 1 2 2 3 4 4 4 
В алгоритме RLE предлагается заменить ее следующей структурой: 1 4 2 2 3 1 4 3, где первое число каждой пары чисел - это код данных, а второе - коэффициент повторения. Проблема в том, что при сжатии этой прогой(код выше), эти коэффициенты повторения не видны, вместо них квадратиками или другие символы(нецифры), то есть 1 4 2 2 3 1 4 3 представляется как 1 символ 2 символ 3 символ 4 символ
Проблема в кодировке?

Автор: JackYF 24.7.2007, 13:37
Цитата(NEt_Hunter @  24.7.2007,  11:48 Найти цитируемый пост)
Проблема в кодировке? 

нет.

Количество повторений записывается в бинарном формате в виде одного байта.
Если число повторений было 3, то записывается байт со значением 3 (служебный символ, на экране не отобразишь).

Это сделано для облегчения кода и уменьшения размера файла, нам же архивацию надо делать, не так ли?
И программе-распаковщику будет легче считать один байт, чем разбирать строчное выражения и переводить в число.

Автор: NEt_Hunter 2.8.2007, 09:49
Все ясно, спасибо за пояснение!

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)