+ /* Descomprimo */
+ FILE *fp_out;
+ Uint32 block_size = 0,zgungrouped = 0, k;
+ unsigned char *block, *mtf, *orig;
+ unsigned char *z, *zgbuffer;
+ int zgmoved = 0,z_len=0,moredata = 0,decoded = 0;
+ unsigned char use_zg = 0,zgbyte = 0,retbytes = 0;
+ HUFF_STATE *shuff;
+ ZG zg;
+
+ /* Inicializo el descompresor */
+ if ((shuff = shuff_init_decoder(src, NULL)) == NULL) return 1;
+
+ /* Abrimos el archivo de salida */
+ fp_out = fopen(dst, "wb");
+
+ /* Descomprimo primero que nada el pagesize utilizado para comprimir */
+ if (!(moredata = shuff_decode_chunk(shuff,(char*)&block_size,sizeof(Uint32),&decoded))) return 1;
+
+ /* Descomprimo byte que indica si se usa ZG */
+ if (!(moredata = shuff_decode_chunk(shuff, &use_zg, 1, &decoded))) return 1;
+ if (use_zg) zg_init(&zg);
+
+ /* Creo buffers */
+ zgbuffer = malloc(sizeof(unsigned char)*256);
+ block = malloc(block_size*sizeof(unsigned char)+sizeof(Uint32));
+ orig = malloc(block_size*sizeof(unsigned char));
+
+ /* Descomprimimos de a chunks segun convenga */
+ do {
+ if (block_size > 0) {
+ /* Descomprimo el Zlen y el Z del MTF*/
+ moredata = shuff_decode_chunk(shuff,(char*)&z_len,sizeof(int),&decoded);
+ z = malloc(sizeof(unsigned char)*z_len);
+ moredata = shuff_decode_chunk(shuff,z,z_len,&decoded);
+
+ /* Veo si se uso Zero Grouping para comprimir */
+ if (use_zg) {
+ /* Desagrupo bytes hasta completar la pagina or End of Source File */
+ zgungrouped = 0;
+ do {
+ /* Levanto un byte zerogrouped y lo paso por el zg_ungroup */
+ zgmoved = 0;
+ moredata = shuff_decode_chunk(shuff,&zgbyte,1,&decoded);
+ retbytes = zg_ungroup(&zg,zgbuffer,zgbyte);
+ /* Muevo del zgbuffer a mi bloque lo que corresponda */
+ while ((zgmoved < retbytes) && (zgungrouped < block_size+sizeof(Uint32))) {
+ block[zgungrouped++] = zgbuffer[zgmoved++];
+ }
+ } while ((moredata) && (zgungrouped < block_size+sizeof(Uint32)));
+
+ /* Me fijo si el ultimo byte procesado que me completo la pagina fue un 0 */
+ if (zgbyte == 0) {
+ /* Leo un byte mas (un 0 seguro) y zg_ungroup cambiara su estado */
+ moredata = shuff_decode_chunk(shuff,&zgbyte,1,&decoded);
+ zg_ungroup(&zg,zgbuffer,zgbyte);
+ }
+
+ /* Normalizo variables para continuar en common code */
+ decoded = zgungrouped;
+ }
+ else {
+ /* Levanto una salida de MTF */
+ moredata = shuff_decode_chunk(shuff,block,block_size+sizeof(Uint32),&decoded);
+ }
+
+ /* Le aplico MTF inverso a la salida de MTF levantada previamente */
+ mtf = jacu_mtf_inv(z, block, decoded);