void decompressFile(FILE* fin, FILE* fout){ /* Read number of characters from file * Read number of nodes of Huffman Tree */ uint32_t numberOfChars, countChars = 0; uint16_t numberOfNodes; fread(&numberOfChars, sizeof(uint32_t), 1, fin); fread(&numberOfNodes, sizeof(uint16_t), 1, fin); /* Read Huffman Tree */ TagHuffmanNode HuffmanVector[numberOfNodes]; int i; for(i = 0; i < numberOfNodes; i++){ fread(&HuffmanVector[i], sizeof(TagHuffmanNode), 1, fin); } /* Decompress */ char buffer; int semafor = 0; int indice = 0; while(fread(&buffer, sizeof(char), 1, fin) && !feof(fin)){ int bits[8]; /* Get 8 bits from file */ charToBinary(buffer, bits); /* Decode according to Huffman Tree */ for(i = 0; i < 8; i++){ /* Number of characters - finished */ if(countChars == numberOfChars){ semafor = 1; break; } /* Parse the tree */ if(bits[i] == 1) indice = HuffmanVector[indice].right; else indice = HuffmanVector[indice].left; /* Leaf-node - a character */ if(HuffmanVector[indice].right == -1 && HuffmanVector[indice].left == -1){ fprintf(fout, "%c", HuffmanVector[indice].value); countChars++; indice = 0; } } /* If number of characters is finished */ if(semafor == 1) break; } }
// ----------------------------------------------------------- // FUNCTION main : // This function reads in the input from stdin and // compresses it using the given algorithm. // PARAMETER USAGE : // int argc - The number of arguments. // char* argv[] - The arguments. // ----------------------------------------------------------- int main(int argc, const char* argv[]) { int freq[256]; char buf[1024]; char freqChars[16]; frequent(freq, freqChars); for (int i = 0; i < 16; i++) { write(1, &freqChars[i], sizeof(char)); } if (lseek(0, 0, SEEK_SET) == -1) { sprintf(buf, "Seeking of the source has failed.\n"); write(2, buf, strlen(buf)); } struct BitWriter bw; init(&bw); int cnt; while ((cnt = read(0, buf, sizeof(buf))) > 0) { // Read in all characters in SIN for (int i = 0; i < cnt; i++) { //printf("\n\n\n\n"); //printf("looking at char %c:\n", buf[i]); if (freq[(int)buf[i]] == 1) { // Is a frequent char //printf("It is frequent\n"); writeBit(&bw, 0); // Count repeat times int j; int origCnt = cnt; for (j = i + 1; j - i < 8 && buf[j % origCnt] == buf[i]; j++) { // Still equal and counting if (j == cnt - 1) { // J passed end. Get more input cnt = read(0, buf, sizeof(buf)); if (cnt == 0) { // No more input break; } } } int tmp = i; i = j - 1; // Set j to number of repeated times j = j - tmp; if (j == 1) { // Just one frequent char //printf("It does not repeat.\n"); writeBit(&bw, 0); } else { // More than one. Print count //printf("It does repeat %d times\n", j); writeBit(&bw, 1); int bits[3]; getThreeBitInt(j - 1, bits); for (int k = 0; k < 3; k++) { writeBit(&bw, bits[k]); } } // Write frequent char number for (int k = 0; k < 15; k++) { if (freqChars[k] == buf[i]) { int bits[4]; getFourBitInt(k, bits); for (int l = 0; l < 4; l++) { writeBit(&bw, bits[l]); } break; } } } else { // Not a frequent character //printf("It is not frequent\n"); writeBit(&bw, 1); int bits[8]; charToBinary(buf[i], bits); for (int k = 0; k < 8; k++) { writeBit(&bw, bits[k]); } } } } writeBit(&bw, 0); writeBit(&bw, 0); writeBit(&bw, 1); writeBit(&bw, 1); writeBit(&bw, 1); writeBit(&bw, 1); flush(&bw); }