Tfe

Ongi etorri tfe-ren webgunera...

Old stuff/ecole_etude_fac_de_pau/licence_3/projet_lzw/include/inflater.cpp

(Deskargatu)

/*
    This file is part of projet_lzw_univ_pau.

    projet_lzw_univ_pau is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    projet_lzw_univ_pau is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with projet_lzw_univ_pau; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/



#include "inflater.h"
#include <iostream>

/* Fonction append d un buffer sur un autre */
void transfert(std::vector<char>& a,std::vector<char>& b)
{
	for(int i=0;i<a.size();i++)
	{
	    b.push_back(a[i]);	
	}
	a.clear();
}


/* Constructeur */
Inflater::Inflater()
{
    commence=0; // booleen pour savoir si on traite le premier buffer
    std::pair<unsigned  int,char > valeur;
    valeur.first=0;
    valeur.second='\0';
    dico.push_back(valeur);        
    unsigned  int a=0;
    
    // Ajout des elements ascii 0.0 a 0.255 dans le dico
    for (int i=0;i<256;i++)
    {
	valeur.second = i;
	add_word(valeur);
    }
    

}



/* Fonction d'ajout  d'un buffer */
void Inflater::setInput(std::vector<unsigned  int>& msg)
{

    for(int i=0;i<msg.size();i++)
	{
	buffer.push_back(msg[i]);
	}
	msg.clear();
}


/* Fonction inutilisee */
int Inflater::needInput() {   }


/* Ajout d un mot dans le dictionnaire */    
void Inflater::add_word(const std::pair<unsigned  int,char>& valeur) 
{   
     dico.push_back(valeur);   
}


/* Trouve un mot dans le dictionnaire */
int Inflater::find_word(const unsigned  int& recherche)
{
return dico.size() > recherche;
}


/* Fonction de decompressoin */
int Inflater::inflate(int methode)
{
    if (buffer.empty()) { return 0 ; }
    decompression.clear(); // on vide le buffer 
    int demande=0;
    std::vector<char> portion;
    std::pair<unsigned  int,char > valeur;
    std::pair<unsigned  int,char > tempo;
    
    int current=1; // on commence au 2eme nombre !
    int size=buffer.size(); // capture la taille totale pour ne pas la recalculer par la suite
    
    
    if (commence==0)
    {
    valeur  = dico[buffer[0]];
    portion.clear();
    while(valeur.first != 0)
    {
	portion.push_back(valeur.second); // on ajoute les elements correspondant au buffer[current]
	valeur=dico[valeur.first];	
    }
    portion.push_back(valeur.second); // on ajoute les elements finals
    reverse(portion.begin(),portion.end()); // ordre inverse d'arrivee...
    transfert(portion,decompression); // on ajoute le tout dans la decompression finale
    }
    commence=1;
    while(size>1 && demande == 0)
    {
	if (size<2 && methode==1)
	{
	    demande=1;
	}
	else
	{
	valeur.first=buffer[0];
        if (find_word(buffer[1]))	{ tempo=dico[buffer[1]];} 
	else    { tempo=dico[buffer[0]]; } // cas special 
	
	while(tempo.first != 0)
	{
	    tempo= dico[tempo.first]; // on garde la partie de gauche 
	}
	valeur.second=tempo.second;
	add_word(valeur); // ajout du nouveau mot
    
	valeur = dico[buffer[1]];
	portion.clear();
	
	// On cherche les elements a afficher
	while(valeur.first != 0)
	{
	portion.push_back(valeur.second);
	valeur=dico[valeur.first];	
	}
	portion.push_back(valeur.second);
	// Affiche dans  l ordre inverse */
	reverse(portion.begin(),portion.end());
	transfert(portion,decompression);
	
	
	buffer.erase(buffer.begin());
	size=buffer.size();
	}
    }

    return 1;
}