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

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

LZSS

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

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

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

#include "stdafx.h"
#include <stdio.h>

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

typedef unsigned char uchar;
typedef unsigned int uint;


// параметры LZSS компрессора/декомпрессора

#define N 4096 /* размер кольцевого буфера */
#define F 128 /* размер просматриваемого буфера */
#define THRESHOLD 3 /* minimum match length */

#define N_BITS 12 /* log<2>N */
#define F_BITS 7 /* log<2>F */

uchar ring_buff[N+F]; /* кольцевой буфер */
uint next[N+1+4096], prev[N+1]; /* reserve space for hash as sons */
uint match_pos, match_len; /* match length & position */

//=========================================================
/*      I/O     */

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

static unsigned long int o_bitbuffer;
static unsigned int o_bitcount;
//---------------------------------------------------------
// функции битового вывода
void send_reset() { o_bitbuffer = 0; o_bitcount = 0; };

void send_code(unsigned int what_code, unsigned int how_bits)
{
 o_bitbuffer |= (unsigned long int)what_code << o_bitcount;
 o_bitcount += how_bits;

 while (o_bitcount >= 8) {
  putc(o_bitbuffer & 0xff, outfile);
  o_bitbuffer >>= 8;
  o_bitcount -= 8;
 };
}

void send_finish() { while (o_bitcount!=0) send_code(0,1); };
//---------------------------------------------------------
// функции битового ввода

static unsigned long int i_bitbuffer;
static unsigned int i_bitcount;

void read_reset(void) { i_bitbuffer = 0; i_bitcount = 0; };

unsigned int read_code(unsigned int how_bits)
{
 unsigned int answer;
 unsigned long int temp;

 while(i_bitcount < how_bits) {
  temp = (getc(infile) & 0xff);
  temp <<= i_bitcount;
  i_bitbuffer |= temp;
  i_bitcount += 8;
 };

 answer = i_bitbuffer & ((1 << how_bits) - 1);
 i_bitbuffer >>= how_bits;
 i_bitcount -= how_bits;
 return answer;
};
//=========================================================
// функции реализации lzss

//---------------------------------------------------------
// инициализация lzss
void init_lzss()
{
 uint i;

 for (i = 0; i < N+F; i++)
  ring_buff[i] = '\0';

 for (i = 0; i < N + 1 + 4096; i++)
  next[i] = N;

 for (i = 0; i < N + 1; i++)
  prev[i] = N;
};
//---------------------------------------------------------
// удаление
void del(uint r)
{
 if ( prev[r] == N ) return;
 next[prev[r]] = next[r];
 prev[next[r]] = prev[r];
 prev[r] = next[r] = N;
};
//---------------------------------------------------------
// вставка
void insert(uint r)
{
 uint next_r, c;
 c = ring_buff[r] + (ring_buff[r+1] << 8) & 0xfff;
 next_r = next[c + N + 1];
 next[c + N + 1] = r;
 prev[r] = c + N + 1;
 next[r] = next_r;
 if (next_r != N) prev[next_r] = r;
};
//---------------------------------------------------------
//
void locate(uint r)
{
 uint p, c, i;

 match_len = match_pos = 0;
 c = ring_buff[r] + (ring_buff[r+1] << 8) & 0xfff;

 p = next[c + N + 1];
 i = 0;

 while (p != N) {
  for(i = 0; (i < F) && (ring_buff[p+i] ==
   ring_buff[r+i]); i++);
  if (i>match_len) {
   match_len = i;
   match_pos = (r - p) & (N - 1);
  };
  if (i == F) break;
  p = next[p];
 };

 if (i == F)
  del(p);
};
//---------------------------------------------------------
// функция сжатия фходного файла в выходной
void lzss_encode()
{
 uint r, maxlen;
 int c;
 unsigned long int ps = 0, textsize;   /*printsize*/

 init_lzss();
 send_reset();
 r = 0;
 textsize = 0;

 maxlen = 0;
 while (maxlen<F) {
  if ((c = getc(infile)) != EOF) {
   ring_buff[maxlen + N] = ring_buff[maxlen] = c;
   maxlen++; textsize++;
  } else break;
 };

 while(maxlen) {
  locate(r);
  if (match_len > maxlen) match_len = maxlen;
  if (match_len<THRESHOLD) {
   send_code(0, match_len = 1);
   send_code(ring_buff[r], 8);
  } else {
   send_code(1,1);
   send_code(match_pos,     N_BITS);
   send_code(match_len - 1, F_BITS);
  };

  while(match_len--) {
   del( (r+F) & (N - 1) );
   maxlen--;
   if ((c = getc(infile)) != EOF) {
    ring_buff[(r+F) & (N - 1)] = c;
    if (r+F >= N) ring_buff[r+F] = c;
    textsize++; maxlen++;
   };
   insert(r);
   r = (r+1) & (N-1);
  };

  if (ps<textsize) {
   printf(" Done %10ld\r", textsize);
   ps+=4000;
  };
 };

 send_code(1,1);
 send_code(0,N_BITS);
 send_finish();
};
//---------------------------------------------------------
// Функция декомпрессии
void lzss_decode()
{
 uint r, c, d, l;

 init_lzss();
 read_reset();
 r = 0;

 while(1) {
  c = read_code(1);
  if (!c) {
   putc(ring_buff[r] = read_code(8), outfile);
   r = (r+1) & (N - 1);
  } else {
   d = read_code(N_BITS);
   if (!d) break;
   l = read_code(F_BITS) + 1;
   d = (r-d) & (N - 1);
   while(l--) {
    putc(ring_buff[r] = ring_buff[d], outfile);
    r = (r+1) & (N-1);
    d = (d+1) & (N-1);
   };
  };
 };
};
//---------------------------------------------------------
// гравная функция
int _tmain(int argc, _TCHAR* argv[])
{
 if (argc!=4) {
  printf("Usage:\n  LZSS e(encode)|d(decode) input output\n");
  return(BAD_ARGUMENT);
 };

 switch (argv[1][0]) {
  case 'D': case 'd':
  case 'E': case 'e':
   if ((infile = fopen(argv[2],"rb")) == NULL) {
    printf(" Unable to open input file '%s'.\n", argv[2]);
    return(BAD_FILE);
   };

   if ((outfile = fopen(argv[3],"wb")) == NULL) {
    printf(" Unable to open output file '%s'.\n", argv[3]);
    return(BAD_FILE);
   };

   break;
  default:
   printf(" Unknown option selector '%s' - use D or E", argv[1]);
   return(BAD_ARGUMENT);
 };

 if (toupper(argv[1][0]) == 'E') lzss_encode(); else lzss_decode();

 fclose(infile);
 fclose(outfile);

 fprintf(stderr,"\nLZSS complete\n");

 return NO_ERROR;

}


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