LZW compression algorithm C # source _c# Tutorial

Source: Internet
Author: User
Tags hash
Using System;

Using System.IO;

 Namespace Gif.components {public class Lzwencoder {private static readonly int EOF =-1;
 private int IMGW, IMGH;
 Private byte[] pixary;
 private int initcodesize;
 private int remaining;

 private int curpixel; Gifcompr. C-gif Image Compression Routines///Lempel-ziv compression based on ' compress '.

 GIF modifications by//David Rowley (mgardi@watdcsu.waterloo.edu)//general defines static readonly int BITS = 12; static readonly int hsize = 5003;  80% occupancy//GIF Image compression-modified ' compress '////Based on:compress.c-file, Ala IEEE
 Computer, June 1984.
 by Authors:spencer W. Thomas (Decvax!harpo!utah-cs!utah-gr!thomas)//Jim McKie (Decvax!mcvax!jim)       Steve Davies (DECVAX!VAX135!PETSD!PEORA!SRD)//Ken Turkowski (Decvax!decwrl!turtlevax!ken)// James A. Woods (Decvax!ihnp4!ames!jaw)//Joe Orost (decvax!vax135!petsd!jOE) int n_bits; Number of Bits/code int maxbits = bits; User settable max # bits/code int maxcode; Maximum code, given n_bits int maxmaxcode = 1 << bits; Should NEVER generate this code int[] Htab = new int[hsize];//This is a hash of the cheese, where you can quickly find 1 key int[] Codetab = new Int[h

 SIZE]; int hsize = hsize; For dynamic table sizing int free_ent = 0; The unused entry//block compression Parameters-after all codes are the up,//and used compression rate,
 Start over.

 BOOL CLEAR_FLG = false; Algorithm:use open addressing double hashing (no chaining) on the//prefix code/next character. We do a variant of Knuth ' s//Algorithm D (Vol. 3, Sec. 6.4) along with G. Knott ' s relatively-prime//secondary probe. Here, the modular division-probe is gives way/to a faster exclusive-or. Also do blocks compression with//a adaptive reset, whereby the code table is cleared when the compression//ratio Dec Reases, butAfter the table fills. The variable-length output//codes are re-sized at this point, and a special clear code are generated//for the DECOMPR Essor. Late addition:construct The table according to//file size for noticeable speed improvement on small files.

 Please direct//questions about this implementation to Ames!jaw.

 int g_init_bits;
 int Clearcode;

 int Eofcode;
 Output////output the given code. Inputs://code:a n_bits-bit integer. If = =-1, then EOF.
 This is assumes//that n_bits =< wordsize-1.
 Outputs://Outputs code to the file.
 Assumptions://Chars are 8 bits long. Algorithm://Maintain a BITS character long buffer (so that 8 codes'll//fit in it exactly). Use the VAX insv instruction to insert each//code in turn.

 When the buffer fills up empty it and start over.
 int cur_accum = 0;

 int cur_bits = 0; int [] masks = {0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00fF, 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xFFFF};

 Number of characters so far in this ' packet ' int a_count;

 Define the storage for the packet accumulator byte[] Accum = new byte[256]; ----------------------------------------------------------------------------public lzwencoder (int width, int
  Height, byte[] pixels, int color_depth) {IMGW = width;
  IMGH = height;
  Pixary = pixels;
 Initcodesize = Math.max (2, color_depth);
 //ADD A character to the "end of" the current packet, and if it's 254//characters, flush the packet to disk.
  void Add (byte C, Stream outs) {accum[a_count++] = C;
 if (a_count >= 254) Flush (outs); //clear out of the hash table//table clear for block compress void cleartable (Stream outs) {resetcodetable (HSI
  Ze);
  Free_ent = Clearcode + 2;

  CLEAR_FLG = true;
 Output (Clearcode, outs); //Reset Code table//all initialized to-1 void resetcodetable (int hsize) {for (int i = 0; i < hsize;
 ++i) Htab[i] =-1;
  } void Compress (int init_bits, Stream outs) {int fcode;
  int I/* = 0 */;
  int C;
  int ent;
  int disp;
  int Hsize_reg;

  int hshift;
      Set up the globals:g_init_bits-initial number of bits//raw data, in GIF files, the length of the original data can be 1 (monochrome), 4 (16 colors), and 8 (256 colors)
      Start with 1//, but when the original data length is 1, start with 3//So the original length 1->3,4->5,8->9//? Why is the initial length of the data word 1, starting at 3?? If the +1=2, can only represent four kinds of states, plus Clearcode and Endcode ran out.

  Therefore must extend to 3 g_init_bits = init_bits; Set up the necessary values/whether you need to add a clear flag//gif in order to increase the compression rate, the use of variable length (VCL). For example, the original data is 8 digits, then first add 1-bit (8+1=9)//When the label to the 2^9=512, more than the current length of 9 can represent the maximum value, at this time the label must be used 10 to express/And so on, when the label to 2^12, because the maximum of 12, can not be followed
  Extended, the need to insert a clearcode in the 2^12=4096 position, indicating that from then on, from 9-bit again CLEAR_FLG = false;
      N_bits = g_init_bits;
      To obtain the maximum value of n-digit can be expressed (the GIF image begins generally as 3,5,9, so Maxcode is generally 7,31,511) Maxcode = Maxcode (n_bits); This means that from here I am starting to construct the dictionary dictionary again, all previous tags are voided,//start using the new tag. How much is the size of this label set appropriate?
 It's said theoretically the greater the compression rate (I personally feel too big and not necessarily good),     However, the cost of processing is also exponential growth//gif, Clearcode is the value of the original data can be expressed in the maximum word value +1, such as the original data length of 8, then clearcode=1<< (9-1) =256 Clearcode = 1
      << (INIT_BITS-1);
      End sign for clearcode+1 Eofcode = Clearcode + 1;
      This is the end of the Free_ent = Clearcode + 2; Clear quantity A_count = 0;

  Clear Packet//obtains the next pixel from the image ent = Nextpixel ();
  Hshift = 0;
      for (FCode = hsize; FCode < 65536; FCode *= 2) ++hshift; Set hash code range Hshift = 8-hshift;
      Set hash code range bound Hsize_reg = hsize; Clears the Fixed-size hash table for storing tokens, which corresponds to the dictionary resetcodetable (HSIZE_REG);

  Clear Hash Table Output (clearcode, outs);              
    Outer_loop:while ((c = nextpixel ())!= EOF) {FCode = (c << maxbits) + ent; i = (c << hshift) ^ ent;
     XOR hashing//Hey, demo, come again, I know you if (htab[i] = = FCode) {ent = codetab[i];
    Continue //This boy, new here else if (Htab[i] >= 0)//non-empty slot {disp = hsize_reg-i;//SecondaryHash (after G. Knott) if (i = = 0) disp = 1;

     do {if ((I-= disp) < 0) i + = Hsize_reg;
      if (htab[i] = = FCode) {ent = codetab[i];
     Goto Outer_loop;
    } while (Htab[i] >= 0);
               Output (ent, outs);
               It can be seen from here that Ent is the prefix (prefix), while the character symbol currently being processed is the suffix (suffix) ent = c;  To determine if the end terminator exceeds the current number of digits that can be expressed if (Free_ent < Maxmaxcode) {//If there is no super codetab[i] = free_ent++;//
    Code-> hashtable//hash table to establish the corresponding index htab[i] = FCode;
    else//description exceeds the current range, empty the dictionary, and ClearTable (outs) again;
  }//Put out the final code.
  Output (ent, outs);
 Output (Eofcode, outs); }//----------------------------------------------------------------------------public void Encode (Stream os) {O S.writebyte (Convert.tobyte (initcodesize)); Write "Initial code size" byte//This image contains how many pixels remaining = IMGW * IMGH; Reset Navigation varIables//Current processing pixel index curpixel = 0; Compress (initcodesize + 1, OS); Compress and write the pixel data os. WriteByte (0); Write Block Terminator}//Flush the packet to disk, and reset the accumulator void Flush (Stream outs) {if (a _count > 0) {outs.
  WriteByte (Convert.tobyte (A_count)); Outs.
  Write (accum, 0, A_count);
  A_count = 0; }///<summary>///obtains the maximum number of n digits to express///</summary>///<param name= "n_bits" > digits, generally 
 Case n_bits = 9</param>///<returns> maximum, for example n_bits=8, the return value is 2^8-1=255</returns> int maxcode (int n_bits)
 {return (1 << n_bits)-1; }//----------------------------------------------------------------------------//Return of the next pixel from the IMA GE//----------------------------------------------------------------------------///<summary>///obtained from image
     One pixel///</summary>///<returns></returns> private int nextpixel () { How many pixels left to deal with//if not, return to end flag if (remaining = 0) returns EOF;
      Otherwise processing the next, and the number of unhandled pixels-1--remaining;
      The currently processed pixel int temp = curpixel + 1;
  If the current processing pixel is within the pixel range if (temp < Pixary.getupperbound (0)) {//next pixel byte pix = pixary[curpixel++];
  return pix & 0xFF;
 return 0xFF;  ///<summary>///output word to output stream///</summary>///<param name= "code" > the word to Output </param>/// <param name= "Outs" > output stream </param> void output (int code, stream outs) {//Get the maximum flag value that the current sign bit can represent Cur_accum &

  Amp;= Masks[cur_bits];
  if (cur_bits > 0) cur_accum |= (Code << cur_bits);
      else//If the flag bit is 0, the current label is the input stream cur_accum = code; The maximum character length (9-10-11-12-9-10 ...) of the current indicator.
      ) Cur_bits + = N_bits;
        If the current maximum length is greater than 8 while (Cur_bits >= 8) {//Output a byte Add ((Byte) (Cur_accum & 0xff), outs) to the stream;
  Move the current label right 8-bit cur_accum >>= 8;
  Cur_bits-= 8; }//If the next entry is going to being too Big for the code size,//Then increase it, if possible.
   if (free_ent > Maxcode | | | clear_flg) {if (CLEAR_FLG) {Maxcode = Maxcode (n_bits = g_init_bits);
  CLEAR_FLG = false;
   else {++n_bits;
   if (n_bits = = maxbits) Maxcode = Maxmaxcode;
  else Maxcode = Maxcode (n_bits);
  } if (code = = Eofcode) {//at EOF, write the rest of the buffer.
   while (Cur_bits > 0) {Add ((byte) (Cur_accum & 0xff), outs);
   Cur_accum >>= 8;
  Cur_bits-= 8;
  } Flush (outs);
 }
 }
 }
}

The above is the entire content of this article, I hope to give you a reference, but also hope that we support the cloud-dwelling community.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.