示例#1
0
文件: test_bitio.c 项目: danyf90/lz78
int main(int argc, char* argv[]) {
	struct bitio *bd;
	uint64_t d, r;
	int i;

	//TEST 1: writes 0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF23456789ABCDEF
	if ((bd = bitio_open("bitio_test.dat", 'w')) == NULL) {
		perror("bopen(w)");
		exit(EXIT_FAILURE);
	}
	d = 0x0123456789ABCDEF;
	bitio_write(bd, d, 64);
	bitio_write(bd, d, 56);
	d = 0x23456789ABCDEF01;
	bitio_write(bd, d, 64);
	bitio_write(bd, d, 64);
	bitio_close(bd);

	if ((bd = bitio_open("bitio_test.dat", 'r')) == NULL) {
		perror("bopen(r)");
		exit(EXIT_FAILURE);
	}

	for (i = 1; i <= 3; i++) {
		bitio_read(bd, &r, 64);
		if (r != 0x0123456789ABCDEF)
			exit(EXIT_FAILURE);
	}

	bitio_read(bd, &r, 56);
	if (r != 0x23456789ABCDEF)
		exit(EXIT_FAILURE);

	bitio_close(bd);
	//delete file
	unlink("bitio_test.dat");

	//TEST 2: stdin and stdout
	while(bitio_read(bstdin, &r, 1) > 0) {
		bitio_write(bstdout, r, 1);
	}

	bitio_flush(bstdout);

	exit(EXIT_SUCCESS);
}
示例#2
0
文件: main.c 项目: Jaxx89/lz78
int main() {
  struct bitio* b=bit_open("prova.txt", "w");
  uint64_t a;
  bitio_write(b, 'a', 64);
  bitio_write(b, 'b', 64);
  bitio_write(b, 'c', 32);
  bitio_write(b, 'd', 8);
  bitio_write(b, 'd', 8);
  bitio_write(b, 'd', 8);
  bitio_write(b, 0x08, 6);
  bitio_write(b, 0xefafbfcf, 32);
  bitio_write(b, 'a', 64);
  bitio_write(b, 'b', 64);
  bitio_write(b, 'a', 64);
  bitio_close(b);
  b=bit_open("prova.txt", "r");
  return 0;
}
示例#3
0
int main(int argc, char **argv)
{
   bitio *b = NULL;
   uint64_t data = UINT64_MAX;
   int ret;
   
   if (!(b = bitio_open("test2", O_RDONLY)))
   {
       perror("bitio_open");
       exit(-1);
   }

   for(int i = 0; i<1; i++ )
   {
       ret = bitio_read(b, &data, 32);
       ret = bitio_read(b, &data, 64);
       if (ret)
       {
           printf("ret %d\n", ret);
           break;
       }
       fprintf(stderr,"%016llX -> %" PRIu64 "\n",
              (long long unsigned int)data,
              data);
        ret = bitio_read(b, &data, 32);

       /*ret = bitio_read(b, &data, 64);
       if (ret)
       {
           printf("ret %d\n", ret);
           break;
       }
       fprintf(stderr,"%016llX -> %" PRIu64 "\n",
              (long long unsigned int)data,
              data);*/
   }
   bitio_close(b);

   return 0;
}
示例#4
0
int64_t decompress(const char* in_filename, const char* out_filename, uint8_t flags) {

    struct bitio		*bd = bstdin;
    struct dictionary	*d = NULL;
    struct utimbuf		*t = NULL;
    FILE*				fout = stdout;
    char				*out_file = NULL;
    uint8_t				bits, initial_bits, meta_type, meta_size;
    uint16_t			c;
    uint32_t			bitMask, cur, first_record, len, next_record, dict_size = 0, written = 0, write_count = 0;
    uint64_t			filesize = 0;
    char				*word;
    int					first = 1, md5c_size = 0, md5d_size = 0;
    void				*meta_data, *md5c = NULL, *md5d = NULL;
    EVP_MD_CTX			*md_ctx = NULL;

    if (in_filename != NULL) {
        bd = bitio_open(in_filename, 'r');
        if (bd == NULL)
            goto error;
    }

    //read metadata
    while ((meta_data = meta_read(bd, &meta_type, &meta_size)) != META_END) {
        LOG("META_TYPE: %d", meta_type);
        switch (meta_type) {
        case META_DICT_SIZE:
            dict_size = *(uint32_t*)meta_data;
            PRINT(1, "Dictionary Size:\t%d\n", dict_size);
            break;

        case META_NAME:
            PRINT(1, "Original file name:\t%s\n", (char*)meta_data);
            if (flags & DEC_ORIG_FILENAME) {
                out_file = malloc(meta_size);
                if (out_file == NULL)
                    goto error;
                memcpy((void*)out_file, meta_data, meta_size);
                out_filename = out_file;
            }
            break;

        case META_MD5:
            md5c = malloc(meta_size);
            memcpy(md5c, meta_data, meta_size);
            md5c_size = meta_size;
            word = sprinth(md5c, md5c_size);
            PRINT(1, "Original md5sum:\t%s\n", word);
            free(word);
            // initialize md context
            OpenSSL_add_all_digests();
            md_ctx = malloc(sizeof(EVP_MD_CTX));
            EVP_MD_CTX_init(md_ctx);
            EVP_DigestInit(md_ctx, EVP_get_digestbyname("md5"));
            md5d_size = EVP_MD_CTX_size(md_ctx);
            md5d = malloc(md5d_size);
            break;

        case META_TIMESTAMP:
            t = malloc(sizeof(*t));
            t->actime = *((time_t*)meta_data); // access time
            t->modtime = *((time_t*)meta_data); // modification time
            break;

        default: // META_ERROR
            LOG("Unknown metadata");
            errno = EINVAL;
            goto error;
        }
        free(meta_data);
    }

    if ((flags & DEC_ORIG_FILENAME) && out_file == NULL) // if i have DEC_ORIG_FILENAME setted but no info in metadata i use stdin as outfile
        out_filename = "stdin";

    if (out_filename != NULL) {
        fout = fopen(out_filename, "w");
        if (fout == NULL)
            goto error;
    }

    if (out_filename != NULL && in_filename != NULL && strcmp(in_filename, out_filename) == 0) {
        errno = EINVAL;
        goto error;
    }

    if (dict_size == 0)
        goto error;

    d = dict_new(dict_size, 0, dict_size, NUM_SYMBOLS);

    if (d == NULL)
        goto error;

    first_record = dict_init(d);
    next_record = first_record;
    initial_bits = 0;
    bitMask = 1;
    while (bitMask < next_record) {
        bitMask <<= 1;
        initial_bits++;
    }
    bits = initial_bits;

    for (;;) {
        // put in cur the index of the fetched word in the dictionary
        cur = fetch(bd, bits);
        if (cur == ROOT_NODE)
            goto error;

        if (cur == EOF_SYMBOL)
            break;

        c = dict_first_symbol(d, cur);

        if (c == EOF_SYMBOL)
            goto error;

        if (!first) {
            // complete previous record with index of new record
            // ROOT_NODE as current node value means 'don't change it'.
            dict_fill(d, next_record, ROOT_NODE, (uint8_t) c, 0);
            next_record++;
            if ((next_record+1) & bitMask) {
                bitMask <<= 1;
                bits++;
            }
        }
        else
            first = 0;

        // get the word in the dictionary at index cur.
        word = dict_word(d, cur, &len);
        if (word == NULL)
            goto error;

        written = fwrite(word, 1, len, fout);

        if (written < len)
            goto error;
        else { // md5 computation and visual feedback

            if (md5c != NULL) // compute md5 of decompressed
                EVP_DigestUpdate(md_ctx, word, len);

            write_count += written;
            if (write_count >= COUNT_THRESHOLD) {
                filesize += write_count;
                write_count = 0;
                PRINT(1, ".");
            }
        }

        if (next_record + 1 == dict_size) {

            next_record = first_record;

            bits = initial_bits;
            bitMask = 1 << bits;

            first = 1; // set first iteration to be the next
        }

        // add a new record
        dict_fill(d, next_record, cur, 0, 0); // symbol will be filled at the beginning of next iteration

    }

    filesize += write_count;

    if (md5c != NULL) {
        EVP_DigestFinal_ex(md_ctx, md5d, (unsigned int*)&md5d_size);

        if (md5c_size == md5d_size && memcmp(md5c, md5d, md5c_size) == 0)
            PRINT(1, "\nmd5sum Check:\t\tOK");
        else {
            PRINT(1, "\nmd5sum Check:\t\tFailed");
            goto error;
        }
    }

    PRINT(1, "\nDecompression Finished\n\n");

    fclose(fout);
    if (out_file != NULL && t != NULL)
        if (utime(out_filename, t) < 0) { // set modification time
            PRINT(1, "Error while changing last modification time");
        }
    free(out_file);
    free(t);
    dict_delete(d);
    bitio_flush(bd);
    if (bd != bstdin)
        bitio_close(bd);
    return filesize;

error:
    PRINT(1, "\n");
    if (out_filename != NULL)
        unlink(out_filename);
    free(out_file);
    free(t);
    dict_delete(d);
    bitio_flush(bd);
    if (bd != bstdin)
        bitio_close(bd);
    if (fout != NULL)
        fclose(fout);
    return -1;
}
示例#5
0
文件: comp.c 项目: Jaxx89/lz78
/* compressor algorithm for lz78:
 * from is the path of the file to compress, size is the size of the dictionary
 * to is the compressed file name, it can be chose by the user, 
 * 		otherwise a standard name is put in its place*/
