/*--Function for Decompressor--*/ void decompress(struct bitio* file_to_read,struct bitio* file,lz78_decompressor* in) { //char * out=malloc(sizeof(char)*150); char out[50]; out[0]='\0'; int i=0; int j=0; char first_char=0; file_to_read=bit_open(in->file_to_decompress,0); if(file_to_read==NULL){ printf("File not found or you don't have enough privilege to open a file\n"); return; } uint64_t inp=0; int temp=0; char prec_char=0; int first_father; int ret=0; int x=0; //fseek(file_to_read->f,4,SEEK_SET); in->info_ptr=getinfo(file_to_read); reset: while(x>=0){ ret=bit_read(file_to_read,16,&inp); first_father=temp=(int)(inp&((1UL<<16)-1))-1; if(first_father<=0)goto fine_file; while((first_char=look_up_array(temp))==-1){ out[i]=(char)array_tree[temp].c; temp=(int)array_tree[temp].father_num; i++; } if(ret<=0) { fine_file:printf("The file was correctly extracted...\n"); //no more data to read flush_out_buffer(file); break; } out[i]=first_char; if(x==0){ prec_char=(int)(inp&((1UL<<16)-1))-1; //printf("ricevuto :%d Inserisco il nodo %d con padre %d\n",first_father,(int)in->counter_child_tree-1,prec_char); array_tree[(int)in->counter_child_tree-1].father_num=(int)((inp&((1UL<<16)-1))-1); in->counter_child_tree++; } if(x>0){ //printf("Inserisco %c nel nodo %d temp:%d\n",array_tree[temp].c,(int)in->counter_child_tree-2,temp); array_tree[(int)in->counter_child_tree-2].c=array_tree[temp].c; //printf("Inserisco il nodo %d con padre %d\n",(int)in->counter_child_tree-1,(int)(inp&((1UL<<16)-1))-1); /*I have to add a new node*/ array_tree[(int)in->counter_child_tree-1].father_num=(int)(inp&((1UL<<16)-1))-1; out[0]=((int)in->counter_child_tree-2==(int)((inp&((1UL<<16)-1))-1))?array_tree[temp].c:(char)array_tree[(int)((inp&((1UL<<16)-1))-1)].c; //If i have received the last node insert, i have to update the output string becouse i didn't have the char of the node received in->counter_child_tree++; } //out[i+1]='\0'; for(j=i;j>=0;j--){bit_write(file,8, out[j]); //printf("%c",(out[j])); } // I print the buffer string //printf("\n"); i=0; x++; out[0]='\0'; if(in->counter_child_tree>=in->d_max-1){ //need to empty the array based tree for the decompressor free(array_tree); in->counter_child_tree=0; array_init(6700417,in); x=0; goto reset; } } /*rewind(file_to_read->f); uint64_t r; bit_read(file_to_read,8,&r); printf("%c aad\n",(char)r&((1UL<<8)-1)); bit_read(file_to_read,8,&r); printf("%c aad\n",(char)r&((1UL<<8)-1)); bit_read(file_to_read,8,&r); printf("%c aad\n",(char)r&((1UL<<8)-1)); bit_read(file_to_read,8,&r); printf("%c aad\n",(char)r&((1UL<<8)-1)); */ bit_close(file_to_read); }
int arithmetic_decoding(const char* encoded_file, const char* decoded_file) { FILE* fout; uint8_t byte; int i; int i_ss; int i_d; int n; int bitc = 0; uint64_t tmp, mask, stream_slice; int bits_to_read; struct CST* cumulative_sums_tree_pointer; struct BitBuffer* bbp = bit_open(encoded_file, BIT_BUFFER_READ); if (bbp == NULL) { printf("%s: No such file\n", encoded_file); return -1; } cumulative_sums_tree_pointer = CST_create(NUM_CODEPOINTS); if (cumulative_sums_tree_pointer == NULL) { printf("Error: CST creation failed\n"); bit_close(bbp); return -1; } fout = fopen(decoded_file, "wb"); if (fout == NULL) { printf("Error: cannot create output file %s\n", decoded_file); return -1; } // we deal with the zero-frequency problem initializing all counters to 1 and consequently NUM_CODEPOINTS to total_count total_count = NUM_CODEPOINTS; for (i=1; i<NUM_CODEPOINTS; i++) counter_increment(cumulative_sums_tree_pointer, i); LOW = 0; HIGH = 0xFFFFFFFFFFFFFFFF; bits_to_read = sizeof(uint64_t) * 8; stream_slice = 0x0000000000000000; for (;;) { n = bit_read(bbp, &tmp, bits_to_read); if (n == -1) { printf("Error occurred!!\n"); return -1; } // here n could be zero, but this is not a concern bitc+=n; if (bits_to_read == sizeof(uint64_t) * 8) mask = 0xFFFFFFFFFFFFFFFF; else mask = ((uint64_t)1 << bits_to_read) - 1; stream_slice = ((stream_slice << bits_to_read) | (tmp & mask)); /* i = 0; mask = 0x0000000000000001; while (i < bits_to_read) { stream_slice <<= 1; if (tmp & mask) stream_slice |= 0x0000000000000001; mask <<= 1; i++; } */ n = bs(cumulative_sums_tree_pointer, stream_slice); if (n == -1) return -1; if (n == NUM_CODEPOINTS - 1) // EOF symbol received break; byte = (uint8_t)n; fwrite(&byte, 1, 1, fout); tmp = ((HIGH - LOW) / total_count); HIGH = LOW + tmp * (cumulative_sums_lookup(cumulative_sums_tree_pointer, byte + 1)); LOW = LOW + tmp * cumulative_sums_lookup(cumulative_sums_tree_pointer, byte); // deadlock resolution if ((HIGH & 0xC000000000000000) == 0x8000000000000000 && (LOW & 0xC000000000000000) == 0x4000000000000000) { i_d = 2; mask = 0x2000000000000000; while (mask && (LOW & mask) && (HIGH & mask) == 0) { i_d++; mask >>= 1; } LOW &= ~mask; HIGH |= mask; HIGH <<= i_d; LOW <<= i_d; } else
/*--Function for compress file--*/ void compress(char * str_in,lz78_compressor * in, struct bitio* file) { char* buf=malloc(16); uint64_t inp=0; int father=0; int child=0; int go=1; uint64_t c=0; int flag=0; int ret=0; struct bitio*file_out=bit_open(in->output_file,1); /*After compress i put the info of the file at the beginning of the file*/ info* ret_info=malloc(sizeof(info)); /*Put the info at the beginning of the file and return a structure with the info*/ ret_info=addinfo(file_out,file,in->file_to_compress,0,in->d_max); in->number_of_code^=in->number_of_code; //XOR reset: if(flag==0){ /*Only for the first character*/ ret=bit_read(file,(u_int)8,&inp); buf[1]=(char)(inp&((1UL<<8)-1)); //printf("Ric: %X\n",buf[1] & 0xff); } printf("-----------\n"); while(go==1){ while(look_up_and_add(father,buf[1],in)==0){//repeat the operation until i don't fint a node =>scroll the tree buf[0]=buf[1]; father=hash_table[hash(child,(char)(inp&((1UL<<8)-1)))].child_index; //printf("Padre: %d\n",father); ret=bit_read(file,(u_int)8,&inp); buf[1]=(char)(inp&((1UL<<8)-1)); //printf("Ric: %X\n",buf[1] & 0xff); child=father; } //printf("Output: %X Char %c\n",father & 0xff,buf[1]); bit_write(file_out,16, (int) father); in->number_of_code++; father=0; // restart from the root child=0; c++; if(ret==0)break; if(in->counter_child_tree>=in->d_max-1){ //I need to empty the tree and restart the compressio from the current position free(hash_table); in->counter_child_tree=0; hash_init(6700417,in); goto reset; }; } flush_out_buffer(file_out); //add the SHA-1 of the compressed-file in the header long old_index=ftell(file_out->f);//save the curren pointer to position of the file struct bitio* file_out_rd=bit_open(in->output_file,0);//I re-open the output file but in in read mode this time getSHA1(88,in->number_of_code,file_out_rd,ret_info); //I do the SHA-1 over the whole file bit_close(file_out_rd); fseek(file_out->f,(long)0x40,SEEK_SET); //I write the SHA-1 hash in the correct position //printf("SHA-1: "); for (int i = 0; i < 20; i ++) { bit_write(file_out,(u_int)8*sizeof(unsigned char),(unsigned char)ret_info->sha1[i]); // printf(" %2x", (unsigned char)ret_info->sha1[i]); } bit_write(file_out,(u_int)32,in->number_of_code); //printf("\n"); flush_out_buffer(file_out); fseek(file_out->f,old_index,SEEK_SET); // restore the pointer of the file in order to close the file in the rigth way //close the file descriptor bit_close(file_out); }