Advertisement
ijontichy

huffman.cpp

Jan 21st, 2012
136
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.75 KB | None | 0 0
  1. /*
  2.  * Replacement for older Skulltag Launcher Protocol's huffman.cpp
  3.  *
  4.  * Copyright 2009 Timothy Landers
  5.  * email: code.vortexcortex@gmail.com
  6.  *
  7.  * Permission is hereby granted, free of charge, to any person obtaining a copy
  8.  * of this software and associated documentation files (the "Software"), to deal
  9.  * in the Software without restriction, including without limitation the rights
  10.  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11.  * copies of the Software, and to permit persons to whom the Software is
  12.  * furnished to do so, subject to the following conditions:
  13.  *
  14.  * The above copyright notice and this permission notice shall be included in
  15.  * all copies or substantial portions of the Software.
  16.  *
  17.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20.  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22.  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23.  * THE SOFTWARE.
  24.  */
  25.  
  26. // required for atexit()
  27. #include <stdlib.h>
  28.  
  29. #include "huffman.h"
  30. #include "huffcodec.h"
  31.  
  32. using namespace skulltag;
  33. // Global Variables
  34.  
  35. /** Reference to the HuffmanCodec Object that will perform the encoding and decoding. */
  36. static HuffmanCodec * __codec = 0;
  37.  
  38. // Function Implementation
  39.  
  40. /** Creates and intitializes a HuffmanCodec Object. <br>
  41.  * Also arranges for HUFFMAN_Destruct() to be called upon termination. */
  42. void HUFFMAN_Construct(){
  43.  
  44.     // The exact structure description of a Huffman tree
  45.     static unsigned char const compatible_huffman_tree[] = {
  46.           0,  0,  0,  1,128,  0,  0,  0,  3, 38, 34,  2,  1, 80,  3,110,
  47.         144, 67,  0,  2,  1, 74,  3,243,142, 37,  2,  3,124, 58,182,  0,
  48.           0,  1, 36,  0,  3,221,131,  3,245,163,  1, 35,  3,113, 85,  0,
  49.           1, 41,  1, 77,  3,199,130,  0,  1,206,  3,185,153,  3, 70,118,
  50.           0,  3,  3,  5,  0,  0,  1, 24,  0,  2,  3,198,190, 63,  2,  3,
  51.         139,186, 75,  0,  1, 44,  2,  3,240,218, 56,  3, 40, 39,  0,  0,
  52.           2,  2,  3,244,247, 81, 65,  0,  3,  9,125,  3, 68, 60,  0,  0,
  53.           1, 25,  3,191,138,  3, 86, 17,  0,  1, 23,  3,220,178,  2,  3,
  54.         165,194, 14,  1,  0,  2,  2,  0,  0,  2,  1,208,  3,150,157,181,
  55.           1,222,  2,  3,216,230,211,  0,  2,  2,  3,252,141, 10, 42,  0,
  56.           2,  3,134,135,104,  1,103,  3,187,225, 95, 32,  0,  0,  0,  0,
  57.           0,  0,  1, 57,  1, 61,  3,183,237,  0,  0,  3,233,234,  3,246,
  58.         203,  2,  3,250,147, 79,  1,129,  0,  1,  7,  3,143,136,  1, 20,
  59.           3,179,148,  0,  0,  0,  3, 28,106,  3,101, 87,  1, 66,  0,  3,
  60.         180,219,  3,227,241,  0,  1, 26,  1,251,  3,229,214,  3, 54, 69,
  61.           0,  0,  0,  0,  0,  3,231,212,  3,156,176,  3, 93, 83,  0,  3,
  62.          96,253,  3, 30, 13,  0,  0,  2,  3,175,254, 94,  3,159, 27,  2,
  63.           1,  8,  3,204,226, 78,  0,  0,  0,  3,107, 88,  1, 31,  3,137,
  64.         169,  2,  2,  3,215,145,  6,  4,  1,127,  0,  1, 99,  3,209,217,
  65.           0,  3,213,238,  3,177,170,  1,132,  0,  0,  0,  2,  3, 22, 12,
  66.         114,  2,  2,  3,158,197, 97, 45,  0,  1, 46,  1,112,  3,174,249,
  67.           0,  3,224,102,  2,  3,171,151,193,  0,  0,  0,  3, 15, 16,  3,
  68.           2,168,  1, 49,  3, 91,146,  0,  1, 48,  3,173, 29,  0,  3, 19,
  69.         126,  3, 92,242,  0,  0,  0,  0,  0,  0,  3,205,192,  2,  3,235,
  70.         149,255,  2,  3,223,184,248,  0,  0,  3,108,236,  3,111, 90,  2,
  71.           3,117,115, 71,  0,  0,  3, 11, 50,  0,  3,188,119,  1,122,  3,
  72.         167,162,  1,160,  1,133,  3,123, 21,  0,  0,  2,  1, 59,  2,  3,
  73.         155,154, 98, 43,  0,  3, 76, 51,  2,  3,201,116, 72,  2,  0,  2,
  74.           3,109,100,121,  2,  3,195,232, 18,  1,  0,  2,  0,  1,164,  2,
  75.           3,120,189, 73,  0,  1,196,  3,239,210,  3, 64, 62, 89,  0,  0,
  76.           1, 33,  2,  3,228,161, 55,  2,  3, 84,152, 47,  0,  0,  2,  3,
  77.         207,172,140,  3, 82,166,  0,  3, 53,105,  1, 52,  3,202,200
  78.     };
  79.  
  80.     // create a HuffmanCodec that is compatible with the previous implementation.
  81.     __codec = new HuffmanCodec( compatible_huffman_tree, sizeof compatible_huffman_tree );
  82.  
  83.     // set up the HuffmanCodec to perform in a backwards compatible fashion.
  84.     __codec->reversedBytes( true );
  85.     __codec->allowExpansion( false );
  86.  
  87.     // request that the destruct function be called upon exit.
  88.     atexit( HUFFMAN_Destruct );
  89. }
  90.  
  91. /** Releases resources allocated by the HuffmanCodec. */
  92. void HUFFMAN_Destruct(){
  93.     if ( __codec != 0 ) delete __codec;
  94. }
  95.  
  96. /** Applies Huffman encoding to a block of data. */
  97. void HUFFMAN_Encode(
  98.     /** in: Pointer to start of data that is to be encoded. */
  99.     unsigned char const * const inputBuffer,
  100.     /** out: Pointer to destination buffer where encoded data will be stored. */
  101.     unsigned char * const outputBuffer,
  102.     /** in: Number of chars to read from inputBuffer. */
  103.     int const &inputBufferSize,
  104.     /**< in+out: Max chars to write into outputBuffer. <br>
  105.      *      Upon return holds the number of chars stored or 0 if an error occurs. */
  106.     int * outputBufferSize
  107. ){
  108.     int bytesWritten = __codec->encode( inputBuffer, outputBuffer, inputBufferSize, *outputBufferSize );
  109.  
  110.     // expansion occured -- provide backwards compatibility
  111.     if ( bytesWritten < 0 ){
  112.         // check buffer sizes
  113.         if ( *outputBufferSize < (inputBufferSize + 1) ){
  114.             // outputBuffer too small, return "no bytes written"
  115.             *outputBufferSize = 0;
  116.             return;
  117.         }
  118.  
  119.         // perform the unencoded copy
  120.         for ( int i = 0; i < inputBufferSize; i++ ) outputBuffer[i+1] = inputBuffer[i];
  121.         // supply the "unencoded" signal and bytesWritten
  122.         outputBuffer[0] = 0xff;
  123.         *outputBufferSize = inputBufferSize + 1;
  124.     } else {
  125.         // assign the bytesWritten return value
  126.         *outputBufferSize = bytesWritten;
  127.     }
  128. } // end function HUFFMAN_Encode
  129.  
  130. /** Decodes a block of data that is Huffman encoded. */
  131. void HUFFMAN_Decode(
  132.     unsigned char const * const inputBuffer,    /**< in: Pointer to start of data that is to be decoded. */
  133.     unsigned char * const outputBuffer,         /**< out: Pointer to destination buffer where decoded data will be stored. */
  134.     int const &inputBufferSize,                 /**< in: Number of chars to read from inputBuffer. */
  135.     int *outputBufferSize                       /**< in+out: Max chars to write into outputBuffer. Upon return holds the number of chars stored or 0 if an error occurs. */
  136. ){
  137.     // check for "unencoded" signal & provide backwards compatibility
  138.     if ((inputBufferSize > 0) && ((inputBuffer[0]&0xff) == 0xff)){
  139.         // check buffer sizes
  140.         if ( *outputBufferSize < (inputBufferSize - 1) ){
  141.             // outputBuffer too small, return "no bytes written"
  142.             *outputBufferSize = 0;
  143.             return;
  144.         }
  145.  
  146.         // perform the unencoded copy
  147.         for ( int i = 1; i < inputBufferSize; i++ ) outputBuffer[i-1] = inputBuffer[i];
  148.  
  149.         // supply the bytesWritten
  150.         *outputBufferSize = inputBufferSize - 1;
  151.     } else {
  152.         // decode the data
  153.         *outputBufferSize = __codec->decode( inputBuffer, outputBuffer, inputBufferSize, *outputBufferSize );
  154.     }
  155. } // end function HUFFMAN_Decode
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement