2 #include "psiGonzalo.h"
5 // IMPLEMENTACI�N DAS FUNCI�NS
7 void destroyGonzaloCompressedPsi(GonzaloCompressedPsi *compressedPsi) {
9 //free(compressedPsi->Hlen.s.spos);
10 //free(compressedPsi->Hacc.s.spos);
11 freeHuff2(compressedPsi->Hlen);
12 freeHuff2(compressedPsi->Hacc);
13 free(compressedPsi->cPsi);
14 free(compressedPsi->bposS);
18 GonzaloCompressedPsi gonzaloCompressPsi(uint *Psi, uint psiSize, uint T, uint HUFF) {
20 GonzaloCompressedPsi compressedPsi;
41 // Construe os arboles de huffman, o dos valores directos
42 // e o das lonxitudes dos runs. Usa como vectores auxiliares de frecuencias
43 // a acc e lacc, que finalmente libera.
44 acc = (uint *)malloc (HUFF*sizeof(uint));
45 lacc = (uint *)malloc ((samplen-1)*sizeof(uint));
46 for (k=0;k<HUFF;k++) acc[k]=0;
47 for (k=0;k<samplen-1;k++) lacc[k]=0;
51 for (i=0;i<=links;i++) {
52 if ((k == 1) && (i % samplen)) { if (ok != 1) oi = i; }
59 if ((k < 1) || (k >= HUFF)) acc[0]++;
62 ok = (i % samplen) ? k : 0;
71 Hacc = createHuff (acc,HUFF-1, UNSORTED);
72 Hlen = createHuff (lacc,samplen-2, UNSORTED);
74 pslen = bits(psiSize+1);
75 _bplen = bits(Hacc.total+Hlen.total+(1+links/samplen+totexc)*pslen);
76 _bposS = (uint *)malloc ((((1+links/samplen)*_bplen+W-1)/W)*sizeof(uint));
77 _cPsi = (uint *)malloc (((Hacc.total+Hlen.total+(1+links/samplen+totexc)*pslen+W-1)/W)*sizeof(uint));
83 for (i=0;i<=links;i++) {
85 if ((k == 1) && (i % samplen)) { if (ok != 1) oi = i; }
88 _cptr = encodeHuff (Hacc,1,_cPsi,_cptr);
89 _cptr = encodeHuff(Hlen,i-oi-1,_cPsi,_cptr);
92 if ((k > 1) && (k < HUFF)) _cptr = encodeHuff (Hacc,k,_cPsi,_cptr);
94 _cptr = encodeHuff (Hacc,0,_cPsi,_cptr);
95 bitwrite (_cPsi,_cptr,pslen,Psi[i]);
100 bitwrite (_bposS,(i/samplen)*_bplen,_bplen,_cptr);
101 bitwrite (_cPsi,_cptr,pslen,Psi[i]);
105 ok = (i % samplen) ? k : 0;
110 _cptr = encodeHuff (Hacc,1,_cPsi,_cptr);
111 _cptr = encodeHuff(Hlen,i-oi-1,_cPsi,_cptr);
114 // Calculamos o espacio total
115 totalSize = (((1+links/samplen)*_bplen+W-1)/W)*sizeof(uint) +
116 ((Hacc.total+Hlen.total+(1+links/samplen+totexc)*pslen+W-1)/W)*sizeof(uint) +
117 5*sizeof(int) + sizeHuff2(Hacc) + sizeHuff2(Hlen);
118 printf("\n\tCompressed Psi size = %d bytes\n", totalSize);
120 // Necesario antes de decodificar
121 prepareToDecode(&Hacc);
122 prepareToDecode(&Hlen);
124 // Asignamos os valores e devolvemos psi comprimido
125 compressedPsi.links = psiSize;
126 compressedPsi.totexc = totexc;
127 compressedPsi.cPsi = _cPsi;
128 compressedPsi.samplen = samplen;
129 compressedPsi.bposS = _bposS;
130 compressedPsi.bplen = _bplen;
131 compressedPsi.pslen = pslen;
132 compressedPsi.Hacc = Hacc;
133 compressedPsi.Hlen = Hlen;
134 compressedPsi.totalMem = totalSize;
139 return compressedPsi;
144 int getGonzaloPsiValue(GonzaloCompressedPsi *compressedPsi, unsigned int position) {
146 uint *cPsi = compressedPsi->cPsi;
147 uint samplen = compressedPsi->samplen;
148 uint *bposS = compressedPsi->bposS;
149 uint bplen = compressedPsi->bplen;
150 uint pslen = compressedPsi->pslen;
151 THuff *Hacc = &compressedPsi->Hacc;
152 THuff *Hlen = &compressedPsi->Hlen;
154 uint sampj,cptr,val,dval,rlen,head,hlen;
156 sampj = (position/samplen)*samplen;
157 cptr = bitread(bposS,(sampj/samplen)*bplen,bplen);
159 val = bitread(cPsi,head,pslen);
162 while (sampj < position) {
164 head = decodeHuff(Hacc,&dval,cPsi,head);
168 val = bitread(cPsi,head,pslen);
174 head = decodeHuff(Hlen,&rlen,cPsi,head);
176 if (sampj + rlen >= position) return val + (position-sampj);
192 void storeGonzaloCompressedPsi(GonzaloCompressedPsi *compressedPsi, char *filename) {
198 if( (file = open(filename, O_WRONLY|O_CREAT, 0700)) < 0) {
199 printf("Cannot open file %s\n", filename);
203 // Copias locales dos arboles de HUFFMAN
204 Hacc = compressedPsi->Hacc;
205 Hlen = compressedPsi->Hlen;
207 write(file, &(compressedPsi->links), sizeof(int));
208 write(file, &(compressedPsi->totexc), sizeof(int));
209 write(file, &(compressedPsi->samplen), sizeof(int));
210 write(file, &(compressedPsi->bplen), sizeof(int));
211 write(file, &(compressedPsi->pslen), sizeof(int));
212 // Almacenar o arbol de huffman principal
213 write(file, &Hacc.max, sizeof(int));
214 write(file, &Hacc.lim, sizeof(int));
215 write(file, &Hacc.depth, sizeof(int));
216 // write(file, Hacc.s.spos, (Hacc.lim+1)*sizeof(int));
217 write(file, Hacc.s.symb, (Hacc.lim+1)*sizeof(int));
218 write(file, Hacc.num, (Hacc.depth+1)*sizeof(int));
219 write(file, Hacc.fst, (Hacc.depth+1)*sizeof(int));
220 // Fin de almacenar o arbol de huffman principal
221 // Almacenar o arbol de huffman das lonxitudes dos runs
222 write(file, &Hlen.max, sizeof(int));
223 write(file, &Hlen.lim, sizeof(int));
224 write(file, &Hlen.depth, sizeof(int));
225 // write(file, Hlen.s.spos, (Hlen.lim+1)*sizeof(int));
226 write(file, Hlen.s.symb, (Hlen.lim+1)*sizeof(int));
227 write(file, Hlen.num, (Hlen.depth+1)*sizeof(int));
228 write(file, Hlen.fst, (Hlen.depth+1)*sizeof(int));
229 // Fin de almacenar o arbol de huffman das lonxitudes dos runs
230 write(file, compressedPsi->bposS, ((compressedPsi->bplen*(1+compressedPsi->links/compressedPsi->samplen)+W-1)/W)*sizeof(uint));
231 write(file, compressedPsi->cPsi, ((Hacc.total+Hlen.total+(1+compressedPsi->links/compressedPsi->samplen+compressedPsi->totexc)*compressedPsi->pslen+W-1)/W)*sizeof(int));
233 write(file, &(compressedPsi->totalMem), sizeof(int));
240 GonzaloCompressedPsi loadGonzaloCompressedPsi(char *filename) {
242 GonzaloCompressedPsi compressedPsi;
249 if( (file = open(filename, O_RDONLY)) < 0) {
250 printf("Cannot read file %s\n", filename);
253 read(file, &(compressedPsi.links), sizeof(int));
254 read(file, &(compressedPsi.totexc), sizeof(int));
255 read(file, &(compressedPsi.samplen), sizeof(int));
256 read(file, &(compressedPsi.bplen), sizeof(int));
257 read(file, &(compressedPsi.pslen), sizeof(int));
258 // Cargamos o arbol de Huffman principal
259 read(file, &Hacc.max, sizeof(int));
260 read(file, &Hacc.lim, sizeof(int));
261 read(file, &Hacc.depth, sizeof(int));
262 //Hacc.s.spos = (unsigned int *) malloc((Hacc.lim+1)*sizeof(int));
263 Hacc.s.symb = (unsigned int *) malloc((Hacc.lim+1)*sizeof(int));
264 Hacc.num = (unsigned int *) malloc((Hacc.depth+1)*sizeof(int));
265 Hacc.fst = (unsigned int *) malloc((Hacc.depth+1)*sizeof(int));
266 //read(file, Hacc.s.spos, (Hacc.lim+1)*sizeof(int));
267 read(file, Hacc.s.symb, (Hacc.lim+1)*sizeof(int));
268 read(file, Hacc.num, (Hacc.depth+1)*sizeof(int));
269 read(file, Hacc.fst, (Hacc.depth+1)*sizeof(int));
270 compressedPsi.Hacc = Hacc;
271 // Fin da carga do arbol de Huffman principal
272 // Cargamos o arbol de Huffman coas lonxitudes dos runs
273 read(file, &Hlen.max, sizeof(int));
274 read(file, &Hlen.lim, sizeof(int));
275 read(file, &Hlen.depth, sizeof(int));
276 //Hlen.s.spos = (unsigned int *) malloc((Hlen.lim+1)*sizeof(int));
277 Hlen.s.symb = (unsigned int *) malloc((Hlen.lim+1)*sizeof(int));
278 Hlen.num = (unsigned int *) malloc((Hlen.depth+1)*sizeof(int));
279 Hlen.fst = (unsigned int *) malloc((Hlen.depth+1)*sizeof(int));
280 //read(file, Hlen.s.spos, (Hlen.lim+1)*sizeof(int));
281 read(file, Hlen.s.symb, (Hlen.lim+1)*sizeof(int));
282 read(file, Hlen.num, (Hlen.depth+1)*sizeof(int));
283 read(file, Hlen.fst, (Hlen.depth+1)*sizeof(int));
284 compressedPsi.Hlen = Hlen;
285 // Fin da carga do arbol de Huffman coas lonxitudes dos runs
286 compressedPsi.bposS = (uint *) malloc (((compressedPsi.bplen*(1+compressedPsi.links/compressedPsi.samplen)+W-1)/W)*sizeof(uint));
287 read(file, compressedPsi.bposS, ((compressedPsi.bplen*(1+compressedPsi.links/compressedPsi.samplen)+W-1)/W)*sizeof(uint));
288 compressedPsi.cPsi = (uint *) malloc (((Hacc.total+Hlen.total+(1+compressedPsi.links/compressedPsi.samplen+compressedPsi.totexc)*compressedPsi.pslen+W-1)/W)*sizeof(uint));
289 read(file, compressedPsi.cPsi, ((Hacc.total+Hlen.total+(1+compressedPsi.links/compressedPsi.samplen+compressedPsi.totexc)*compressedPsi.pslen+W-1)/W)*sizeof(uint));
291 read(file, &(compressedPsi.totalMem), sizeof(int));
294 return compressedPsi;