void compress(char* from, char* to, int size){
	
	//fprintf(stderr, "compressor\n");
    //int, i, flen;	//length of filename
    //int i;
    unsigned int tmp=0; //temporary variable in which we put the byte read    
    unsigned int itmp=0, size_tmp=0; //itmp is the index to write;
    int position=0, father=0; //postion in the dictionary
    //int fd=open(filename,  'r'); //file descriptor
    dictionary* dict=malloc(sizeof(dictionary)); //dictionary
    int blen=1;     //bit lenght of my dictionary's indexes
    size_tmp=size;
    struct bitio* bit;
    header hdr;		//header of the file
    int result=0;
	int longest_match=1, tmp_longest_match=0;
	FILE* file_read, *file_write;
    
    //compute how many bit to write in the compressed file 
    while(size_tmp>>=1) blen++;
    
    fprintf(stderr, "blen: %i\n", blen);
    
    //initialize the dictionary
    dict_init(dict, size, 256);
    
    father=0;
    
    //initialize the bitio structure to write bits instead of bytes
    bit=bit_open(to, "w");
    if(bit==NULL) fprintf(stderr, "null bitio\n");
    
    
    //creation of the header of the file
    hdr.dictionary_size=size;
	hdr.longest_match=0;	//prepare the space for the overwriting
	
    //write the header in the top of the file
    //flen=strlen(hdr.extension);
    bitio_write(bit, (uint64_t)hdr.dictionary_size, sizeof(int)*8);
	bitio_write(bit, (uint64_t)hdr.longest_match, sizeof(int)*8);
    //for(i=0; i<6; i++)
		//bitio_write(bit, (uint64_t)hdr.extension[i], sizeof(char)*8);
    
    //read a byte from the file
    //fprintf(stderr, "%i\n", fd);
    if(from==NULL) file_read=stdin;
	else file_read=fopen(from, "r");
    //fprintf(stderr, "%c\n", (char)tmp);
	
	//first read
	result=fread(&tmp, 1, 1, file_read);
	
    father=tmp;
	
	//read the file until reach the EOF or an error occurs
    do {
			
		//read one byte from the file
		result=fread(&tmp, 1, 1, file_read);
		//fprintf(stderr, "%i ",tmp );        
		
		itmp=father;	
		tmp_longest_match++;
		//search if we already have the actual string in the dictionary
		position=dict_search(&father, tmp, dict);
		//fprintf(stderr, "new_father: %i %i\n", father, position);
		
		if(position!=0) {
			if(longest_match < tmp_longest_match) 
				longest_match = tmp_longest_match;
			tmp_longest_match=0;
			//add the string in the dictionary
			dict_add_word(position, father, tmp, dict);
			//fprintf(stderr, "%i: %i %i\n", position, father, tmp);
			
			bitio_write(bit, (uint64_t)itmp, blen);
			//fprintf(stderr,  "\n");
			father=tmp;
		}
	} while(result!=0 || !feof(file_read));
    //write the last position reached
    bitio_write(bit, father, blen);
    
    //close all the structures writing EOFC on the compressed file
    bitio_write(bit, EOFC, blen);
    bitio_close(bit);
	//fprintf(stderr, "%i\n", longest_match);
	
	//write the longest match in the file
	file_write=fopen(to, "r+b");
	fseek(file_write, sizeof(int), SEEK_SET); 
	hdr.longest_match=longest_match;
	fwrite(&hdr.longest_match, sizeof(int), 1, file_write);
	fclose(file_write);
	
    //free all other structures
    suppress_dictionary(dict);
    free(dict);
	fclose(file_read);
    
    
    fprintf(stderr, "compression executed\n");
}
示例#6
0
文件: compressor.c 项目: danyf90/lz78
int64_t compress(const char* in_filename, const char* out_filename, uint32_t dict_size, uint32_t ht_size, uint8_t flags) {

	struct bitio		*bd = bstdout;
	struct dictionary	*d = NULL;
	struct stat			file_stat;
	time_t				t;
	FILE				*fin = stdin;
	char				*md5_str;
	int					c, read_count = 0;
	uint8_t				bits, initial_bits;
	uint32_t			bitMask, cur, next_record, y;
	uint64_t			filesize = 0;
	unsigned char		*md5;


	if (out_filename != NULL && in_filename != NULL && strcmp(in_filename, out_filename) == 0) {
		errno = EINVAL;
		goto error;
	}

	if (in_filename != NULL) {
		fin = fopen(in_filename, "r");
		if (fin == NULL)
			goto error;
	}

	if (out_filename != NULL) {
		bd = bitio_open(out_filename, 'w');
		if (bd == NULL)
			goto error;
	}

	//write metadata
	if (flags & META_DICT_SIZE)
		if (meta_write(bd, META_DICT_SIZE, &dict_size, sizeof(dict_size)) < 0)
			goto error;

	if (flags & META_MD5) {
		if (fin != stdin) {
			int md5_size;

			md5 = compute_digest(fin, "md5", &md5_size);
			if (meta_write(bd, META_MD5, md5, md5_size) < 0)
				goto error;
			md5_str = sprinth(md5, md5_size);
			PRINT(1, "md5sum:\t\t\t%s\n", md5_str);
			free(md5);
			free(md5_str);
		}
		else
			PRINT(1, "md5sum:\t\t\tNot availabe when reading from stdin\n");
	}

	if ((flags & META_NAME) && in_filename != NULL) { //don't put META_NAME if input = stdin
		c = path_len(in_filename);
		if (meta_write(bd, META_NAME, (void*)&in_filename[c], strlen(in_filename) - c + 1) < 0)
			goto error;
	}

	if ((flags & META_TIMESTAMP) && in_filename != NULL) { //don't put META_TIMESTAMP if input = stdin
		fstat(fileno(fin), &file_stat);
		t = file_stat.st_mtime;
		if (meta_write(bd, META_TIMESTAMP, &t, sizeof(t)) < 0)
			goto error;
	}

	if (meta_finalize(bd) < 0)
		goto error;

	d = dict_new(dict_size, 1, ht_size, NUM_SYMBOLS);

	if (d == NULL)
		goto error;

	next_record = dict_init(d);
	initial_bits = 0;
	bitMask = 1;
	while (bitMask < next_record) {
		bitMask <<= 1;
		initial_bits++;
	}
	bits = initial_bits;
	bitMask = 1 << bits;
	
	cur = ROOT_NODE;
	for(;;) {
  		c = fgetc(fin);
		if (c == EOF) {

			//emit last word
			if (emit(bd, cur, bits) < 0)
				goto error;

			//emit EOF
			dict_lookup(d, ROOT_NODE, EOF_SYMBOL, &y);

			if (emit(bd, y, bits) < 0)
				goto error;

			break;
		}
		
		filesize++;

		if (VERBOSE_LEVEL > 0 && ++read_count >= COUNT_THRESHOLD) {
			read_count = 0;
			PRINT(1, ".");
		}

		if (!dict_lookup(d, cur, (uint16_t) c, &y)) { //node not found

			if (emit(bd, cur, bits) < 0)
				goto error;

			dict_fill(d, y, cur, (uint16_t) c, next_record++);
			if (next_record & bitMask) {
				bitMask <<= 1;
				bits++;
			}

			if (next_record == dict_size) {
				next_record = dict_reinit(d);
				bits = initial_bits;
				bitMask = 1 << bits;
			}

			// search again starting from last unmatched symbol
			dict_lookup(d, ROOT_NODE, (uint16_t) c, &y);
		}

		cur = dict_next(d, y);
	}

	PRINT(1, "\nCompression Finished\n\n");
	dict_delete(d);
	bitio_flush(bd);
	if (bd != bstdout)
		bitio_close(bd);
	if (fin != NULL)
		fclose(fin);
	return filesize;

error:
	PRINT(1, "\n");
	dict_delete(d);
	bitio_flush(bd);
	if (bd != bstdout)
		bitio_close(bd);
	if (fin != NULL)
		fclose(fin);
	return -1;
}