/**************************************************************************** * Function : ReadHeader * Description: This function reads the header information stored by * WriteHeader. If the same algorithm that produced the * original tree is used with these counts, an exact copy of * the tree will be produced. * Parameters : ht - pointer to array of pointers to tree leaves * inFile - file to read from * Effects : Frequency information is read into the node of ht * Returned : 0 for success, -1 for failure. errno will be set in the * event of a failure. ****************************************************************************/ static int ReadHeader(huffman_node_t **ht, bit_file_t *bfp) { count_t count; int c; int status = -1; /* in case of premature EOF */ while ((c = BitFileGetChar(bfp)) != EOF) { BitFileGetBits(bfp, (void *)(&count), 8 * sizeof(count_t)); if ((count == 0) && (c == 0)) { /* we just read end of table marker */ status = 0; break; } ht[c]->count = count; ht[c]->ignore = 0; } /* add assumed EOF */ ht[EOF_CHAR]->count = 1; ht[EOF_CHAR]->ignore = 0; if (0 != status) { /* we hit EOF before we read a full header */ fprintf(stderr, "error: malformed file header.\n"); errno = EILSEQ; /* Illegal byte sequence seems reasonable */ } return status; }
tree_node *extract_fread_bytemap(bit_file_t *compressed, int uniquebytes) { int i, j, c, size; tree_node *root, *current, **next; root = tree_create_branch(NULL, NULL); for (i = 0; i < uniquebytes; i++) { c = BitFileGetChar(compressed); size = BitFileGetChar(compressed); current = root; for (j = 0; j < size; j++) { next = BitFileGetBit(compressed) ? ¤t->right : ¤t->left; if (*next == NULL) { *next = (j == size - 1) ? tree_create_leaf(c, 0) : tree_create_branch(NULL, NULL); } current = *next; } } return root; }
/*************************************************************************** * Function : GetCodeWord * Description: This function reads and returns a code word from an * encoded file. In order to deal with endian issue the * code word is read least significant byte followed by the * remaining bits. * Parameters : bfpIn - bit file containing the encoded data * Effects : code word is read from encoded input * Returned : The next code word in the encoded file. EOF if the end * of file has been reached. * * NOTE: If the code word contains more than 16 bits, this routine should * be modified to read in all the bytes from least significant to * most significant followed by any left over bits. ***************************************************************************/ int GetCodeWord(bit_file_t *bfpIn) { unsigned char byte; int code; /* get LS character */ if ((code = BitFileGetChar(bfpIn)) == EOF) { return EOF; } /* get remaining bits */ if (BitFileGetBits(bfpIn, &byte, CODE_MS_BITS(currentCodeLen)) == EOF) { return EOF; } code |= ((int)byte) << CODE_MS_BITS(currentCodeLen); return code; }
/*************************************************************************** * Function : main * Description: This function demonstrates the usage of each of the bit * bit file functions. * Parameters : argc - the number command line arguments (not used) * Parameters : argv - array of command line arguments (not used) * Effects : Writes bit file, reads back results, printing them to * stdout. * Returned : EXIT_SUCCESS ***************************************************************************/ int main(int argc, char *argv[]) { bit_file_t *bfp; FILE *fp; int i, numCalls, value; if (argc < 2) { numCalls = NUM_CALLS; } else { numCalls = atoi(argv[1]); } /* create bit file for writing */ bfp = BitFileOpen("testfile", BF_WRITE); if (bfp == NULL) { perror("opening file"); return (EXIT_FAILURE); } /* write chars */ value = (int)'A'; for (i = 0; i < numCalls; i++) { printf("writing char %c\n", value); if(BitFilePutChar(value, bfp) == EOF) { perror("writing char"); if (0 != BitFileClose(bfp)) { perror("closing bitfile"); } return (EXIT_FAILURE); } value++; } /* write single bits */ value = 0; for (i = 0; i < numCalls; i++) { printf("writing bit %d\n", value); if(BitFilePutBit(value, bfp) == EOF) { perror("writing bit"); if (0 != BitFileClose(bfp)) { perror("closing bitfile"); } return (EXIT_FAILURE); } value = 1 - value; } /* write ints as bits */ value = 0x11111111; for (i = 0; i < numCalls; i++) { printf("writing bits %0X\n", (unsigned int)value); if(BitFilePutBits(bfp, &value, (unsigned int)(8 * sizeof(int))) == EOF) { perror("writing bits"); if (0 != BitFileClose(bfp)) { perror("closing bitfile"); } return (EXIT_FAILURE); } value += 0x11111111; } /* close bit file */ if (BitFileClose(bfp) != 0) { perror("closing file"); return (EXIT_FAILURE); } else { printf("closed file\n"); } /* reopen file for appending */ bfp = BitFileOpen("testfile", BF_APPEND); if (bfp == NULL) { perror("opening file"); return (EXIT_FAILURE); } /* append some chars */ value = (int)'A'; for (i = 0; i < numCalls; i++) { printf("appending char %c\n", value); if(BitFilePutChar(value, bfp) == EOF) { perror("appending char"); if (0 != BitFileClose(bfp)) { perror("closing bitfile"); } return (EXIT_FAILURE); } value++; } /* write some bits from an integer */ value = 0x111; for (i = 0; i < numCalls; i++) { printf("writing 12 bits from an integer %03X\n", (unsigned int)value); if(BitFilePutBitsInt(bfp, &value, 12, sizeof(value)) == EOF) { perror("writing bits from an integer"); if (0 != BitFileClose(bfp)) { perror("closing bitfile"); } return (EXIT_FAILURE); } value += 0x111; } /* convert to normal file */ fp = BitFileToFILE(bfp); if (fp == NULL) { perror("converting to stdio FILE"); return (EXIT_FAILURE); } else { printf("converted to stdio FILE\n"); } /* append some chars */ value = (int)'a'; for (i = 0; i < numCalls; i++) { printf("appending char %c\n", value); if(fputc(value, fp) == EOF) { perror("appending char to FILE"); if (fclose(fp) == EOF) { perror("closing stdio FILE"); } return (EXIT_FAILURE); } value++; } /* close file */ if (fclose(fp) == EOF) { perror("closing stdio FILE"); return (EXIT_FAILURE); } /* now read back writes */ /* open bit file */ bfp = BitFileOpen("testfile", BF_READ); if (bfp == NULL) { perror("reopening file"); return (EXIT_FAILURE); } /* read chars */ for (i = 0; i < numCalls; i++) { value = BitFileGetChar(bfp); if(value == EOF) { perror("reading char"); if (0 != BitFileClose(bfp)) { perror("closing bitfile"); } return (EXIT_FAILURE); } else { printf("read %c\n", value); } } /* read single bits */ for (i = 0; i < numCalls; i++) { value = BitFileGetBit(bfp); if(value == EOF) { perror("reading bit"); if (0 != BitFileClose(bfp)) { perror("closing bitfile"); } return (EXIT_FAILURE); } else { printf("read bit %d\n", value); } } /* read ints as bits */ for (i = 0; i < numCalls; i++) { if(BitFileGetBits(bfp, &value, (unsigned int)(8 * sizeof(int))) == EOF) { perror("reading bits"); if (0 != BitFileClose(bfp)) { perror("closing bitfile"); } return (EXIT_FAILURE); } else { printf("read bits %0X\n", (unsigned int)value); } } if (BitFileByteAlign(bfp) == EOF) { fprintf(stderr, "failed to align file\n"); if (0 != BitFileClose(bfp)) { perror("closing bitfile"); } return (EXIT_FAILURE); } else { printf("byte aligning file\n"); } /* read appended characters */ for (i = 0; i < numCalls; i++) { value = BitFileGetChar(bfp); if(value == EOF) { perror("reading char"); if (0 != BitFileClose(bfp)) { perror("closing bitfile"); } return (EXIT_FAILURE); } else { printf("read %c\n", value); } } /* read some bits into an integer */ for (i = 0; i < numCalls; i++) { value = 0; if(BitFileGetBitsInt(bfp, &value, 12, sizeof(value)) == EOF) { perror("reading bits from an integer"); if (0 != BitFileClose(bfp)) { perror("closing bitfile"); } return (EXIT_FAILURE); } else { printf("read 12 bits into an integer %03X\n", (unsigned int)value); } } /* convert to stdio FILE */ fp = BitFileToFILE(bfp); if (fp == NULL) { perror("converting to stdio FILE"); return (EXIT_FAILURE); } else { printf("converted to stdio FILE\n"); } /* read append some chars */ value = (int)'a'; for (i = 0; i < numCalls; i++) { value = fgetc(fp); if(value == EOF) { perror("stdio reading char"); if (0 != BitFileClose(bfp)) { perror("closing bitfile"); } return (EXIT_FAILURE); } else { printf("stdio read %c\n", value); } } /* close file */ if (fclose(fp) == EOF) { perror("closing stdio FILE"); return (EXIT_FAILURE); } return(EXIT_SUCCESS); }
int main(int argc, char** argv) { bit_file_t* f; FILE* outf; char* infile,*outfile; uint8_t* input,*bwt,*output,lumode; int32_t I,n; mode_t lupdate_alg; /* parse command line parameter */ if (argc !=2) { print_usage(argv[0]); exit(EXIT_FAILURE); } infile = argv[1]; /* read input file */ f = BitFileOpen(infile, BF_READ); if (!f) { fatal("could not open file %s.",infile); } /* check if compressed with aazip */ if (BitFileGetChar(f) != 'A' || BitFileGetChar(f) != 'A') { fatal("file %s not compressed with aazip.",infile); } fprintf(stdout,"FILE: %s\n",infile); /* read header */ BitFileGetBitsInt(f,&I,32,sizeof(I)); BitFileGetBitsInt(f,&lumode,8,sizeof(lumode)); lupdate_alg = lumode; input = decode_huffman(f,&n); /* malloc output memory */ bwt = safe_malloc(n*sizeof(uint8_t)); /* peform list update */ switch (lupdate_alg) { case SIMPLE: fprintf(stdout,"LUPDATE: Simple\n"); bwt = lupdate_simple(input,n,bwt); break; case MTF: fprintf(stdout,"LUPDATE: Move-To-Front\n"); bwt = lupdate_movetofront(input,n,bwt); break; case FC: fprintf(stdout,"LUPDATE: FC\n"); bwt = lupdate_freqcount(input,n,bwt); break; case WFC: fprintf(stdout,"LUPDATE: WFC\n"); bwt = lupdate_wfc(input,n,bwt); break; case TS: fprintf(stdout,"LUPDATE: TS\n"); bwt = lupdate_timestamp(input,n,bwt); break; default: fatal("unkown list update algorithm."); } /* reverse bwt */ output = reverse_bwt(bwt,n,I,input); /* write output */ outfile = safe_strcat(infile,".org"); outf = safe_fopen(outfile,"w"); if (fwrite(output,sizeof(uint8_t),n,outf)!= (size_t)n) { fatal("error writing output."); } safe_fclose(outf); /* clean up */ free(bwt); free(input); BitFileClose(f); return (EXIT_SUCCESS); }