АЛГОРИТМЫ СЖАТИЯ

ТеорияПрактикаКонтроль знанийДемонстрация
Содержание
Введение
Классификация
-Критерии оценки
-Надёжность и сложность
-Методы сжатия
-Методы кодирования
Сжатие без потерь
-RLE
-Семейство LZ
-LZ77
-LZSS
-LZ78
-LZW
-LZM
-LZB
-LZH
-LZC
-LZT
-LZMV
-LZJ
-LZFG
-Унарное кодирование
-Метод Хаффмана
-Арифметическое кодирование
-Вероятностное сжатие
-BWT
Сжатие с потерями
-Звук и видео
-Изображения
Алгоритмы сжатия с потерями
-JPEG
-JPEG2000
-Wavelet
-Фрактальный
Предметный указатель

RLE

Исходный код реализации алгоритма RLE (Visual C++) - скачать.

Алгоритм RLE - теория.

Исходный код реализации алгоритма RLE
// RLE.cpp 

#include <stdio.h> 
#include <memory.h>
#include <stdlib.h>

/* Коды ошибок */
#define NO_ERROR      0
#define BAD_FILE_NAME 1
#define BAD_ARGUMENT  2


#define FALSE 0
#define TRUE  1

/* входной и выходной файлы */
FILE *source_file, *dest_file;

/*
'byte_stored_status' равен 'TRUE'если байт
прочитан 'fgetc'или 'FALSE' если нет дейтвительного
байта, не прочитано и не содержится в 'val_byte_stored'
*/

int byte_stored_status=FALSE;
int val_byte_stored;


/* псевдопроцедуры */

#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))

#define write_array(array,byte_nb_to_write)\
	  ((void)fwrite((array),1,(byte_nb_to_write),dest_file))

#define write_block(byte,time_nb)\
  {
    unsigned char array_to_write[129];\
    (void)memset(array_to_write,(byte),(time_nb));\
    write_array(array_to_write,(time_nb));\
  }
//=========================================================
// Сжатие методом RLE
void rle1encoding()
{
 register unsigned char byte1, byte2, frame_size, array[129];

 if (!end_of_data())
 {
  byte1=read_byte();
  frame_size=1;
  if (!end_of_data())
  {
   byte2=read_byte();
   frame_size=2;
   do {
    if (byte1==byte2)
    {
     while ((!end_of_data())&&(byte1==byte2)
      &&(frame_size<129))
     {
      byte2=read_byte();
      frame_size++;
     }
     if (byte1==byte2) /* встретили
           последовательность
           одинаковых байт */
     {
      write_byte(126+frame_size);
      write_byte(byte1);
      if (!end_of_data())
      {
       byte1=read_byte();
       frame_size=1;
      }
      else frame_size=0;
     } else
     {
      write_byte(125+frame_size);
      write_byte(byte1);
      byte1=byte2;
      frame_size=1;
     }
     if (!end_of_data())
     {
      byte2=read_byte();
      frame_size=2;
     }
    } else /* подготовка массива для
        сравнений, в нем будут
        храниться все идентичные байты */
    {
     *array = byte1;
     array[1]=byte2;
     while ((!end_of_data())&&(array[frame_size-2]!=
      array[frame_size-1])&&(frame_size<128))
     {
      array[frame_size]=read_byte();
      frame_size++;
     }
     if (array[frame_size-2]==array[frame_size-1])
      /* встретилась ли последовательность из разных байт,
      следующих за одинаковыми? */
     { /* Да, тогда не считаем 2 последних байта */
      write_byte(frame_size-3);
      write_array(array,frame_size-2);
      byte1=array[frame_size-2];
      byte2=byte1;
      frame_size=2;
     } else
     {
      write_byte(frame_size-1);
      write_array(array,frame_size);
      if (end_of_data())
       frame_size=0;
      else {
       byte1=read_byte();
       if (end_of_data())
        frame_size=1;
       else {
        byte2=read_byte();
        frame_size=2;
       }
      }
     }
    }
   } while ((!end_of_data())||(frame_size>=2));
  }
  if (frame_size==1)
  {
   write_byte(0);
   write_byte(byte1);
  }
 }
} 
//---------------------------------------------------------
// Декомпрессия методом RLE
void rle1decoding()
{
 unsigned char header;
 register unsigned char i;

 while (!end_of_data())
 {
  header=read_byte();
  switch (header & 128)
  {
   case 0:
    if (!end_of_data())
     for (i=0;i<=header;i++)
      write_byte(read_byte());
    /* else INVALID FILE */
    break;
   case 128:
    if (!end_of_data())
     write_block(read_byte(),(header & 127)+2);
    /* else INVALID FILE */
  }
 }
}
//---------------------------------------------------------
// Вывод помощи о пользовании программой
void help()
{
 printf("RLE_01 e(encoding)|d(decoding) source target\n");
} 
//---------------------------------------------------------
// главная функция
int _tmain(int argc, _TCHAR* argv[])
{
 if (argc!=4)
 { 
  help();
  exit(BAD_ARGUMENT);
 }
 else if ( tolower(argv[1][0])!= 'e'
  && tolower(argv[1][0])!= 'd')
 {
  help();
  exit(BAD_ARGUMENT);
 }
 else if ((source_file=fopen(argv[2],"rb"))==NULL)
 {
  help();
  exit(BAD_FILE_NAME);
 }
 else if ((dest_file=fopen(argv[3],"wb"))==NULL)
 {
  help();
  exit(BAD_FILE_NAME);
 }
 else { 
  if (tolower(argv[1][0]) == 'e') rle1encoding();
  else rle1decoding();
  fclose(source_file);
  fclose(dest_file);
 }
 printf("Completed.\n");
 return (NO_ERROR); 
}


К cодержаниюВперёд
2006 All Rights Reserved