Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > арифметическое кодирование


Автор: sl3n 16.5.2006, 12:38
Здравствуйте
Проблема состоит в том, что мой исходник может обрабатывать только один файл, а мне нужно чтобы програмка могла сжимать сразу несколько файлов. Требуется исходник на с/с++ и только по методу арифметического кодирования. Буду признателен если вы мне поможете. 
 

Автор: _hunter 16.5.2006, 12:56
а почему бы свой исходник не поправить? -- чтобы он мог сжимать сразу несколько файлов... 

Автор: sl3n 17.5.2006, 10:03
проблема в этом и состоит что я не могу етого сделать если есть чем помочь был бы только рад
прикреплю свой исходник:
Код

include <stdio.h>
#include <process.h>
#define BITS_IN_REGISTER 16
#define TOP_VALUE (((long) 1 << BITS_IN_REGISTER) - 1)
#define FIRST_QTR (TOP_VALUE / 4 + 1)
#define HALF      (2 * FIRST_QTR)
#define THIRD_QTR (3 * FIRST_QTR)
#define NO_OF_CHARS 256
#define EOF_SYMBOL    (NO_OF_CHARS + 1)
#define NO_OF_SYMBOLS (NO_OF_CHARS + 1)
#define MAX_FREQUENCY 16383

unsigned char         index_to_char [NO_OF_SYMBOLS];
int              char_to_index [NO_OF_CHARS];

int                   cum_freq [NO_OF_SYMBOLS + 1];
int              freq [NO_OF_SYMBOLS + 1];

long                  low, high;
long              value;

long              bits_to_follow;
int              buffer;
int              bits_to_go;
int              garbage_bits;
FILE *in, *out;
void start_model (void)
{
  int i;

  for ( i = 0; i < NO_OF_CHARS; i++)
  {
    char_to_index [i] = i + 1;
    index_to_char [i + 1] = i;
  }
  for ( i = 0; i <= NO_OF_SYMBOLS; i++)
  {
    freq [i] = 1;
    cum_freq [i] = NO_OF_SYMBOLS - i;
  }
  freq [0] = 0;
}
void update_model ( int symbol)
{
  int i;
  int ch_i, ch_symbol;
  int cum;
  if (cum_freq [0] == MAX_FREQUENCY)
  {
    cum = 0;
       for ( i = NO_OF_SYMBOLS; i >= 0; i--)
    {
      freq [i] = (freq [i] + 1) / 2;
      cum_freq [i] = cum;
      cum += freq [i];
    }
  }
  for ( i = symbol; freq [i] == freq [i - 1]; i--);
  if (i < symbol)
  {
    ch_i                      = index_to_char [i];
    ch_symbol                 = index_to_char [symbol];
    index_to_char [i]         = ch_symbol;
    index_to_char [symbol]    = ch_i;
    char_to_index [ch_i]      = symbol;
    char_to_index [ch_symbol] = i;
  }
  freq [i] += 1;
  while (i > 0)
  {
    i -= 1;
    cum_freq [i] += 1;
  }
}
void start_inputing_bits (void)
{
  bits_to_go = 0;
  garbage_bits = 0;
}
int input_bit (void)
{
  int t;

  if (bits_to_go == 0)
  {
    buffer = getc (in);
    if (buffer == EOF)
    {
      garbage_bits += 1;
      if (garbage_bits > BITS_IN_REGISTER - 2)
      {
    printf ("Îøèáêà â ñæàòîì ôàéëå\n");
    exit (-1);
      }
    }
    bits_to_go = 8;
  }
  t = buffer & 1;
  buffer >>= 1;
  bits_to_go -= 1;
  return t;
}
void start_outputing_bits (void)
{
  buffer = 0;
  bits_to_go = 8;
}
void output_bit ( int bit)
{
  buffer >>= 1;
  if (bit)
    buffer |= 0x80;
  bits_to_go -= 1;
  if (bits_to_go == 0)
  {
    putc ( buffer, out);
    bits_to_go = 8;
  }
}
void done_outputing_bits (void)
{
  putc ( buffer >> bits_to_go, out);
}
void output_bit_plus_follow ( int bit)
{
  output_bit (bit);
  while (bits_to_follow > 0)
  {
    output_bit (!bit);
    bits_to_follow--;
  }
}
void start_encoding (void)
{
  low            = 0l;
  high           = TOP_VALUE;
  bits_to_follow = 0l;
}
void done_encoding (void)
{
  bits_to_follow++;
  if (low < FIRST_QTR)
    output_bit_plus_follow (0);
  else
    output_bit_plus_follow (1);
}
void start_decoding (void)
{
  int i;

  value = 0l;
  for ( i = 1; i <= BITS_IN_REGISTER; i++)
    value = 2 * value + input_bit ();
  low = 0l;
  high = TOP_VALUE;
}
void encode_symbol ( int symbol)
{
  long range;

    range = (long) (high - low) + 1;
  high = low + (range * cum_freq [symbol - 1]) / cum_freq [0] - 1;
  low = low + (range * cum_freq [symbol]) / cum_freq [0];
 
  for (;;)
  {
    if (high < HALF)
      output_bit_plus_follow (0);
    else if (low >= HALF)
    {
      output_bit_plus_follow (1);
      low -= HALF;
      high -= HALF;
    }
    else if (low >= FIRST_QTR && high < THIRD_QTR)
    {
      bits_to_follow += 1;
      low -= FIRST_QTR;
      high -= FIRST_QTR;
    }
    else
      break;
      low = 2 * low;
    high = 2 * high + 1;
  }
}

