HuffmanTree*
HuffmanEncoder::huffmanTreeFromFrequencyMap(uint64_t *FreqMap)
{
    priority_queue<HuffmanTree*,vector<HuffmanTree*>,HuffmanTreeCompare> forest{};

    for (int i = 0; i < 256; i++) {
        if (FreqMap[i] == 0) {
            continue;
        }
        HuffmanTree *tree = new HuffmanTree((char)i, FreqMap[i]);
        if (tree->GetWeight() == 0) {
            printf("Weight is 0!!!********************************************************8\n");
        }
        forest.push(tree);
    }

    printf("%ld trees in forest", forest.size());

    while (forest.size() > 1) {
        HuffmanTree *smallest = forest.top();
        forest.pop();
        HuffmanTree *secondSmallest = forest.top();
        forest.pop();
        HuffmanTree *tree = new HuffmanTree(smallest, secondSmallest);
        forest.push(tree);
    }

    return forest.top();
}
示例#2
0
int main(int argc, char* argv[]) {
    using namespace ptlmuh006;

    if(argc != 4){
        std::cout << "Incorrect usage." << std::endl;
        std::cout << "Please use huffencode as follows:" << std::endl;
        std::cout << "huffencode <option> <inputFilename> <outputFilename>" << std::endl;
        std::cout << "\t___options:___" << std::endl;
        std::cout << "\t -c compress data from inputFilename to outputFilename" << std::endl;
        std::cout << "\t -x extract compressed data from inputFilename to outputFilename" << std::endl;

    }else{
        HuffmanTree* huff = new HuffmanTree;

        std::string option = argv[1];
        if(option == "-c"){
            huff->compress(argv[2], argv[3]);
            std::cout << "Compressed " << argv[2] << " into " << argv[3] << "." << std::endl;

        }else if(option == "-x"){
            huff->extract(argv[2], argv[3]);
            std::cout << "Extracted from " << argv[2] << " into " << argv[3] << "." << std::endl;
        }

        delete huff;
    }
    return 0;
}
示例#3
0
void TextEncryptor::processInputStream(istream& input) {
	char c;
	bitset<8> outputSymbol;
	string pattern;
	while (input.get(c)) {
		pattern += ht->getEncodingForSymbol(c);

		while ( pattern.length() >= 8) {
			outputSymbol = bitset<8>(pattern.substr(0, 8));
			char i = (char)outputSymbol.to_ulong();
			operator << (binaryOutput, i);

			pattern.erase(0, 8);
		}
	}

	// If last byte is not completely filled up,
	//   we append bits from white space sysmbol until the end of the last byte...
	if (pattern.length() > 0) {
		string& strWhiteSpace = ht->getEncodingForSymbol(' ');
		size_t curSpaceBit = 0;
		while (pattern.length() < 8) {
			pattern += strWhiteSpace[ curSpaceBit++ % strWhiteSpace.length() ];
		}
		outputSymbol = bitset<8>(pattern);
		char i = (char)outputSymbol.to_ulong();
		operator << (binaryOutput, i);
	}
}
void Test()
{
	int w[] = {5,29,7,8,14,23,3,11};
	HuffmanTree *ht = new HuffmanTree();
	ht->huffmanInit(w, 8);
	ht->printTree(15);
	ht->createHuffmanCode(8);
	ht->printCode(8);
}
HuffmanTree*
HuffmanEncoder::huffmanTreeFromMap(vector<string> huffmanMap)
{
    //Generates a Huffman Tree based on the supplied Huffman Map.Recall that a
    //Huffman Map contains a series of codes(e.g. 'a' = > 001).Each digit(0, 1)
    //in a given code corresponds to a left branch for 0 and right branch for 1.

    HuffmanTree *tree = new HuffmanTree(new HuffmanInternalNode(NULL, NULL));

    for (int i = 0; i < 256; i++) {
        char c = (char) i;
        string code = huffmanMap[i];
        if (code.length() == 0)
            continue;
        HuffmanInternalNode *n = (HuffmanInternalNode*)tree->GetRoot();

        for (unsigned int j = 0; j < code.length() -1; ++j) {
            if (code[j] == '0') {
                if (n->GetLeftChild() != NULL) {
                    n = (HuffmanInternalNode*) n->GetLeftChild();
                }
                else {
                    n->SetLeftChild(new HuffmanInternalNode(NULL, NULL));
                    n = (HuffmanInternalNode*) n->GetLeftChild();
                }
            }
            else {
                if (n->GetRightChild() != NULL) {
                    if (n->IsLeaf()) {
                        //tree->Print();
                        exit(1);
                    }
                    n = (HuffmanInternalNode*) n->GetRightChild();
                }
                else {
                    n->SetRightChild(new HuffmanInternalNode(NULL, NULL));
                    n = (HuffmanInternalNode*) n->GetRightChild();
                }
            }
        }
        c = code[code.length() -1];
        if (c == '0') {
            n->SetLeftChild(new HuffmanLeafNode((char)i, 0));
        }
        else {
            n->SetRightChild(new HuffmanLeafNode((char)i, 0));
        }
    }

    //printf("Tree created from map:\n");
    //tree->Print();

    return tree;
}
示例#6
0
文件: huffman.cpp 项目: nayrk/CS165
int main(){
	ifstream file;
	file.open("Amazon_EC2.txt");
	if(!file.is_open()) cout << "File not found";

	//Create a vector of freqs
	//256 for ascii values initialized to 0
	vector<int> freq(256,0);

	int c;
	int count = 0;
	while(file.good()){
		count++;
		c = file.get();
		//End of file
		if(c < 0) continue;
		freq[c] = freq[c] + 1;
	}
	file.close();

	/*
	for(int i = 0; i < freq.size(); i++){
		if(freq[i] != 0){
			double ratio = ((double)freq[i]/(double)count)*100;
			cout << (char)i <<  " " << ratio << endl;
		}
	}
	*/

	//Instantiate tree
	HuffmanTree tree;
	//Call create to make the tree 
	tree.create(freq);

	//Create output file stream
	ofstream outputFile("compressedFile.txt",ios::out);	
	stream out(outputFile);

	//Open file to get letters to compress with path
	ifstream file2;
	file2.open("Amazon_EC2.txt");

	//Call compress to write bits of each letter to the file
	char z;
	while(file2.good()){
		z = (char)file2.get();	
		tree.compress(z, out);
	}

	file2.close();
	outputFile.close();
	cout << endl << "Outputfile Created: compressedFile.txt" << endl << endl;
	return 0;	
}
示例#7
0
文件: main.cpp 项目: timj-pdx/huffman
int main( int argc, char* argv[] )
{
  if ( argc != 2 ) {
    cerr << "\n    usage: " << argv[0] << " file\n\n";
    return 1;
  }
  string exec = argv[0];
  string fileName = argv[1];
  bool   compressFlag;

  exec.replace(0,exec.find_last_of('/')+1,""); // Get 'basename' of arg[0]
  if (exec == "compress") compressFlag = true;
  else                    compressFlag = false;

  if (compressFlag) {	// Compress

    string compressedFile = fileName + ".hc";

    CountTable  ct(fileName.c_str());
    HuffmanTree ht;

    ct.createCharMap();
    //ct.printCharMap();
    ct.buildNodeList(ht);
    //ht.printNodeList();
    ht.buildTree();
    //ht.printTree();
    ht.genCharSeqTable();
    //ht.printCharSeqTable();

    CompressFile cf(fileName, compressedFile);
    //ht.printNodeList();
    cf.doit(ht);

  } else {		// Uncompress

    string compressedFile   = fileName + ".hc";
    string uncompressedFile = fileName + ".uc";

    //  CountTable  ct(fileName);
    HuffmanTree ht;
    UncompressFile uf(compressedFile, uncompressedFile);

    uf.buildNodeList(ht);
    //ht.printNodeList();
    ht.buildTree();
    //ht.printTree();
    //uf.printCompressedBits();
    uf.doit(ht);

 }

} // End Main()
示例#8
0
int main()
{

    HuffmanTree H;
    char c[50];
    int n=0;
    H.Show(c,n);
    cout<<endl;
    cout<<"请输入01序列#结尾"<<endl;
    cin>>c;
    H.Translate(c);
    return 0;
}
示例#9
0
int main()
{
	ifstream image;
	image.open("/home/cxy229/image/data.dat");
    if(!image.good())     //文件未成功打开
    {
        cerr<<" error:: unable to open image! "<<endl;
        exit(1);
    }
    char aaaa[4]={'a','b','c','d'};
    int w[4]={5,6,7,8};
    HuffmanTree<char> test;
    test.setTree(w,aaaa,4,0);
    test.encode(test.getroot(),"");
    cout<<"d:"<<test.coding('d')<<endl;
	cout<<"c:"<<test.coding('c')<<endl;
    cout<<"b:"<<test.coding('b')<<endl;
    cout<<"a:"<<test.coding('a')<<endl;
    cout<<test.uncoding("010110");
    cout<<endl;

    imgCompressor img;
    img.run();
    return 0;
}
示例#10
0
void imgCompressor::compresse()//图片压缩
{
    ofstream img_com("/home/cxy229/image/img_compressed",ios::app);
    if(!img_com)
    {
        cout<<" fail to open img_compressed"<<endl;
        exit(1);
    }

    ifstream image;
    image.open("/home/cxy229/image/data.dat",ios::in);
    if(!image.good())    //文件未成功打开
    {
        cerr<<" error:: unable to open image! "<<endl;
        exit(1);
    }

    char temp[65];
    string str = "";
    int k = 0;
    while(!image.eof())
    {
        image.getline(temp,65);
        for(k = 0; k < 64; k += 8)
        {
            str = swich(temp + k, 8);
            img_com<<h_tree.coding(str);//将压缩后的编码写入文件
        }
        img_com<<endl;
    }

    image.close();
    img_com.close();
}
示例#11
0
void imgCompressor::decompresse()
{
    ifstream img_com;
    img_com.open("/home/cxy229/image/img_compressed");
    if(!img_com.good())    //文件未成功打开
    {
        cerr<<" error:: unable to open img_compressed! "<<endl;
        exit(1);
    }
    ofstream img_decom("/home/cxy229/image/img_decompressed",ios::out|ios::app);
    if(!img_decom)
    {
        cout<<" fail to open img_decom"<<endl;
        exit(1);
    }

    char temp[100];
    string str;
    while(!img_com.eof())
    {
        img_com.getline(temp,99);
        str = swich(temp,strlen(temp));
        //cout<<str;
        img_decom<<h_tree.uncoding(str)<<endl;
    }
    img_com.close();
    img_decom.close();
}
示例#12
0
void UncompressFile::doit(HuffmanTree& ht)
{
    if (!osPtr.is_open()) {     // Open file
        osPtr.open(outFile.c_str());
        if (!osPtr) {
            cerr << "Error: Could not open: '" << outFile << "' for writing" << endl;
            return;
        }
    }

    unsigned char c;

    while (true) {
        c = ht.getChar(getBit());
        if (c < (unsigned char)'\x80') {
            //      if ( c  > ' ' ) printf("'%c'\n", c);
            //      else            printf("'%02x'\n", c);
            osPtr.put(c);
            continue;
        } else if (c == (unsigned char)EOF) {
            break;
        } else if (c == (unsigned char)'\xf0') { // Not there yet
            continue;
        } else if (c == (unsigned char)'\xf1') {
            cout << "uncompress() : Internal Error\n";
            break;
        }
    }
    if ( isPtr.is_open()) isPtr.close();
    if ( osPtr.is_open()) osPtr.close();

} // End doit()
string
HuffmanEncoder::decodeBits(vector<bool> bits, vector<string> huffmanMap)
{
    HuffmanTree *tree = HuffmanEncoder::huffmanTreeFromMap(huffmanMap);

    vector<string> map = HuffmanEncoder::huffmanEncodingMapFromTree(tree);
    HuffmanEncoder::writeEncodingMapToFile(map, "encmap.map");

    HuffmanNode *n = tree->GetRoot();
    ostringstream result{};
    uint64_t last_index = 0;
    string stack;
    int num_decoded = 0;

    //tree->Print();

    for (auto it = bits.begin(); it != bits.end(); ++it) {
        bool bit = *it;
        if (bit == false) {
            stack += "0";
            n = ((HuffmanInternalNode*)n)->GetLeftChild();
        }
        else {
            stack += "1";
            n = ((HuffmanInternalNode*)n)->GetRightChild();
        }
        if (n->IsLeaf()) {
            result << ((HuffmanLeafNode*)n)->GetValue();
            num_decoded++;
            n = tree->GetRoot();
            stack = "";
        }
        last_index++;
    }

    /* TODO: perhaps the priority queue is different for each? That might
     * explain it. Compare frequencies, that can't be wrong. Issue is we have
     * different huffman maps on each run. Although, that might not be a problem
     * on write. The files are slightly different, make sure it's writing to a
     * good offset. Maybe try writing/reading garbage from that spot or
     * something, print out the first few chars, idk. Print where the offsets
     * and such are. Figure out exactly what is going where and if the way it's
     * getting compressed/decompressed differently is a problem. */


    return result.str();
}
示例#14
0
void addCharacter(HuffmanTree& T,int c,Writer& w)
{
	T.writeCode(T.getLeaf(c),w);
	if (T.getLeaf(c)==T.getLeaf(NYT))
	{
		//cout << c;
		w.writeNine(c);
		T.splitNYT(T.getLeaf(NYT),c);
	}
	T.updateBlockFirst();
	T.updateTree(T.getLeaf(c));
	//cout << (T.getRoot())->getWeight() << endl;
}
示例#15
0
int main(int argc, char* argv[]) {
    if (argc < 4) {
        cerr << "please provide an appropriate flag (-compress/-decompress) and two file names." << endl;
        return -1;
    }

    HuffmanTree tree;
    ifstream in(argv[2], ios::in | ios::binary);
    ofstream out(argv[3], ios::out | ios::binary);

    if (strcmp(argv[1], "-compress") == 0) {
        tree.encode(in, out);
    } else if (strcmp(argv[1], "-decompress") == 0) {
        tree.decode(in, out);
    }

    return 0;
}
示例#16
0
//-------------------------------------------------------------------------------------------------
bool Huffman::createTable(std::vector<unsigned int> symbols, std::vector<unsigned int> counts)
{
	HuffmanTree tree; // Tree for creating the table
	
	// Build the tree
	tree.buildTree(symbols, counts);
	
	// Get the table from the tree
	if(! tree.getTable((*m_pSymbols), (*m_pCodes)))
	{
		std::cerr << "Error in createTable: tree is empty" << std::cout;
		return false;
	}

	//Sort the table by code length for faster average lookup
	sortTable();

	return true;
}
示例#17
0
int main() {
	string line;
	ifstream f("Huffman.txt");
	getline(f, line);
	HuffmanTree* ht = new HuffmanTree(line);
	cout << "original message: " << line << "\n\n";
	ht->buildTable();
	ht->buildHeap();
	ht->displayFreqTable();
	ht->displayHuffTable();
	ht->writeEncodedString();
	ht->decodeHuffman();
	ht->writeDecodedString();
	ht->compressEncodedString();
	ht->decompress();

	system("pause");
	return 0;

}
示例#18
0
void BinaryDecryptor::processInputStream(istream& input) {
	string currentEncoding;
	char desiredSymbol;
	char inputChar;
	bitset<8> inputBits;

	while (input.get(inputChar)) {
		
		inputBits = inputChar;
		string inputString = inputBits.to_string();
		for (size_t i = 0; i < 8; ++i) {
			currentEncoding += inputString[i];
			if (ht->containsEncodingPattern(currentEncoding)) {
				desiredSymbol = ht->getCharFromPattern(currentEncoding);
				textOutput << desiredSymbol;
				currentEncoding.clear();
			}
		}
	}
}
示例#19
0
std::unordered_map<char, std::string>  HuffmanTree::compress_file(std::string inputFile, std::string outputFile) {
    // variables and typedef
    typedef HuffmanTree::HuffmanNode node_type;
    HuffmanTree tree;
    std::unordered_map<char, unsigned int> map;
    std::unordered_map<char, std::string> code_table;
    std::priority_queue<node_type,std::vector<node_type>, HuffmanTree::Compare> prior_q;
    // calling methods
    tree.create_map(map,inputFile);
    tree.fill_queue(prior_q,map);
    HuffmanTree::HuffmanNode node(tree.build_tree(prior_q));
    tree.generate_code_table(node,code_table,"");
    tree.generate_code_file(outputFile, code_table);
    std::string bit_string = tree.generate_bit_string(inputFile,code_table);
    tree.generate_binary_compressed_file(outputFile, bit_string);
    tree.generate_compressed_file(outputFile, bit_string);
    return code_table;
}
示例#20
0
HuffmanTree *HuffmanTreeFactory::BuildTree(u32 code_symbols)
{
	if (_heap.size() < 1) return 0;

	while (_heap.size() > 1)
	{
		HuffmanTreeNode *branch = new HuffmanTreeNode;

		CAT_OBJCLR(*branch);
		ProbabilityType probability_sum = 0.;

		// For each code symbol,
		for (u32 ii = 0; ii < code_symbols; ++ii)
		{
			HuffmanTreeNode *leaf = _heap.top();
			_heap.pop();

			branch->children[ii] = leaf;
			probability_sum += leaf->probability;

			if (_heap.empty())
				break;
		}

		branch->probability = probability_sum;

		// Push the combined branch back on the heap
		_heap.push(branch);
	}

	HuffmanTreeNode *root = _heap.top();
	_heap.pop();

	HuffmanTree *tree = _tree;
	tree->Initialize(code_symbols, root);
	_tree = 0;

	return tree;
}
示例#21
0
void decode() {
    int nCasos;
    string encoded_text, plain_text;

    cout << "decoding..." << endl;

    cin >> nCasos; cin.ignore();

    for (int i = 0; i < nCasos; i++) {
        // Leer el texto codificado
        getline(cin, encoded_text);

        // Leer y reconstruir el árbol de huffman, que viene inorden
        // NOTA: tengo que distinguir entre HuffmanBranch y HuffmanLeaf
        HuffmanTree* ht = HuffmanReader::read();
        cout << ht->to_string() << endl;

        // Una vez que tenemos el texto y el árbol, decodificarlo
        plain_text = Huffman::decode(encoded_text, *ht);
        cout << plain_text << endl;

        //delete ht;
    }
}
示例#22
0
void UncompressFile::buildNodeList(HuffmanTree& ht)
{
    if ( !isPtr.is_open()) {
        isPtr.open(inFile.c_str());
        if (!isPtr) {
            cerr << "Error: Could not open: '" << inFile << "' for reading" << endl;
            return;
        }
    }

    //  char readBuf[readBufSize];
    isPtr.getline((char*)readBuf,readBufSize);

    string buf; // Have a buffer string
    vector<string> token;
    stringstream ss((char*)readBuf);
    unsigned int count;

    // Tokenize the string into a vector
    while (ss >> buf) {
        token.push_back(buf);
        count++;
    }

    // Validate that we have a even number
    if (count % 2 != 0) {
        cerr << "CountTable::extractCharMap() : Internal Error\n";
        return;
    }

    unsigned int c;
    // Convert the first token to 'hex' and the second to 'unsigned'
    for (unsigned i=0; i<token.size(); i+=2) {
        istringstream hex_char(token[i]);
        hex_char >> hex >> c;
        istringstream int_char(token[i+1]);
        int_char >> count;
        ht.buildNodeList(c, count);
    }

    if (isPtr.is_open()) isPtr.close();

} // End buildNodeList()
示例#23
0
TableInfo phuffman::utility::BuildTable(InputIterator first, InputIterator last, Codes& table) {
    using namespace std;
    typedef DepthCounterNode Node;
    typedef multimap<size_t, Node*> HuffmanTree;
    typedef vector<Node*> Nodes;

    assert(distance(first, last) <= constants::MAXIMUM_DATABLOCK_SIZE);
    assert(table.size() >= constants::ALPHABET_SIZE);

    HuffmanTree tree;
    Nodes leafs;
    TableInfo info;

    // Initialize tree
    {
        Frequencies frequencies = CountFrequencies(first, last);
        Frequencies::const_iterator first = frequencies.begin(), last = frequencies.end();
        while (first != last) {
            Node* leaf = new Node(first->symbol);
            tree.insert(make_pair(first->frequency, leaf));
            leafs.push_back(leaf);
            ++first;
        }
    }

    // Build tree
    {
        for (size_t i=0, size=tree.size(); i<size-1; ++i) {
            HuffmanTree::iterator first = tree.begin(), second = tree.begin();
            ++second;
            size_t freq = first->first + second->first; // Calculate freq for a node
            Node* node = new Node(first->second, second->second); 
            ++second;
            tree.erase(first, second); // Remove two nodes with the smallest frequency
            tree.insert(make_pair(freq, node)); // Add node that points to previosly removed nodes
        }
        assert(tree.size() == 1);
    }

    // Count codelengths
    // In fact, codelengths are already counted in the 'depth' member of a node
    // There is only one exception: if the tree contains only one object, we need to set it's depth manually
    Node* root = tree.begin()->second;
    root->depth = 1;

    // Sort nodes by codelength
    sort(leafs.begin(), leafs.end(), TreeComparator);

    // Build table
    {
        Nodes::const_iterator first = leafs.begin(), last = leafs.end();
        Node *curNode = *first;
        info.maximum_codelength = curNode->depth;
        Code curCode = CodeMake(curNode->depth, 0);
        table[curNode->element] = curCode;
        ++first;
        while (first != last) {
            assert(curNode->depth >= curCode.codelength);
            curNode = *first;
            // If current codeword and next codeword have equal lengths
            if (curNode->depth == curCode.codelength) {
            // Just increase codeword by 1
                curCode.code += 1;
            }
            // Otherwise
            else {
                // Increase codeword by 1 and _after_ that shift codeword right
                curCode.code = (curCode.code + 1) >> (curNode->depth - curCode.codelength);
            }
            curCode.codelength = curNode->depth;
            table[curNode->element] = curCode;
            ++first;
        }
    }
    
    delete root;

    return info;
}
示例#24
0
void FileCompress::Uncompress(const char* filename)
{
	HuffmanTree ht;
	int size = 0;
	//从配置文件中获取字符信息
	string filenameconfig = filename;
	filenameconfig += ".config";

	FILE* fout = fopen(filenameconfig.c_str(),"r");
	assert(fout);
	unsigned char ch = fgetc(fout);
	long long sum = 0;
	while (!feof(fout))
	{
		_infos[ch]._ch = ch;
		size++;
		char num = fgetc(fout);
		num = fgetc(fout);
		_infos[ch]._count = num - '0';
		sum += _infos[ch]._count;
		ch = fgetc(fout);
		ch = fgetc(fout);
	}
	fclose(fout);
	//建树
	CharInfo invaild;
	//ReadConfig(filename, _infos);
	ht.CreateTree(_infos, size,invaild);

	//从压缩文件取值遍历
	string filenamecom = filename;
	filenamecom += ".com";
	FILE* fin = fopen(filenamecom.c_str(),"r");
	assert(fin);

	string filenameuncom = filename;
	filenameuncom += ".uncom";

	fout = fopen(filenameuncom.c_str(), "w");
	assert(fout);
	HuffmanTreeNode<CharInfo>* temp = ht.GetRoot();
	ch = fgetc(fin);
	int count = 0;
	unsigned int t = 1;
	while ( !feof(fin))//sum != 0)
	{
		int x = 0;
		for (int i = 7; i >= 0; i--)
		{
			x = ch & (t << 7);
			if ((char)ch == EOF)
			{
				cout << 1;
			}
			ch <<= 1;
			if (x == 0)
				temp = temp->_left;
			else if (x == 0x80)
				temp = temp->_right;
			if (temp->_left == NULL && temp->_right == NULL)
			{
				fputc(temp->_weight._ch, fout);
				//sum--;
				cout << temp->_weight._ch;
				temp = ht.GetRoot();
				x = 0;
			}
		}
		ch = fgetc(fin);
	}
	fclose(fin);
	fclose(fout);
}
示例#25
0
void FileCompress::Compress(const char* filename)
{
	HuffmanTree mh;
	int size = Get_infos_Com(filename);
	//建树
	CharInfo invaild;
	mh.CreateTree(_infos, size,invaild);
	//编码
	string code;
	GenerateHuffmanCode(mh.GetRoot(), code);

	//配置文件
	string filenameConfig = filename;
	filenameConfig += ".config";
	
	FILE* fout = fopen(filenameConfig.c_str(), "wb");

	assert(fout);
	for (int i = 0; i < 256; i++)
	{
		if (_infos[i]._count != 0)
		{
			fputc(_infos[i]._ch, fout);
			fputc(',', fout);
			fputc(_infos[i]._count+'0',fout);
			fputc('\n',fout);
		}
	}
	fclose(fout);
	//WriteConfig(filename);
	FILE* fin = fopen(filename, "r");
	unsigned char ch = fgetc(fin);

	string filenamecom = filename;
	filenamecom += ".com";

	fout = fopen(filenamecom.c_str(), "w+");
	assert(fout);
	
	unsigned char value = 0;
	int pos = 7;

	while (!feof(fin))
	{
		if (ch == '\r')
		{
			ch = fgetc(fout);
			if (ch != '\n')
			{
				fseek(fout, -1, SEEK_CUR);
			}
		}
		string& code = _infos[ch].code;
		int d = 0;
		for (int i = 0; i < code.size(); i++)
		{
			value <<= 1;
			if ((code[i] - '0') & (1))
			{
				value |= 1;
			}
			else
			{
				value |= 0;
				d = 1;
			}
			pos--;

			if (pos == -1)
			{
				fputc(value, fout);
				if (d = 0)
				{
					cout << 1;
				}
				value = 0;
				d = 0;
				pos = 7;
			}
		}
		ch = fgetc(fin);
	}
	if (pos != -1)
	{
		for (int i = 0; i <= pos; i++)
		{
			value <<= 1;
		}
		fputc(value, fout);
	}
	fclose(fin);
	fclose(fout);
}
示例#26
0
int main()
{
	string text;
	bool BeingInit = 0, BeingEncode = 0;
	HuffmanTree *tree;
	char *c;
	int *value;
	int n;
	int select;
	while (true)
	{
		cout << "1.initialization" << endl;
		cout << "2.write text to file" << endl;
		cout << "3.Encoding" << endl;
		cout << "4.Decoding" << endl;
		cout << "5.Print CodeFile" << endl;
		cout << "6.TreePrinting" << endl;
		cout << "7.show The Huffman code" << endl;
		cout << "8.exit" << endl;
		cin >> select;
		switch (select)
		{
		case 1:
			int t; 
			cout << "1.build a new HuffmanTree" << endl;
			cout << "2.load from the file" << endl; 
			cin >> t;
			while (true)
			{
				if (t == 1)
				{
					cout << "输入字符个数:";
					cin >> n;
					c = new char[n];
					value = new int[n];
					for (int i = 0; i<n; i++)
					{
						cout << "第" << i + 1 << "个字符:";
						cin >> c[i];
						cout << "第" << i + 1 << "个权值:";
						cin >> value[i];
					}
					tree = new HuffmanTree(value, n, c);
					break;
				}
				if (t == 2)
				{
					tree = new HuffmanTree;
					break;
				}
			}
			cout << "initialization success!" << endl;
			BeingInit = 1;
			tree->save();
			break;
		case 2:cout << "input your text: "; cin >> text;
			tree->writefile(text);
			cout << "OK!" << endl;
			break;
		case 3:if (!BeingInit) { cout << "the tree is not exist" << endl; break; }
			   tree->Encoding();
			   cout << "succeed in encoding!" << endl;
			   BeingEncode = 1;
			   break;
		case 4:if (!BeingInit) { cout << "the tree is not exist" << endl; break; }
			   if (!BeingEncode) { cout << "the tree haven't been encode, you must encoding before!" << endl; break; }
			   tree->Decoding();
			   cout << "succeed in decoding!" << endl;
			   break;
		case 5:if (!BeingInit) { cout << "the tree is not exist" << endl; break; }
			   if (!BeingEncode) { cout << "the tree haven't been encode, you must encoding before!" << endl; break; }
			   tree->Print(); cout << endl; break;
		case 6:if (!BeingInit) { cout << "the tree is not exist" << endl; break; }
			   tree->printing();
			   break;
		case 7:tree->Huffmancode(); cout << endl; break;
		case 8:exit(0);
		default:break;
		}
	}
示例#27
0
void imgCompressor::buildTree()
{
    h_tree.setTree(wei,color,sum,"");
    h_tree.encode(h_tree.getroot(),"");
}
int
main(int argc, char ** argv)
{
    if (argc != 4) // 检查参数数量
    {
        showUsage();
        return 1;
    }
    else
    {
        filename = argv[1];
        // 判断文件名的后缀是不是 ".hfm"
        if (string(".hfm") != filename.substr(filename.length()-4, 4))
        {
            fprintf(stderr, "输入文件的后缀不是 .hfm 。\n");
            return 1;
        }
        treeFilename = argv[2];
        sscanf(argv[3], "%lu", &bitLength);
    }

    // 载入哈夫曼树
    HuffmanTree tree;
    tree.loadFromFile(treeFilename.c_str());

    // 构造映射表
    // 映射表是将字符映射到一个二进制序列的表
    constructMapping(&tree, vector<int>());
    
    // 打开待解码的文件
    iBitFile bin((filename).c_str());

    // 打开输出的文件
    // file 定义在了本文件头部,为了方便函数 commitBuffer 而调整。
    file = fopen((filename.substr(0, filename.length()-4)).c_str(), "wb");
    
    // 解码
    HuffmanTree * p = &tree;
    for (size_t i=0; i<bitLength; ++i)
    {
        int bit = bin.readNextBit();
        p = p->childs[bit];
        if (p == NULL)
        {
            fprintf(stderr, "待解码文件和树文件似乎不是对应的。");
            return 1;
        }
        if (p->key != -1)
        {
            writeToBuffer((unsigned char)p->key);
            p = &tree;
        }
    }

    commitBuffer(bufferpos);

    fclose(file);
    bin.close();
    fflush(stdout);

    return 0;
}
示例#29
0
#define CATCH_CONFIG_MAIN
#include "catch.hpp"

#include <fstream>
#include <iostream>
#include <sstream>
#include <stdio.h>
#include <unordered_map>

#include "huffman.h"

using namespace ptlmuh006;

TEST_CASE("Files correctly compressed", "[compression]") {
    HuffmanTree huff;

    SECTION("Frequency table corectly generated") {
        //GIVEN: A string of data
        std::string data = "aaabbbccc   dddddddddd\nccc";

        //WHEN: We count the frequency of the characters in the string of data
        std::unordered_map<char, int> freqTbl = huff.countFrequency(data);

        //THEN: We should get a correct frequency table with characters mapped to tallys
        REQUIRE( freqTbl.size() == 6 );
        REQUIRE( freqTbl['a'] == 3 );
        REQUIRE( freqTbl['b'] == 3 );
        REQUIRE( freqTbl['c'] == 6 );
        REQUIRE( freqTbl[' '] == 3 );
        REQUIRE( freqTbl['d'] == 10 );
        REQUIRE( freqTbl['\n'] == 1 );
示例#30
0
bool Compress::compress() {
    File * f = new File(m_path, m_fileName);
    QByteArray qba = f->read();
    if (qba != NULL) {
        CountOccurrence * co = new CountOccurrence(qba);
        QList<Occurrence> occur = co->orderByOccurrence();
        HuffmanTree * cht = new HuffmanTree(occur);
        Tree * tree = cht->createTree();
        tree->createRep();
        cht->createHash(tree);

        QString data;
        for (int i = 0; i < qba.size(); ++i) {
            QString pathNode = cht->hash()->value(qba.at(i));
            data.append(pathNode);
        }

        int garbageSize = 8 - data.size()%8;
        if (garbageSize == 8) {
            garbageSize = 0;
        }
        for (int i = 0; i < garbageSize; ++i) {
            data.append("0");
        }

        QBitArray toByte;
        toByte.resize(data.size());
        for (int i = 0; i < data.size(); ++i) {
            if (data.at(i) == '0') {
                toByte[i] = true;
            }
            else {
                toByte[i] = false;
            }
        }

        bool ok;
        QByteArray encoded;
        QString c;
        for (int i = 0; i < data.size(); i+=8) {
            QString h = data.mid(i,8);
            encoded.append(QChar(h.toInt(&ok, 2)));
            c.append(h);
        }

        QString binaryGarbageSize = QString::number(garbageSize,2);
        QString binaryTreeSize = QString::number(tree->rep().size(),2);
        int zeros = 16 - (binaryGarbageSize.size() + binaryTreeSize.size());
        for (int i = 0; i < zeros; ++i) {
            binaryTreeSize.prepend(QString::number(0));
        }

        QString toBit = binaryGarbageSize;
        toBit.append(binaryTreeSize);

        int h1 = toBit.mid(0,8).toInt(&ok, 2);
        int h2 = toBit.mid(8,8).toInt(&ok, 2);

        QByteArray toWrite;
        toWrite.clear();
        toWrite.append(QChar(h1));
        toWrite.append(QChar(h2));
        toWrite.append(m_fileName);

        for (int i = m_fileName.size(); i < 128; ++i ) {
            toWrite.append("#");
        }

        toWrite.append(tree->rep());
        toWrite.append(encoded);

        f->write(toWrite, m_path + m_compressedFileName);

        qDebug() << m_fileName << " comprimido";

        return true;
    } else {
        qDebug() << "Arquivo não encontrado";

        return false;
    }
}