コード例 #1
0
ファイル: Huffman.cs プロジェクト: CheneyWu/coreclr
    /**************
	** DoHuffman **
	***************
	** Execute a huffman compression on a block of plaintext.
	** Note that (as with IDEA encryption) an iteration of the
	** Huffman test includes a compression AND a decompression.
	** Also, the compression cycle includes building the
	** Huffman tree.
	*/
    public override double Run()
    {
        huff_node[] hufftree;
        long accumtime;
        double iterations;
        byte[] comparray;
        byte[] decomparray;
        byte[] plaintext;

        InitWords();

        /*
		** Allocate memory for the plaintext and the compressed text.
		** We'll be really pessimistic here, and allocate equal amounts
		** for both (though we know...well, we PRESUME) the compressed
		** stuff will take less than the plain stuff.
		** Also note that we'll build a 3rd buffer to decompress
		** into, and we preallocate space for the huffman tree.
		** (We presume that the Huffman tree will grow no larger
		** than 512 bytes.  This is actually a super-conservative
		** estimate...but, who cares?)
		*/
        plaintext = new byte[this.arraysize];
        comparray = new byte[this.arraysize];
        decomparray = new byte[this.arraysize];

        hufftree = new huff_node[512];

        /*
		** Build the plaintext buffer.  Since we want this to
		** actually be able to compress, we'll use the
		** wordcatalog to build the plaintext stuff.
		*/
        create_text_block(plaintext, this.arraysize - 1, 500);
        //		for (int i = 0; i < this.arraysize-1; i++) {
        //			Console.Write((char)plaintext[i]);
        //		}
        plaintext[this.arraysize - 1] = (byte)'\0';
        // plaintextlen=this.arraysize;

        /*
		** See if we need to perform self adjustment loop.
		*/
        if (this.adjust == 0)
        {
            /*
			** Do self-adjustment.  This involves initializing the
			** # of loops and increasing the loop count until we
			** get a number of loops that we can use.
			*/

            for (this.loops = 100;
              this.loops < global.MAXHUFFLOOPS;
              this.loops += 10)
            {
                if (DoHuffIteration(plaintext,
                    comparray,
                    decomparray,
                  this.arraysize,
                  this.loops,
                  hufftree) > global.min_ticks)
                    break;
            }
        }

        /*
		** All's well if we get here.  Do the test.
		*/
        accumtime = 0L;
        iterations = (double)0.0;

        do
        {
            accumtime += DoHuffIteration(plaintext,
                comparray,
                decomparray,
                this.arraysize,
                this.loops,
                hufftree);
            iterations += (double)this.loops;
        } while (ByteMark.TicksToSecs(accumtime) < this.request_secs);

        /*
		** Clean up, calculate results, and go home.  Be sure to
		** show that we don't have to rerun adjustment code.
		*/
        //this.iterspersec=iterations / TicksToFracSecs(accumtime);

        if (this.adjust == 0)
            this.adjust = 1;

        return (iterations / ByteMark.TicksToFracSecs(accumtime));
    }
コード例 #2
0
ファイル: Huffman.cs プロジェクト: lodejard/AllNetCore
    /**************
    ** DoHuffman **
    ***************
    ** Execute a huffman compression on a block of plaintext.
    ** Note that (as with IDEA encryption) an iteration of the
    ** Huffman test includes a compression AND a decompression.
    ** Also, the compression cycle includes building the
    ** Huffman tree.
    */
    public override double Run()
    {
        huff_node[] hufftree;
        long        accumtime;
        double      iterations;

        byte[] comparray;
        byte[] decomparray;
        byte[] plaintext;

        InitWords();

        /*
        ** Allocate memory for the plaintext and the compressed text.
        ** We'll be really pessimistic here, and allocate equal amounts
        ** for both (though we know...well, we PRESUME) the compressed
        ** stuff will take less than the plain stuff.
        ** Also note that we'll build a 3rd buffer to decompress
        ** into, and we preallocate space for the huffman tree.
        ** (We presume that the Huffman tree will grow no larger
        ** than 512 bytes.  This is actually a super-conservative
        ** estimate...but, who cares?)
        */
        plaintext   = new byte[this.arraysize];
        comparray   = new byte[this.arraysize];
        decomparray = new byte[this.arraysize];

        hufftree = new huff_node[512];

        /*
        ** Build the plaintext buffer.  Since we want this to
        ** actually be able to compress, we'll use the
        ** wordcatalog to build the plaintext stuff.
        */
        create_text_block(plaintext, this.arraysize - 1, 500);
        //		for (int i = 0; i < this.arraysize-1; i++) {
        //			Console.Write((char)plaintext[i]);
        //		}
        plaintext[this.arraysize - 1] = (byte)'\0';
        // plaintextlen=this.arraysize;

        /*
        ** See if we need to perform self adjustment loop.
        */
        if (this.adjust == 0)
        {
            /*
            ** Do self-adjustment.  This involves initializing the
            ** # of loops and increasing the loop count until we
            ** get a number of loops that we can use.
            */

            for (this.loops = 100;
                 this.loops < global.MAXHUFFLOOPS;
                 this.loops += 10)
            {
                if (DoHuffIteration(plaintext,
                                    comparray,
                                    decomparray,
                                    this.arraysize,
                                    this.loops,
                                    hufftree) > global.min_ticks)
                {
                    break;
                }
            }
        }

        /*
        ** All's well if we get here.  Do the test.
        */
        accumtime  = 0L;
        iterations = (double)0.0;

        do
        {
            accumtime += DoHuffIteration(plaintext,
                                         comparray,
                                         decomparray,
                                         this.arraysize,
                                         this.loops,
                                         hufftree);
            iterations += (double)this.loops;
        } while (ByteMark.TicksToSecs(accumtime) < this.request_secs);

        /*
        ** Clean up, calculate results, and go home.  Be sure to
        ** show that we don't have to rerun adjustment code.
        */
        //this.iterspersec=iterations / TicksToFracSecs(accumtime);

        if (this.adjust == 0)
        {
            this.adjust = 1;
        }

        return(iterations / ByteMark.TicksToFracSecs(accumtime));
    }
