Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <vector>
- #include <iostream>
- #include <fstream>
- using namespace std;
- struct recordLZW{
- unsigned short index;
- unsigned short prev_index;
- recordLZW(unsigned short index,unsigned short prev_index){
- this->index = index;
- this->prev_index = prev_index;
- }
- bool operator==(const recordLZW& r){
- return (index==r.index)&&(prev_index==r.prev_index);
- }
- };
- class LZW{
- private:
- const char* txtfilename;
- const char* lzfilename;
- ifstream infile;
- ofstream outfile;
- vector<recordLZW> dictionary;
- int inDictionary(const recordLZW& r){
- for(unsigned int i = 0;i<dictionary.size();++i) if(dictionary[i] == r) return i;
- return -1;
- }
- public:
- LZW(const char* txtfilename, const char* lzfilename){
- this->txtfilename = txtfilename;
- this->lzfilename = lzfilename;
- for(unsigned short i=0;i<256;++i) {
- recordLZW tmp(i,0);
- dictionary.push_back(tmp);
- }
- }
- void drawDictionary(){
- for(unsigned int i=256;i<dictionary.size();++i) cout<<i<<":"<<dictionary[i].prev_index<<"("<<(char)dictionary[i].prev_index<<") "<<dictionary[i].index<<"("<<(char)dictionary[i].index<<")"<<endl;
- }
- char firstChar(unsigned short code){
- if(!dictionary[code].prev_index)
- return (char)dictionary[code].index;
- do{
- if(dictionary[code].prev_index<255) return (char)dictionary[code].prev_index;
- else code = dictionary[code].prev_index;
- }while(true);
- }
- void decompress(){
- infile.open(lzfilename,ifstream::binary);
- outfile.open(txtfilename,ofstream::binary);
- unsigned short current_code;
- unsigned short previous_code = 0;
- char* buffer = new char[65535];
- infile.read((char*)&previous_code,sizeof(unsigned short));
- outfile.put((char)previous_code);
- while(true){
- int bufsize = 0;
- if(infile.good()){
- infile.read((char*)¤t_code,sizeof(unsigned short));
- if(infile.eof()) break;
- if(dictionary.size()>current_code){ //ячейка dictionary[current_code] заполнена
- //выводим table[current_code]
- int picode = current_code;
- do{
- buffer[bufsize++] = (char)dictionary[picode].index;
- if(dictionary[picode].prev_index<256) {
- if(dictionary[picode].prev_index>0)
- buffer[bufsize++]=(char)dictionary[picode].prev_index;
- break;
- }
- else picode = dictionary[picode].prev_index;
- }while(true);
- for(int i=bufsize-1;i>=0;--i){
- outfile.put(buffer[i]);
- }
- //выволы
- recordLZW tmp((unsigned short)firstChar(current_code), previous_code);
- dictionary.push_back(tmp);
- previous_code = current_code;
- }else{//если ячейки не существу
- recordLZW tmp((unsigned short)firstChar(previous_code),previous_code);
- dictionary.push_back(tmp);
- int picode = dictionary.size() - 1;
- do{
- buffer[bufsize++] = (char)dictionary[picode].index;
- if(dictionary[picode].prev_index<256) {
- if(dictionary[picode].prev_index>0)
- buffer[bufsize++]=(char)dictionary[picode].prev_index;
- break;
- }
- else picode = dictionary[picode].prev_index;
- }while(true);
- for(int i=bufsize-1;i>=0;--i){
- outfile.put(buffer[i]);
- }
- }
- }else{
- break;
- }
- }
- delete[] buffer;
- //drawDictionary();
- infile.close();
- outfile.close();
- }
- void STUPIDdecompress(){
- infile.open(lzfilename,ifstream::binary);
- outfile.open(txtfilename,ofstream::binary);
- unsigned short current_code;
- char* buffer = new char[65535];
- unsigned short old_code = 0;
- while(true){
- infile.read((char*)¤t_code, sizeof(unsigned short));
- int bufsize = 0;
- if(infile.good()){
- if(current_code<256){
- recordLZW tmp(current_code,old_code);
- cout<<current_code;
- outfile.put((char)current_code);
- if(old_code){
- dictionary.push_back(tmp);
- cout<<" Добавляем 1 "<<dictionary.size()-1<<" "<<dictionary[dictionary.size() - 1].prev_index<<","<<dictionary[dictionary.size() - 1].index<<endl;
- }
- }else{
- cout<<"Нужен "<<current_code<<" имеется "<<dictionary.size()-1<<endl;
- if(dictionary.size()>current_code){
- //outfile.put((char)dictionary[current_code].prev_index);
- //outfile.put((char)dictionary[current_code].index);
- int picode = current_code;
- cout<<"Record: "<<current_code<<" - "<<dictionary[current_code].prev_index<<","<<dictionary[current_code].index<<endl;
- bufsize=0;
- do{
- buffer[bufsize++] = (char)dictionary[picode].index;
- if(dictionary[picode].prev_index<256) {
- buffer[bufsize++]=(char)dictionary[picode].prev_index;
- break;
- }
- else picode = dictionary[picode].prev_index;
- }while(true);
- for(int i=bufsize-1;i>=0;--i){
- outfile.put(buffer[i]);
- }
- }else{
- //oldcode first char
- char fch = firstChar(old_code);
- //cout<<"FC "<<fch<<endl;
- recordLZW tmp(fch,old_code);
- dictionary.push_back(tmp);
- cout<<"Добавляем 2 "<<dictionary.size()-1<<" "<<dictionary[dictionary.size() - 1].prev_index<<","<<dictionary[dictionary.size() - 1].index<<endl;
- if(old_code>255) { // Дописать алгоритм распаковки буфера на лету
- int picode = old_code;
- bufsize=0;
- do{
- buffer[bufsize++] = (char)dictionary[picode].index;
- if(dictionary[picode].prev_index<256) {
- buffer[bufsize++]=(char)dictionary[picode].prev_index;
- break;
- }
- else picode = dictionary[picode].prev_index;
- }while(true);
- for(int i=bufsize-1;i>=0;--i){
- outfile.put(buffer[i]);
- }
- }else{
- outfile.put((char)old_code);
- }
- outfile.put(fch);
- }
- //continue;//FIX IT
- }
- old_code = current_code;
- }else break;
- }
- delete[] buffer;
- drawDictionary();
- infile.close();
- outfile.close();
- }
- void compress(){
- infile.open(txtfilename,ifstream::binary);
- outfile.open(lzfilename,ofstream::binary);
- unsigned char buffer;
- unsigned short prefix = 0;
- while(true){
- infile.read((char*)&buffer,1);
- if(infile.good()) {
- recordLZW tmp(static_cast<unsigned short>(buffer),prefix);
- int find_index = inDictionary(tmp);
- cout<<"Структура :"<<tmp.prev_index<<"("<<(char)tmp.prev_index<<") "<<tmp.index<<"("<<(char)tmp.index<<")";
- if(find_index>=0) {
- cout<<" [найдена]"<<endl;
- prefix = (unsigned short)find_index;
- //if(prefix>255){
- //outfile.write((char*)&prefix,sizeof(prefix));
- //prefix = buffer;
- //cout<<prefix<<" "<<sizeof(prefix)<<endl;
- //}
- }
- else{
- dictionary.push_back(tmp);
- //if(prefix<=255) //FIX IT исправлено для абракадабры, для других может не работать. лишний 00 01
- outfile.write((char*)&prefix,sizeof(unsigned short));
- //cout<<prefix<<endl;
- cout<<" [добавлена]"<<endl;
- prefix = buffer;
- }
- }else{
- if(prefix) outfile.write((char*)&prefix,sizeof(unsigned short));
- break;
- }
- }
- cout<<endl<<dictionary.size() - 256;
- cout<<endl;
- infile.close();
- outfile.close();
- drawDictionary();
- }
- };
Add Comment
Please, Sign In to add comment