]> git.llucax.com Git - z.facultad/75.06/jacu.git/blob - src/blocksorting/bs.c
Abro el archivo fuente de una compresion antes de inicializar el huffman para evitar...
[z.facultad/75.06/jacu.git] / src / blocksorting / bs.c
1
2 #include "bs.h"
3 #include <stdlib.h>
4
5 /* Block Sorting Optimizado en memoria! */
6
7 typedef struct _bs_decode_t_ {
8         char c;
9         Uint32 sig;
10 } t_BlockSortDecode;
11
12 char es_menor(char *data, t_BlockSort *bs, int i, int j);
13
14 int _compare(const void *d1, const void *d2) {
15         t_BlockSortDecode *s1, *s2;
16
17         s1 = (t_BlockSortDecode *)d1;
18         s2 = (t_BlockSortDecode *)d2;
19
20         /* Hack si es el mismo caracter, dejo como mejor la de menor sig */
21         if (s1->c == s2->c) {
22                 return (s1->sig - s2->sig);
23         }
24
25         return (s1->c - s2->c);
26 }
27
28 int __compare(const void *d1, const void *d2) {
29         t_BlockSortData *s1, *s2;
30
31         s1 = (t_BlockSortData *)d1;
32         s2 = (t_BlockSortData *)d2;
33
34         return  es_menor(s1->bs->data, s1->bs, s1->pos_inicial, s2->pos_inicial);
35 }
36
37 char es_menor(char *data, t_BlockSort *bs, int i, int j)
38 {
39         Uint32 pi, pj, k;
40
41         for(k=0; k<bs->len; k++) {
42                 pi = (i+k)%bs->len;
43                 pj = (j+k)%bs->len;
44
45                 if (data[pi] > data[pj]) return 1; /* El primero es mayor */
46                 if (data[pi] < data[pj]) return -1; /* El primero es menor */
47         }
48
49         /* Son iguales! */
50         return 0;
51 }
52
53 void generar_array(char *data, t_BlockSort *bs)
54 {
55         int i;
56         for(i=0; i<bs->len; i++) {
57                 bs->array[i].pos_inicial = i;
58                 bs->array[i].pos_final = (i+bs->len-1)%bs->len;
59                 bs->array[i].ord = (i==0)?1:0;
60                 bs->array[i].bs = bs;
61         }
62 }
63
64 void ordenar_array(char *data, t_BlockSort *bs)
65 {
66         qsort(bs->array, bs->len, sizeof(t_BlockSortData), __compare);
67 }
68
69 int generar_salida(char *data, t_BlockSort *bs, char *salida)
70 {
71         Uint32 i, k;
72         char *out;
73
74         /* Dejo lugar para guardar el K */
75         out = salida + sizeof(Uint32);
76
77         k=-1;
78         for(i=0; i<bs->len; i++) {
79                 out[i] = data[bs->array[i].pos_final];
80                 if (bs->array[i].ord == 1) k = i;
81         }
82         return k;
83 }
84
85 void bs_solve(char *in, char *out, t_BlockSort *bs, Uint32 *k, Uint32 leido)
86 {
87         unsigned int l;
88         l = bs->len;
89         /* Hack para pedasos menores a la pagina */
90         if (leido < bs->len) bs->len = leido;
91         bs->data = in;
92
93         generar_array(in, bs);
94         ordenar_array(in, bs);
95         (*k) = generar_salida(in, bs, out);
96
97         /* Guardo el k y el tamaƱo en el array */       
98         memcpy(out, k, sizeof(Uint32));
99         bs->len = l;
100 }
101
102 void bs_restore(char *dst, char *c, Uint32 k, Uint32 len)
103 {
104         Uint32 i, current;
105         t_BlockSortDecode *in;
106
107         in = malloc(sizeof(t_BlockSortDecode)*len);
108
109         for(i=0; i<len; i++) {
110                 in[i].c = c[i];
111                 in[i].sig = i;
112         }
113
114         qsort(in, len, sizeof(t_BlockSortDecode), _compare);
115         
116         current = k;
117         i=0;
118         do {
119                 dst[i++] = in[current].c;
120                 current = in[current].sig;
121         } while (current != k);
122         free(in);
123 }
124
125 t_BlockSort *bs_create(Uint32 len)
126 {
127         t_BlockSort *tmp;
128
129         tmp = malloc(sizeof(t_BlockSort));
130         tmp->array = malloc(sizeof(t_BlockSortData)*len);
131         tmp->len = len;
132
133         return tmp;
134 }
135
136
137 void bs_destroy(t_BlockSort *bs)
138 {
139         free(bs->array);
140         free(bs);
141 }
142
143 int bs_readblock(FILE *fp, char *data, Uint32 pagesize)
144 {
145         Uint32 i=0;
146
147         while ((!feof(fp)) && (i < pagesize)) {
148                 data[i++] = fgetc(fp);
149         }
150
151         /* Saco un EOF que lee de mas */
152         if (i<pagesize) i--;
153
154         return i;
155 }
156