int decode_symbol (void)
{
  long range;
  int cum, symbol;
  range = (long) (high - low) + 1;
   cum = (int)
    ((((long) (value - low) + 1) * cum_freq [0] - 1) / range);
   for (symbol = 1; cum_freq [symbol] > cum; symbol++);
   high = low + (range * cum_freq [symbol - 1]) / cum_freq [0] - 1;
  low = low + (range * cum_freq [symbol]) / cum_freq [0];
   for (;;)
  {
    if (high < HALF)
    {
    }
    else if (low >= HALF)
    {
      value -= HALF;
      low -= HALF;
      high -= HALF;
    }
    else if (low >= FIRST_QTR && high < THIRD_QTR)
    {
      value -= FIRST_QTR;
      low -= FIRST_QTR;
      high -= FIRST_QTR;
    }
    else
      break;
      low = 2 * low;
    high = 2 * high + 1;
    value = 2 * value + input_bit ();
  }
  return symbol;
}
void encode ( char *infile, char *outfile)
{
  int ch, symbol;

  in = fopen ( infile, "r+b");
  out = fopen ( outfile, "w+b");
  if (in == NULL || out == NULL)
    return;
  start_model ();
  start_outputing_bits ();
  start_encoding ();
  for (;;)
  {
    ch = getc (in);
    if (ch == EOF)
      break;
    symbol = char_to_index [ch];
    encode_symbol (symbol);
    update_model (symbol);
  }
  encode_symbol (EOF_SYMBOL);
  done_encoding ();
  done_outputing_bits ();
  fclose (in);
  fclose (out);
}
void decode ( char *infile, char *outfile)
{
  int ch, symbol;

  in = fopen ( infile, "r+b");
  out = fopen ( outfile, "w+b");
  if (in == NULL || out == NULL)
    return;
  start_model ();
  start_inputing_bits ();
  start_decoding ();
  for (;;)
  {
    symbol = decode_symbol ();
    if (symbol == EOF_SYMBOL)
      break;
    ch = index_to_char [symbol];
    putc ( ch, out);
    update_model (symbol);
  }
  fclose (in);
  fclose (out);
}
void main ( int argc, char **argv)
{
  if (argc < 4)
  {
    printf ("\n Using: ar e|d infile outfile\n");
    exit (0);
  }
  if (argv [1] [0] == 'e')
    encode ( argv [2], argv [3]);
  else if (argv [1] [0] == 'd')
    decode ( argv [2], argv [3]);
  exit (0);
}














   

Автор: Mastkir 17.5.2006, 10:34
А что ты сделать - то не можешь? 
Ты пытался что-то сделать ?
Ты не понимаешь как программа работает, или что? 

Автор: sl3n 17.5.2006, 11:16
программу я не понял до конца от того и не могу исправить
она работает в консоле и запрашивает только один файл для сжатия а что надо изменить чтобы она могла сразу целую папку с файлами взять и сжать 

Автор: _hunter 17.5.2006, 11:25
нужно изменить поведение -- после получения папки (и запрашивать нужно папку а не файл) пройтись по ней рекурсивно и составить список всех файлов.
потом составить из них solid-архив (или после окончания кодирования следующий файл подсовывать) и закодировать его 

Автор: sl3n 17.5.2006, 11:41
у меня врятли это выйдет
есть исходник на подобие?
 был бы рад приобрести 

Автор: _hunter 17.5.2006, 12:22
может где-то и есть.
Цитата(sl3n @  17.5.2006,  11:41 Найти цитируемый пост)
 был бы рад приобрести 

пиши в раздел "Работа"

 

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