00001
00002 #include "decompressore.h"
00003
00004 int decompressore::elevato (int a, int b)
00005 {
00006 if (a == 0) return 0;
00007 int app = 1;
00008 for (int i = 0; i < b; i++)
00009 app *= a;
00010 return app;
00011 }
00012
00013
00014
00015
00016 int decompressore::traduci (char c)
00017 {
00018 int a = 0;
00019 for (int i = 0; i < 8; i++)
00020 a = a + ((c >> (i)) & 1) * elevato(2,i);
00021 return a;
00022 }
00023
00024 #if DEBUG
00025 #include <iostream>
00026 #endif
00027
00028 #if DEBUG
00029 namespace dec
00030 {
00031 void preorderp (node* tree)
00032 {
00033 if (tree == 0) return;
00034 cout << tree -> left << ' ' << tree -> right << endl;
00035 preorderp (tree -> left);
00036 preorderp (tree -> right);
00037 }
00038 void preorder (node* tree)
00039 {
00040 if (tree == 0) return;
00041 cout << tree -> c << ' ' << tree -> freq << endl;
00042 preorder (tree -> left);
00043 preorder (tree -> right);
00044 }
00045 void postorder (node* tree)
00046 {
00047 if (tree == 0) return;
00048 postorder (tree -> left);
00049 postorder (tree -> right);
00050 cout << tree -> c << ' ' << tree -> freq << endl;
00051 }
00052 void inorder (node* tree)
00053 {
00054 if (tree == 0) return;
00055 inorder (tree -> left);
00056 cout << tree -> c << ' ' << tree -> freq << endl;
00057 inorder (tree -> right);
00058 }
00059 }
00060 #endif
00061
00062 decompressore::decompressore(const char file[], const char fileo[])
00063 {
00064 stream.open(fileo, ios::out|ios::binary);
00065 if (!stream) throw "apertura";
00066 #if DEBUG
00067 cout << "apertura ultimata" << endl;
00068 system ("PAUSE");
00069 #endif
00070 contatore = 8;
00071 IOl in(file,pf,num);
00072
00073 #if DEBUG
00074 cout << "vettorizzazione, stampo risultati" << endl;
00075 cout << "vettore pf:" << endl;
00076 for (int i = 0; i < num; i++)
00077 cout << pf[i]->c << ' ' << pf[i]->freq << endl;
00078 system ("PAUSE");
00079 #endif
00080 occorrenze = new int[256];
00081 for (int i = 0; i < 256; i++)
00082 occorrenze [i] = 0;
00083 heap hp(pf,num);
00084 #if DEBUG
00085 cout << "generazione heap completata" << endl;
00086 for (int i = 0; i < num; i++)
00087 cout << hp.v[i] -> c << ' ' << hp.v[i]->freq << endl;
00088 system ("PAUSE");
00089 #endif
00090
00091 int last = hp.lastn();
00092 root = huffman (hp, last);
00093 pun = root;
00094 delete[] pf;
00095
00096 pf = 0;
00097 #if DEBUG
00098 cout << "costruzione albero ultimata" << endl;
00099 dec::preorder (root);
00100 cout << "--------" << endl;
00101 dec::postorder (root);
00102 cout << "--------" << endl;
00103 dec::inorder (root);
00104 system ("PAUSE");
00105 #endif
00106
00107 buffer[0] = in.leggi();
00108 if (buffer[0] == -1) throw "vuoto";
00109 int p = riempibuffer(in);
00110 if (p == -1) throw "vuoto";
00111 #if DEBUG
00112 cout << "primo riempimento eseguito con successo" << endl;
00113 for (int i = 0; i < 8; i++)
00114 cout << buffer[i] << ' ';
00115 cout << endl;
00116 #endif
00117 traduci(in);
00118 #if DEBUG
00119 cout << "traduzione terminata" << endl;
00120 #endif
00121 delete[] occorrenze;
00122 occorrenze = 0;
00123 cancella (root);
00124 pun = 0;
00125 }
00126
00127 node* decompressore::huffman (heap H, int last)
00128 {
00129 for(int i = 0; i < last; i++)
00130 {
00131 node* t = new node;
00132 if (t == 0) throw "memoria";
00133 t->left = H.estrai();
00134 t->right = H.estrai();
00135 t->freq= t->left->freq + t->right->freq;
00136 H.inserisci(t);
00137 }
00138 return H.estrai();
00139 }
00140
00141 int decompressore::riempibuffer(IOl& in)
00142
00143 {
00144 if (contatore != 8) throw "contatore";
00145 contatore = 0;
00146 for (int i = 1; i < 8; i++)
00147 {
00148 int a = in.leggi();
00149 if (a == -1) return -1;
00150 buffer[i] = a;
00151 }
00152
00153 #if DEBUG
00154 cout << "riempimento ultimato" << endl;
00155 for (int i = 0; i < 8; i++)
00156 cout << buffer[i] << ' ';
00157 cout << endl;
00158 #endif
00159 return 1;
00160 }
00161
00162 void decompressore::traduci(IOl& in)
00163 {
00164 if (root -> left == 0 && root -> right == 0)
00165 {
00166 int mem = in.leggi();
00167 while (mem != -1)
00168 {
00169 stream.put (root->c);
00170 if (++contatore == 8)
00171 {
00172 buffer[0] = mem;
00173 riempibuffer(in);
00174 mem = in.leggi();
00175 }
00176 }
00177 if (mem == -1)
00178 while (buffer[contatore++] == 1)
00179 stream.put (root -> c);
00180 return;
00181 }
00182 int mem = in.leggi();
00183
00184
00185
00186 while (mem != -1)
00187 {
00188 for (int i = 0; i < 8; i++)
00189 {
00190 if (contatore > 7 || contatore < 0)
00191 throw "contatore";
00192 if (buffer[contatore] == 0) pun = pun -> left;
00193 if (buffer[contatore] == 1) pun = pun -> right;
00194 contatore++;
00195 if (pun -> left == 0 && pun -> right == 0)
00196 {
00197 int intc = traduci (pun -> c);
00198 if(occorrenze[intc] == pun -> freq)
00199 throw "lettura";
00200 occorrenze[intc]++;
00201 stream.put(pun -> c);
00202 pun = root;
00203 }
00204 }
00205 buffer[0] = mem;
00206 riempibuffer(in);
00207 mem = in.leggi();
00208 }
00209 ultimo();
00210 return;
00211 }
00212
00213 void decompressore::ultimo()
00214 {
00215 #if DEBUG
00216 cout << "ultimo buffer" << endl;
00217 system ("PAUSE");
00218 for (int i = 0; i < 8; i++)
00219 cout << buffer[i] << ' ';
00220 cout << endl;
00221 #endif
00222 for (int i = 0; i < 8; i++)
00223 {
00224 if (contatore > 7 || contatore < 0) throw "contatore";
00225 if (buffer[contatore] == 0) pun = pun -> left;
00226 if (buffer[contatore] == 1) pun = pun -> right;
00227 contatore++;
00228 if (pun -> left == 0 && pun -> right == 0)
00229 {
00230 int intc = traduci (pun -> c);
00231 if(occorrenze[intc] == pun -> freq)
00232
00233
00234 return;
00235 occorrenze[intc]++;
00236 stream.put(pun -> c);
00237 pun = root;
00238 }
00239 }
00240 }
00241
00242 void decompressore::cancella(node*& tree)
00243
00244 {
00245 if (tree==0) return;
00246 cancella (tree ->left);
00247 cancella (tree -> right);
00248 delete tree;
00249 tree = 0;
00250 }
00251
00252
00253
00254
00255