void HuffmanTreeCoder::Compress()
{
    SetSymbolCodes();
    setReaderToBeginning();
    WriteHeader();
    EncodeSymbols();
}
Example #2
0
File: mgtic.c Project: plbogen/CSDL
int 
main (int argc, char *args[])
{
  int i, n, r, c, ch;
  FILE *inf;
  marklistptr library = NULL, list = NULL, step = NULL;
  marklistptr symbol_list = NULL;
  marktype d, d2;
  Pixel **bitmap, **recon, **bitmapcopy;
  char *splitfilename = NULL;
  int cols, rows, count, librarysize, lossy = 1;
  int quick = 0;
  int ticencode = 0, ticdecode = 0, external = 0;
  char *libraryname = NULL, *infile = NULL;
  char *s1 = NULL, *s2 = NULL;
  char bufferin[BUFSIZ], bufferout[BUFSIZ];

  if (argc < 2)
    usage ();

  while ((ch = getopt (argc, args, "edlLQhvXR:")) != -1)
    switch (ch)
      {
      case 'e':
	ticencode = 1;
	break;
      case 'd':
	ticdecode = 1;
	break;
      case 'l':
	lossy = 1;
	break;
      case 'L':
	lossy = 0;
	break;
      case 'Q':
	quick = 1;
	break;
      case 'v':
	V = 1;
	break;
      case 'X':
	external = 1;
	break;
      case 'R':
	splitfilename = optarg;
	break;
      case 'h':
      case '?':
	usage ();
      }

  for (i = 1; i < argc; i++)
    if (args[i][0] != '-')
      if (strcmp (args[i - 1], "-R"))
	{			/* ignore arg following -R, ie. -R <filename> */
	  if (!s1)
	    s1 = args[i];
	  else if (!s2)
	    s2 = args[i];
	  else
	    error_msg (args[0], "too many filenames", "");
	}

  if (ticencode == ticdecode)
    error_msg (args[0], "please specify either encode XOR decode", "");

  if (ticencode)
    {
	  /*****************
	    ENCODING STAGE
	  *****************/
      long PrevBits = 0;
      long BITS_header = 0, BITS_symbols = 0, BITS_offsets = 0, BITS_residue = 0,
        BITS_footer = 0, BITS_library = 0;

      libraryname = s1;
      if (!libraryname)
	error_msg (args[0], "please specify a library file", "");
      infile = s2;
      if (!infile)
	error_msg (args[0], "please specify a file name", "");

      inf = fopen (infile, "rb");
      if (inf == NULL)
	error_msg (args[0], "Trouble opening file:", infile);
      setbuf (inf, bufferin);

      count = librarysize = read_library (libraryname, &library);

      if (V)
	fprintf (stderr, "%s: processing...\n", args[0]);

      if (pbm_isapbmfile (inf))
	{
	  if (V)
	    fprintf (stderr, "reading file %s...\n", infile);
	  bitmap = pbm_readfile (inf, &cols, &rows);
	  fclose (inf);

	  bitmapcopy = pbm_copy (bitmap, cols, rows);

	  if (V)
	    fprintf (stderr, "extracting...");
	  ExtractAllMarks (bitmap, &list, cols, rows);
	  if (V)
	    fprintf (stderr, "(%d marks)\n", marklist_length (list));

	  /* sort into reading order */
	  if (V)
	    fprintf (stderr, "sorting...\n");
	  list = sortmarks (list);

	  pbm_freearray (&bitmap, rows);	/* clear old version */
	  bitmap = bitmapcopy;	/* point to the copy */
	  recon = pbm_allocarray (cols, rows);

	  if (V)
	    fprintf (stderr, "matching...");

	  match_sequence (list, library, &symbol_list, recon, quick);


	  PrevBits = 0;
	  setbuf (stdout, bufferout);
	  /* start output */
	  magic_write (stdout, MAGIC_TIC);
	  InitArithEncoding ();

	  EncodeGammaDist (1);	/* version 1 of the program */
	  EncodeGammaDist (lossy);	/* lossy=1 = no residue */
	  EncodeGammaDist (external);	/* 1== external file */

	  count = marklist_length (symbol_list);
	  if (V)
	    fprintf (stderr, "encoding cols, rows, and number of symbols=%d\n", count);

	  EncodeGammaDist (cols);
	  EncodeGammaDist (rows);
	  EncodeGammaDist (count);
	  EncodeGammaDist (librarysize);

	  BITS_header = CountOfBitsOut - PrevBits;
	  PrevBits = CountOfBitsOut;


	  /* output the library sequence */
	  if (external == 0)
	    {
	      if (V)
		fprintf (stderr, "encoding library\n");

	      bl_clearmodel ();
	      bl_writetemplate (library_template);
	      for (step = library; step; step = step->next)
		bl_compress_mark (step->data);
	      bl_freemodel ();
	      BITS_library = CountOfBitsOut - PrevBits;
	      PrevBits = CountOfBitsOut;
	    }

	  /* output the symbol sequence */
	  if (V)
	    fprintf (stderr, "encoding symbol sequence\n");
	  InitPPM ();
	  EncodeSymbols (symbol_list, count);
	  BITS_symbols = CountOfBitsOut - PrevBits;
	  PrevBits = CountOfBitsOut;


	  /* output the offset sequence */
	  if (V)
	    fprintf (stderr, "encoding offset sequence\n");
	  EncodeOffsets (symbol_list, count);
	  BITS_offsets = CountOfBitsOut - PrevBits;
	  PrevBits = CountOfBitsOut;

	  EncodeChecksum ();	/* code lossy checksum */

	  /* calculate the residue...and compress it---if need be! */
	  if (!lossy)
	    {
	      if (V)
		fprintf (stderr, "encoding residue...\n");

	      d.bitmap = bitmap;
	      d.h = rows;
	      d.w = cols;
	      d2.bitmap = recon;
	      d2.h = rows;
	      d2.w = cols;

	      if (splitfilename)
		{
		  FILE *temp;

		  CloseDownArithEncoding ();
		  fclose (stdout);
		  /* no residue result */
		  BITS_footer = CountOfBitsOut - PrevBits;

		  temp = fopen (splitfilename, "wb");
		  if (temp == NULL)
		    error_msg (args[0], "Trouble creating file:", splitfilename);

		  arith_out = temp;
		  InitArithEncoding ();
		  bl_clair_compress (d, d2);
		  CloseDownArithEncoding ();
		  BITS_residue = CountOfBitsOut;
		  fclose (temp);
		}
	      else
		{
		  bl_clair_compress (d, d2);
		  BITS_residue = CountOfBitsOut - PrevBits;
		  PrevBits = CountOfBitsOut;
		  EncodeChecksum ();	/* code lossless checksum */
		  CloseDownArithEncoding ();
		  BITS_footer = CountOfBitsOut - PrevBits;
		}
	    }
	  else
	    {
	      if (V)
		fprintf (stderr, "not encoding residue..lossy mode\n");
	      CloseDownArithEncoding ();
	      BITS_footer = CountOfBitsOut - PrevBits;
	    }

	  /* because we edit the values above */
	  CountOfBitsOut = BITS_header + BITS_library + BITS_symbols + BITS_offsets + BITS_residue + BITS_footer;

	  fprintf (stderr, "bits: header=%ld, library=%ld, "
		   "symbols=%ld, offsets=%ld, residue=%ld, footer=%ld\n",
		   BITS_header, BITS_library, BITS_symbols,
		   BITS_offsets, BITS_residue, BITS_footer);
	  fprintf (stderr, "total bits: %ld, ", CountOfBitsOut);
	  fprintf (stderr, "Lossy CR: %4.2f", (cols * rows) / (float) (CountOfBitsOut - BITS_residue));
	  if (external)
	    fprintf (stderr, " (excluding external lib)");
	  fprintf (stderr, ", Lossless CR: %4.2f\n", (!lossy) * (cols * rows) / (float) (CountOfBitsOut));
	}
      else
	error_msg (args[0], "unknown format of bitmap--expecting PBM.", "");
    }
  else
    {
	  /*****************
	    DECODING STAGE
	  *****************/
      int lastx, lasty;
      librarysize = 0;

      if (external)
	{
	  libraryname = s1;
	  infile = s2;
	  count = librarysize = read_library (libraryname, &library);
	}
      else
	{
	  infile = s1;
	  if (infile && s2)
	    error_msg (args[0], "too many filenames", "");
	}

      if (!freopen (infile, "rb", stdin))
	error_msg (args[0], "Trouble opening file:", infile);


      if (V)
	fprintf (stderr, "decompressing...\n");

      setbuf (stdin, bufferin);
      magic_check (stdin, MAGIC_TIC);

      InitArithDecoding ();

      {
	int version = DecodeGammaDist ();
	if (version != 1)
	  error_msg (args[0], "Need later version of decompressor.", "");
      }

      {
	int templossy = DecodeGammaDist ();
	if (!lossy)
	  lossy = templossy;	/* can only choose if encoded file is lossless */
	if (V)
	  {
	    if (lossy)
	      fprintf (stderr, "lossy mode\n");
	    else
	      fprintf (stderr, "lossless mode\n");
	  }
      }

      if (DecodeGammaDist ())
	{			/* if compressed file doesn't contain library */
	  if (!external)
	    error_msg (args[0], "compressed file doesn't contain library, specify externally", "");
	  external = 1;
	}
      else
	{			/* if compressed file contains library */
	  if (external)
	    fprintf (stderr, "ignoring external library file\n");
	  external = 0;
	}

      cols = DecodeGammaDist ();
      rows = DecodeGammaDist ();
      count = DecodeGammaDist ();

      i = DecodeGammaDist ();	/* librarysize */
      if (external)
	{
	  if (i > librarysize)
	    error_msg (args[0], "external library file is too small!", "");
	  else if (i < librarysize)
	    fprintf (stderr, "%s: warning, expecting a different (smaller) library.\n", args[0]);
	}
      librarysize = i;

      if (V)
	fprintf (stderr, "cols %d, rows %d, num syms %d, library size %d\n", cols, rows, count, librarysize);

      /* decode library */
      if (external == 0)
	{
	  if (V)
	    fprintf (stderr, "reading library\n");
	  bl_clearmodel ();
	  bl_readtemplate ();
	  for (n = 0; n < librarysize; n++)
	    {
	      bl_decompress_mark (&d);
	      d.symnum = n;
	      if (library == NULL)
		step = marklist_add (&library, d);
	      else
		step = marklist_add (&step, d);
	    }
	  bl_freemodel ();
	  if (V)
	    fprintf (stderr, "read %d marks from library\n", marklist_length (library));
	}

      recon = pbm_allocarray (cols, rows);

      /* decode symbols */
      InitPPM ();
      if (V)
	fprintf (stderr, "decompressing %d symbols\n", count);
      symbol_list = DecodeSymbols (count);

      /* decode offsets */
      if (V)
	fprintf (stderr, "reading offsets...\n");
      DecodeOffsets (symbol_list, count);
      lastx = lasty = 0;
      for (step = symbol_list; step; step = step->next)
	{
	  lastx = lastx + step->data.xoffset;
	  lasty = lasty + step->data.yoffset;

	  marklist_getat (library, step->data.symnum, &d2);
	  for (r = 0; r < d2.h; r++)
	    for (c = 0; c < d2.w; c++)
	      if (pbm_getpixel (d2.bitmap, c, r))
		pbm_putpixel_trunc (recon, lastx + c, lasty + r, 1, cols, rows);	/* we don't care, already warned them! */
	  lastx += d2.w;
	}

      DecodeChecksum (args[0]);

      /* decode the residue */
      if (!lossy)
	{
	  if (V)
	    fprintf (stderr, "decoding residue...\n");

	  bitmap = pbm_allocarray (cols, rows);
	  d.bitmap = bitmap;
	  d.w = d2.w = cols;
	  d.h = d2.h = rows;

	  d2.bitmap = recon;

	  /* NOTE: the 2nd argument is clairvoyantly compressed */
	  if (splitfilename)
	    {
	      FILE *temp;

	      CloseDownArithDecoding ();
	      fclose (stdin);

	      temp = fopen (splitfilename, "rb");
	      if (temp == NULL)
		error_msg (args[0], "Trouble opening file:", splitfilename);

	      arith_in = temp;
	      InitArithDecoding ();
	      bl_clair_decompress (d, d2);
	      CloseDownArithDecoding ();
	      fclose (temp);
	    }
	  else
	    {
	      bl_clair_decompress (d, d2);
	      DecodeChecksum (args[0]);
	      CloseDownArithDecoding ();
	    }
	  pbm_freearray (&recon, rows);
	  recon = bitmap;	/* point to the bitmap */
	}
      else
	{
	  CloseDownArithDecoding ();
	}

      if (V)
	fprintf (stderr, "writing pbm file...\n");
      setbuf (stdout, bufferout);
      pbm_writefile (stdout, recon, cols, rows);
      pbm_freearray (&recon, rows);
    }				/* end decoding */
  exit(0);
}