コード例 #3
0
ファイル: Huffman.cs プロジェクト: CheneyWu/coreclr
    /********************
	** DoHuffIteration **
	*********************
	** Perform the huffman benchmark.  This routine
	**  (a) Builds the huffman tree
	**  (b) Compresses the text
	**  (c) Decompresses the text and verifies correct decompression
	*/
    private static long DoHuffIteration(byte[] plaintext,
        byte[] comparray,
        byte[] decomparray,
        int arraysize,
        int nloops,
        huff_node[] hufftree)
    {
        int i;                          /* Index */
        int j;                         /* Bigger index */
        int root;                       /* Pointer to huffman tree root */
        float lowfreq1, lowfreq2;       /* Low frequency counters */
        int lowidx1, lowidx2;           /* Indexes of low freq. elements */
        int bitoffset;                 /* Bit offset into text */
        int textoffset;                /* Char offset into text */
        int maxbitoffset;              /* Holds limit of bit offset */
        int bitstringlen;              /* Length of bitstring */
        int c;                          /* Character from plaintext */
        byte[] bitstring = new byte[30];             /* Holds bitstring */
        long elapsed;                  /* For stopwatch */

        /*
		** Start the stopwatch
		*/
        elapsed = ByteMark.StartStopwatch();

        /*
		** Do everything for nloops
		*/
        while (nloops-- != 0)
        {
            /*
			** Calculate the frequency of each byte value. Store the
			** results in what will become the "leaves" of the
			** Huffman tree.  Interior nodes will be built in those
			** nodes greater than node #255.
			*/
            for (i = 0; i < 256; i++)
            {
                hufftree[i].freq = (float)0.0;
                hufftree[i].c = (byte)i;
            }

            for (j = 0; j < arraysize; j++)
                hufftree[plaintext[j]].freq += (float)1.0;

            for (i = 0; i < 256; i++)
                if (hufftree[i].freq != (float)0.0)
                    hufftree[i].freq /= (float)arraysize;

            /*
			** Build the huffman tree.  First clear all the parent
			** pointers and left/right pointers.  Also, discard all
			** nodes that have a frequency of true 0.
			*/
            for (i = 0; i < 512; i++)
            {
                if (hufftree[i].freq == (float)0.0)
                    hufftree[i].parent = EXCLUDED;
                else
                    hufftree[i].parent = hufftree[i].left = hufftree[i].right = -1;
            }

            /*
			** Go through the tree. Finding nodes of really low
			** frequency.
			*/
            root = 255;                       /* Starting root node-1 */
            while (true)
            {
                lowfreq1 = (float)2.0; lowfreq2 = (float)2.0;
                lowidx1 = -1; lowidx2 = -1;
                /*
				** Find first lowest frequency.
				*/
                for (i = 0; i <= root; i++)
                    if (hufftree[i].parent < 0)
                        if (hufftree[i].freq < lowfreq1)
                        {
                            lowfreq1 = hufftree[i].freq;
                            lowidx1 = i;
                        }

                /*
				** Did we find a lowest value?  If not, the
				** tree is done.
				*/
                if (lowidx1 == -1) break;

                /*
				** Find next lowest frequency
				*/
                for (i = 0; i <= root; i++)
                    if ((hufftree[i].parent < 0) && (i != lowidx1))
                        if (hufftree[i].freq < lowfreq2)
                        {
                            lowfreq2 = hufftree[i].freq;
                            lowidx2 = i;
                        }

                /*
				** If we could only find one item, then that
				** item is surely the root, and (as above) the
				** tree is done.
				*/
                if (lowidx2 == -1) break;

                /*
				** Attach the two new nodes to the current root, and
				** advance the current root.
				*/
                root++;                 /* New root */
                hufftree[lowidx1].parent = root;
                hufftree[lowidx2].parent = root;
                hufftree[root].freq = lowfreq1 + lowfreq2;
                hufftree[root].left = lowidx1;
                hufftree[root].right = lowidx2;
                hufftree[root].parent = -2;       /* Show root */
            }

            /*
			** Huffman tree built...compress the plaintext
			*/
            bitoffset = 0;                           /* Initialize bit offset */
            for (i = 0; i < arraysize; i++)
            {
                c = (int)plaintext[i];                 /* Fetch character */
                                                       /*
                                                       ** Build a bit string for byte c
                                                       */
                bitstringlen = 0;
                while (hufftree[c].parent != -2)
                {
                    if (hufftree[hufftree[c].parent].left == c)
                        bitstring[bitstringlen] = (byte)'0';
                    else
                        bitstring[bitstringlen] = (byte)'1';
                    c = hufftree[c].parent;
                    bitstringlen++;
                }

                /*
				** Step backwards through the bit string, setting
				** bits in the compressed array as you go.
				*/
                while (bitstringlen-- != 0)
                {
                    SetCompBit(comparray, bitoffset, bitstring[bitstringlen]);
                    bitoffset++;
                }
            }

            /*
			** Compression done.  Perform de-compression.
			*/
            maxbitoffset = bitoffset;
            bitoffset = 0;
            textoffset = 0;
            do
            {
                i = root;
                while (hufftree[i].left != -1)
                {
                    if (GetCompBit(comparray, bitoffset) == 0)
                        i = hufftree[i].left;
                    else
                        i = hufftree[i].right;
                    bitoffset++;
                }
                decomparray[textoffset] = hufftree[i].c;

#if DEBUG
                if (hufftree[i].c != plaintext[textoffset])
                {
                    /* Show error */
                    string error = String.Format("Huffman: error at textoffset {0}", textoffset);
                    throw new Exception(error);
                }
#endif
                textoffset++;
            } while (bitoffset < maxbitoffset);
        }       /* End the big while(nloops--) from above */

        /*
		** All done
		*/
        return (ByteMark.StopStopwatch(elapsed));
    }