예제 #1
0
void write_compression(unsigned char sigbits[255], unsigned long bitencodings[255], FILE * fphuff, FILE * fporig)
{//write the huffman compression to the output file
	//compression variables
	int readchar;
	int numsignificant;
	unsigned long encoding;
	//1000 0000 0000 0000 0000 0000 0000 0000
	unsigned long mask = 0x80000000;

	bitspot = 0;
	currentbyte = 0;

	//write file 
	while (!feof(fporig))
	{//read every character in the file until the EOF is found
		readchar = fgetc(fporig);
		if (readchar != EOF) //keeps the standard EOF file from being written, we must write our own pseudo EOF
		{//save encoding, save amount of digits, shift the most significant bit to the far left
			encoding = bitencodings[(int) readchar];
			numsignificant = sigbits[(int) readchar];
			encoding <<= (32 - numsignificant);
			while (numsignificant > 0)
			{//loop until we have used all of the significant bits in our encoding
				if ((mask & encoding) == mask)
				{//if the furthest left bit is 1, pack a 1
					write_bit(fphuff, 1);
				} else
				{//if the furthest left bit is 0, pack a 0
					write_bit(fphuff, 0);
				}
				//set up the next bit to write, decrement the number of bits still to write
				encoding <<= 1;
				--numsignificant;
			}
		}
	}
	//write the pseudo EOF character, using ASCII NULL = 0000 0000
	encoding = bitencodings[0];
	numsignificant = sigbits[0];
	encoding <<= (32 - numsignificant);
	//same as above, except dedicated to writing pseudo EOF
	while (numsignificant > 0)
	{
		if ((mask & encoding) == mask)
		{
			write_bit(fphuff, 1);
		} else
		{
			write_bit(fphuff, 0);
		}
		encoding <<= 1;
		--numsignificant;
	}
	//finish off the byte with 0's and write it
	pad_file(fphuff);
	return;
}
예제 #2
0
int main(int argc, char * * argv)
{
	int * weights = malloc(sizeof(int) * 256);
	char * filename = argv[1];
	int count;
	int numNodes;
	numchar = 0;
	unsigned char sigbits[255] = {0};
	unsigned long bitencodings[255] = {0};
	Node * temp = NULL;
	Node * head = NULL;
	Node * root = NULL;

	if (argc > 2)
	{//error checking
		fprintf(stderr, "\nERROR! TOO MANY INPUTS, huff.c ACCEPTS 1 INPUT: FILENAME.txt\n\n");
		return  (ERROR);
	}

	FILE * fp = fopen(filename, "r");

	if (fp == NULL)
	{//error checking
		fprintf(stderr, "\nERROR! FILE COULD NOT BE OPENED.\n\n");
		return (ERROR);
	}

	//counting the frequencies of chars in the file
	weights = parse_file(weights, fp);
	fclose(fp);

	//generate linked list of non 0 weighted chars which are sorted in ascending order
	for (count = 0, numNodes = 0; count < 256; ++count)
	{
		if (weights[count] != 0)
		{//use all characters that showed up in the input file
			temp = create_node((char) count, weights[count]);
			if (head == NULL)
			{//if its the first node, set it as the head
				head = temp;
			} else
			{//insert the node into the list in ascending order
				head = insert_node(head, temp);
			}//keep track of the number of nodes in the list
			++numNodes;
		}
	}

	//adding pseudo-EOF node
	temp = create_node((char) 0, 1);
	head = insert_node(head, temp);
	++numNodes;

	//make huffman tree out of linked list
	root = create_tree(head, numNodes);

	//create sigbits and encodings from huffman tree
	bits = 0;
	countbits = 0;
	generate_encodings(root, sigbits, bitencodings);

	//file to read from
	FILE * fporig = fopen(filename, "r");
	rewind(fporig);
	//file to write to
	strcat(filename, ".huff");
	FILE * fphuff = fopen(filename, "w");

	if (fporig == NULL || fphuff == NULL)
	{//error checking
		fprintf(stderr, "\nERROR! FILE COULD NOT BE OPENED.\n\n");
		return (ERROR);
	}

	//write header
	bitspot = 0;
	currentbyte = 0;
	write_header(root, fphuff);
	//write an extra 0 so that the header reader can reach the exit condition
	write_bit(fphuff, 0);
	//pad with zeroes
	pad_file(fphuff);
	//write the number of characters
	fwrite(&numchar, sizeof(unsigned int), 1, fphuff);
	//write a newline which will mark the end of the header
	unsigned char newline = '\n';
	fwrite(&newline, sizeof(unsigned char), 1, fphuff);

	//write compressed data with pseudo EOF and necessary padding
	write_compression(sigbits, bitencodings, fphuff, fporig);

	//were done
	fclose(fporig);
	fclose(fphuff);
	destroy_tree(root);

	return (0);
}
예제 #3
0
int util_save_image(char *orig_file_name, char *save_file_name)
{
    int origFd = -1, saveFd = -1;
    char *start_data, *end_data, *start_text, *end_round;
    struct exec old_hdr, new_hdr;
    struct stat old_stat;
    int n, page_size, length_text, length_data;

    if ((origFd = open(orig_file_name, 0)) < 0) {
	perror(orig_file_name);
	(void) fprintf(stderr, "Cannot open original a.out file\n");
	goto bad;
    }

    if (fstat(origFd, &old_stat) < 0) {
	perror(orig_file_name);
	(void) fprintf(stderr, "Cannot stat original a.out file\n");
	goto bad;
    }

    /*
     * Read the a.out header from the original file.
     */
    if (read(origFd, (char *) &old_hdr, sizeof(old_hdr)) != sizeof(old_hdr)) {
	perror(orig_file_name);
	(void) fprintf(stderr, "Cannot read original a.out header\n");
	goto bad;
    }
    if (N_BADMAG(old_hdr)) {
	(void) fprintf(stderr, "File %s has a bad magic number (%o)\n",
			orig_file_name, old_hdr.a_magic);
	goto bad;
    }
    if (old_hdr.a_magic != ZMAGIC) {
	(void) fprintf(stderr, "File %s is not demand-paged\n", orig_file_name);
	goto bad;
    }

    /*
     * Open the output file.
     */
    if (access(save_file_name, /* F_OK */ 0) == 0) {
	(void) unlink(save_file_name);
    }
    if ((saveFd = creat(save_file_name, 0777)) < 0) {
	if (errno == ETXTBSY) {
	    (void) unlink(save_file_name);
	    saveFd = creat(save_file_name, 0777);
	}
	if (saveFd < 0) {
	    perror(save_file_name);
	    (void) fprintf(stderr, "Cannot create save file.\n");
	    goto bad;
	}
    }

    /*
     * Find out how far the data segment extends.
     */
    new_hdr = old_hdr;
    end_data = sbrk(0);
    page_size = getpagesize();
    n = ((((int) end_data) + page_size - 1) / page_size) * page_size;
    end_round = (char *) n;
    if (end_round > end_data) {
	end_data = sbrk(end_round - end_data);
    }

#ifdef vax
    start_text = 0;
    length_text = new_hdr.a_text;
    start_data = (char *) old_hdr.a_text;
    length_data = end_data - start_data;
#endif vax
#ifdef	sun
    start_text = (char *) N_TXTADDR(old_hdr) + sizeof(old_hdr);
    length_text = old_hdr.a_text - sizeof(old_hdr);
    start_data = (char *) N_DATADDR(old_hdr);
    length_data = end_data - start_data;
#endif	sun
    new_hdr.a_data = end_data - start_data;
    new_hdr.a_bss = 0;

    /*
     * First, the header plus enough pad to extend up to N_TXTOFF.
     */
    if (write(saveFd, (char *) &new_hdr, (int) sizeof(new_hdr)) !=
				sizeof(new_hdr)) {
	perror("write");
	(void) fprintf(stderr, "Error while copying header.\n");
	goto bad;
    }
    if (! pad_file(saveFd, N_TXTOFF(old_hdr) - sizeof(new_hdr))) {
	(void) fprintf(stderr, "Error while padding.\n");
	goto bad;
    }


    /*
     *  Copy our text segment
     */
    if (write(saveFd, start_text, length_text) != length_text) {
	perror("write");
	(void) fprintf(stderr, "Error while copying text segment.\n");
	goto bad;
    }


    /*
     *  Copy our data segment
     */
    if (write(saveFd, start_data, length_data) != length_data) {
	perror("write");
	(void) fprintf(stderr, "Error while copying data segment.\n");
	goto bad;
    }

    /*
     * Copy the symbol table and everything else.
     * This takes us to the end of the original file.
     */
    (void) lseek(origFd, (long) N_SYMOFF(old_hdr), 0);
    if (! copy_file(origFd, saveFd, old_stat.st_size - N_SYMOFF(old_hdr))) {
	(void) fprintf(stderr, "Error while copying symbol table.\n");
	goto bad;
    }
    (void) close(origFd);
    (void) close(saveFd);
    return 1;

bad:
    if (origFd >= 0) (void) close(origFd);
    if (saveFd >= 0) (void) close(saveFd);
    return 0;
}