Advertisement
Guest User

Untitled

a guest
Jul 25th, 2014
188
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.90 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <inttypes.h>
  4.  
  5. #include <vector>
  6.  
  7. class NODE
  8. {
  9.     private:
  10.         uint16_t weight;
  11.         uint8_t value;
  12.         NODE* left;
  13.         NODE* right;
  14.         NODE* parent;
  15.    
  16.     public:
  17.         NODE()
  18.         {
  19.             set(NULL, NULL, NULL, 0, 0);
  20.         }
  21.         ~NODE()
  22.         {
  23.             if (left != NULL)
  24.             {
  25.                 delete left;
  26.                 left = NULL;
  27.             }
  28.            
  29.             if (right != NULL)
  30.             {
  31.                 delete right;
  32.                 right = NULL;
  33.             }
  34.         }
  35.        
  36.         NODE* getRight() { return right; }
  37.         NODE* getLeft() { return left; }
  38.         NODE* getParent() { return parent; }
  39.         uint16_t getWeight() { return weight; }
  40.         uint8_t getValue() { return value; }
  41.        
  42.         void set(NODE* _parent, NODE* _left, NODE* _right, uint16_t _weight, uint8_t _value)
  43.         {
  44.             parent = _parent;
  45.             left = _left;
  46.             right = _right;
  47.             weight = _weight;
  48.             value = _value;
  49.         }
  50.     void setParent(NODE* a)
  51.     { parent = a; }
  52.        
  53.         void print()
  54.         {
  55.             printf("%p %p<->%p %hhu [%hu]\n", parent, left, right, value, weight);
  56.         }
  57. };
  58.  
  59. void createHuffmanTable(std::vector< std::vector<bool> >& TABLE, uint16_t* FREQ, std::vector<uint8_t>& FLATTENED_TREE)
  60. {
  61.     //make the table of nodes
  62.     std::vector<NODE*> all_nodes;
  63.    
  64.     for (uint16_t i=0; i<256; i++)
  65.     {
  66.         if (FREQ[i] != 0)
  67.         {
  68.             NODE* temp = new NODE;
  69.             temp->set(NULL,NULL,NULL,FREQ[i],i);
  70.             all_nodes.push_back(temp);
  71.         }
  72.     }
  73.  
  74.  
  75.     //create the Huffman tree
  76.     if (all_nodes.size() > 1)
  77.     {
  78.         //find the 2 lowest nodes
  79.         NODE* first;
  80.         NODE* second;
  81.  
  82.         uint8_t first_index;
  83.         uint8_t second_index;
  84.  
  85.         while (all_nodes.size() > 1)
  86.         {
  87.             first_index = 0;
  88.             second_index = 0;
  89.  
  90.  
  91.             //grab the first lowest node
  92.             first = all_nodes[0];
  93.             for (int i=0; i<all_nodes.size(); i++)
  94.             {
  95.                 if (all_nodes[i]->getWeight() < first->getWeight())
  96.                 {
  97.                     first = all_nodes[i];
  98.                     first_index = i;
  99.                 }
  100.             }
  101.    
  102.             //remove the first lowest node
  103.             all_nodes[first_index] = all_nodes[all_nodes.size()-1];
  104.             all_nodes.pop_back();
  105.  
  106.             //grab the second lowest node
  107.             second = all_nodes[0];
  108.             for (int i=0; i<all_nodes.size(); i++)
  109.             {
  110.                 if (all_nodes[i]->getWeight() < second->getWeight())
  111.                 {
  112.                     second = all_nodes[i];
  113.                     second_index = i;
  114.                 }
  115.             }
  116.  
  117.             //remove the second lowest node
  118.             all_nodes[second_index] = all_nodes[all_nodes.size()-1];
  119.             all_nodes.pop_back();
  120.  
  121.  
  122.             //join the two nodes
  123.             NODE* temp = new NODE;
  124.             temp->set(NULL, first, second, first->getWeight() + second->getWeight(), 0);
  125.             first->setParent(temp);
  126.             second->setParent(temp);
  127.  
  128.             //push the new node into the vector
  129.             all_nodes.push_back(temp);
  130.         }
  131.     }
  132.  
  133.     //all_nodes[0] is the head of the tree
  134.  
  135.     //extract the leaves and create a flattened tree
  136.     std::vector<NODE*> nodes;
  137.     nodes.push_back(all_nodes[0]);
  138.     all_nodes.clear();
  139.  
  140.     for (uint16_t i=0; i<nodes.size(); i++)
  141.     {
  142.         if (nodes[i]->getLeft() == NULL && nodes[i]->getRight() == NULL)
  143.         {
  144.             all_nodes.push_back(nodes[i]);
  145.         }
  146.  
  147.         if (nodes[i]->getLeft())
  148.         {
  149.             nodes.push_back(nodes[i]->getLeft());
  150.            
  151.             //if leaf
  152.             if (nodes[i]->getLeft()->getLeft() == NULL && nodes[i]->getLeft()->getRight() == NULL)
  153.             {
  154.                 FLATTENED_TREE.push_back('1');
  155.                 FLATTENED_TREE.push_back(nodes[i]->getLeft()->getValue());
  156.             }
  157.             else
  158.                 FLATTENED_TREE.push_back('0');
  159.         }
  160.  
  161.         if (nodes[i]->getRight())
  162.         {
  163.             nodes.push_back(nodes[i]->getRight());
  164.            
  165.             //if leaf
  166.             if (nodes[i]->getRight()->getLeft() == NULL && nodes[i]->getRight()->getRight() == NULL)
  167.             {
  168.                 FLATTENED_TREE.push_back('1');
  169.                 FLATTENED_TREE.push_back(nodes[i]->getRight()->getValue());
  170.             }
  171.             else
  172.                 FLATTENED_TREE.push_back('0');
  173.         }
  174.     }
  175.        
  176.  
  177.  
  178.     //create the Huffman Table of all characters
  179.     if (all_nodes.size() == 1)
  180.     {
  181.         TABLE[ all_nodes[0]->getValue() ].push_back(1);
  182.         //printf(" - %c[%d]\n", all_nodes[0]->getValue(),all_nodes[0]->getValue());
  183.     }
  184.     else
  185.     {
  186.         //get the bit representation of each character
  187.         for (int i=0; i<all_nodes.size(); i++)
  188.         {
  189.             NODE* temp = all_nodes[i];
  190.             while (temp->getParent() != NULL)
  191.             {
  192.                 if (temp->getParent()->getLeft() == temp)
  193.                 {
  194.                     TABLE[ all_nodes[i]->getValue() ].push_back(0);
  195.                 }
  196.                 else if (temp->getParent()->getRight() == temp)
  197.                 {
  198.                     TABLE[ all_nodes[i]->getValue() ].push_back(1);
  199.                 }
  200.                 temp = temp->getParent();
  201.             }
  202.         }
  203.     }
  204.  
  205.     // TABLE contains the huffman table with each vector representing the bit sequence
  206. }
  207.  
  208.  
  209. int main()
  210. {
  211.     system("clear");
  212.     // STAGE 1: read input and create a frequency table
  213.    
  214.     //open the input file for reading
  215.     FILE* fInput = fopen("input.txt", "r");
  216.     if (!fInput)
  217.     {
  218.         printf("Input file could not be read!\n");
  219.         fclose(fInput);
  220.         return 0;
  221.     }
  222.    
  223.     //create a frequency table
  224.     uint16_t frequency_table[256] = {0};
  225.    
  226.     //read the input source
  227.     char line[1024];
  228.     uint64_t original_byte_count = 0;
  229.     while (fgets(line, 1024, fInput) != NULL)
  230.     {
  231.         for (uint16_t i=0; i<strlen(line); i++)
  232.         {
  233.             //LOSSLESS
  234.             //count the frequency of each character
  235.             frequency_table[ line[i] ]++;
  236.  
  237.             //LOSSY
  238.             /*
  239.             if (line[i] >= 97 && line[i] <= 122) //lower case letters
  240.             {
  241.                 frequency_table[ line[i]-32 ]++;
  242.             }
  243.             else
  244.             {
  245.                 frequency_table[ line[i] ]++;
  246.             }
  247.             */
  248.             original_byte_count++;
  249.         }
  250.     }
  251.    
  252.     if (original_byte_count == 0)
  253.     {
  254.         printf("Nothing to encode\n");
  255.         return 0;
  256.     }
  257.          
  258.  
  259.     // STAGE 2: create the Huffman Table of all characters
  260.     std::vector< std::vector<bool> > bitRep(256);
  261.     std::vector<uint8_t> flattened_tree;
  262.     createHuffmanTable(bitRep, frequency_table, flattened_tree);
  263.  
  264.     // STAGE 3: print out the huffman table of the used characters
  265.     for (int i=0; i<bitRep.size(); i++)
  266.     {
  267.         if (bitRep[i].size() > 0)
  268.         {
  269.             for (int j=bitRep[i].size()-1; j>=0; j=j-1)
  270.             {
  271.                 if (bitRep[i][j] == true)
  272.                     printf("1");
  273.                 else if (bitRep[i][j] == false)
  274.                     printf("0");
  275.             }
  276.             printf("   — [%d] %c\n", i, i);
  277.         }
  278.     }
  279.  
  280.     uint64_t bit_sum = 0;
  281.     for (int i=0; i<256; i++)
  282.     {
  283.         if (frequency_table[i] > 0)
  284.         {
  285.             bit_sum = bit_sum + (bitRep[i].size() * frequency_table[i]);
  286.         }
  287.     }
  288.     printf("\n\n");
  289.     printf("Starting number of bits %llu\n", original_byte_count*8);
  290.     printf("number of bits %llu\n", bit_sum);
  291.     printf("number of bytes %f\n", float(bit_sum)/8.0);
  292.     printf("compression ratio %f\n", float(bit_sum)/float(original_byte_count*8));
  293.  
  294.  
  295.     // STAGE 3: store Huffman Table in an array
  296.     uint16_t number_of_active_bytes = 0;
  297.     uint8_t active_byte[32] = {0};
  298.     uint32_t number_of_stored_table_bits = 0;
  299.  
  300.     for (int i=0; i<256; i++)
  301.     {
  302.         //set the active bytes
  303.         if (!bitRep[i].empty())
  304.         {
  305.             number_of_active_bytes++;
  306.             active_byte[i/8] = active_byte[i/8] | (0x1 << i%8);
  307.             number_of_stored_table_bits = number_of_stored_table_bits + bitRep[i].size();
  308.         }
  309.        
  310.     }
  311.    
  312.     printf("\n\n");
  313.     printf("Number of active bytes %hu\n", number_of_active_bytes);
  314.     printf("Number of huffman table bits %u\n", number_of_active_bytes*8 + number_of_stored_table_bits);
  315.  
  316.  
  317.     printf("Number of total bits %llu\n", 37*8 + number_of_active_bytes*8 + number_of_stored_table_bits + bit_sum);
  318.    
  319.  
  320.     for (int i=0; i<flattened_tree.size(); i++)
  321.         printf("%c", flattened_tree[i]);
  322.     printf("\n");
  323. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement