void swapWordBitBlock(iterator A, uint64_t const o0, uint64_t const o1, uint64_t const l) { uint64_t const v0 = getBits(A,o0,l); uint64_t const v1 = getBits(A,o1,l); putBits(A,o0,l,v1); putBits(A,o1,l,v0); }
/* outputs the escape character followed by k and updates the string table and * nbits */ void escapeChar(stringTable* table, pruneInfo* pi, unsigned char k, unsigned char* nbits, FILE* outfile) { putBits(*nbits, ESCAPE_CODE, outfile); putBits(8, k, outfile); unsigned int newCode; stringTableAdd(table, EMPTY_PREFIX, k, &newCode); pruneInfoSawCode(pi, newCode); checkNbits(nbits, table, outfile); }
int main(int argc, char* argv[]){ int c; while ((c=getBits(3)) !=EOF){ putBits(3, c); } flushBits(); }
/* checks to see if the number of bits per code needs to be increased, and if so * sends the GROW_NBITS_CODE and increments nbits */ void checkNbits(unsigned char* nbits, stringTable* table, FILE* outfile) { if(table->highestCode > (1 << *nbits) - 1) { putBits(*nbits, GROW_NBITS_CODE, outfile); (*nbits)++; } }
void getEncodeFlags (int argc, char *argv[]) { int maxBits = 12; int shouldPrune = 0; for (int i = 0; i < argc; i ++) { if (!strcmp(argv[i],"-e")){ Escaped = 1; setEscaped(); } else if (!strcmp(argv[i],"-p")){ shouldPrune = 1; setShouldPrune(); } else if (!strcmp(argv[i],"-m")){ if (i + 1 < argc){ char *endBuf = NULL; int newValue = strtol(argv[i + 1], &endBuf, 10); if (newValue <= 20 && newValue > 8) { maxBits = newValue; setMaxBits(maxBits); } } } } putBits(8, maxBits); if (Escaped == 1){ putBits(1, 1); } else { putBits(1,0); } if (shouldPrune == 1){ putBits(1, 1); } else { putBits(1,0); } }
extern void AperPutSemiConstraintNumber(AsnContext *pContext, S32 lBound, S32 uNum) { U32 distance, nByte ; ASSERT(uNum >= lBound); distance = uNum - lBound; nByte = GetNumberOctetLength(distance); AperPutLengthValue(pContext, 0, ASN_MAX, nByte); PER_ALIGN putBits(pContext, nByte * 8, distance); }
/* checks to see if table should be pruned, and if so, prints the PRUNE_CODE, * calls stringTablePrune, updates nbits, and returns the new stringTable. If * no pruning occurs, the original stringTable* is returned. */ stringTable* checkPrune(stringTable* table, pruneInfo* pi, unsigned long window, unsigned int* oldPrefix, unsigned char* nbits, FILE* outfile) { if(window > 0 && stringTableIsFull(table)) { putBits(*nbits, PRUNE_CODE, outfile); table = stringTablePrune(table, pi, window, oldPrefix); *oldPrefix = EMPTY_PREFIX; // update *nbits for(*nbits = 2; (1 << *nbits) -1 < table->highestCode; (*nbits)++); } return table; }
int getLargestSequence (int firstChar, Tree *codeTrie){ int c = firstChar; int *buildSequence = malloc(sizeof(int)); buildSequence[0] = -1; int foundCode[1]; int wasPruned[1]; *wasPruned = 0; int atEnd = 0; buildSequence = addLetterToString (buildSequence, c); while (checkT(codeTrie, buildSequence, wasPruned, foundCode)) { c = getchar(); if (c == EOF) { atEnd = 1; break; } buildSequence = addLetterToString (buildSequence, c); } if (Escaped) { if (*wasPruned == 2){ putBits(LastBitsCount, 0); putBits(8, buildSequence[0]); c = getchar(); free(buildSequence); return c; } } free(buildSequence); putBits(LastBitsCount, *foundCode); if (*wasPruned == 1){ if (!atEnd) { if (Escaped) { putBits(LastBitsCount, 0); putBits(8, c); c = getchar(); } else { putBits(LastBitsCount, c); } } } LastBitsCount = getBitsCount(); return c; }
// encodes the input stream by taking advantage of lzw algorithm // also implements logic to prune the trie structure used to store the string // table, and escapes single character codes void encode(int e, int m, int p) { Trie st; createT(&st, e); int c = EMPTY; // same as (EMPTY, K), index of the prefix // int value of char k we are testing to see if c,k exists in the table int k; // number of codes you have inserted, 256 without escape flag... int codeCount = (e) ? 3 : 259; int bitCount = (e) ? 2 : 9; int maxbits = (m<=8 || m>20) ? 12 : m; int maxcodes = (1 << maxbits); int firstRead = false; // if first read of k when e flag is present int pruneCount = 0; printf("%02d:%d:%d:", maxbits, p, e); while((k = getchar())!= EOF) { st[c].appearances++; int ck = searchT(&st, c, k, e); // will increment c's appearance once // if ck is not in the table if(ck<0) { // if prune flag & reached maxcodes, do a prune before next insert // into the table, putBits 0 to indicate a prune has occurred // a prune should likewise happen in decode if(c!=EMPTY) { putBits(bitCount, c); } // add ck to the table as long as (e && c == EMPTY) is false // we will add (empty, k) to the table after this condition // !e and c==EMPTY will never happen, bc all chars will have been // added as children to empty // prune right before we reach maxcodes, we would have lost the next // code we insert anyways, now we won't lose k if(p&&(codeCount+1==maxcodes)) { putBits(bitCount, 0); pruneCount++; Trie newst; createT(&newst, e); int oldCodeCount = codeCount; codeCount=pruneT(&st, &newst, e, oldCodeCount); destroyT(&st, oldCodeCount); st = newst; bitCount=codeLength(codeCount); c=EMPTY; ungetc(k, stdin); continue; } // if(!e || c!=EMPTY) { if(codeCount<maxcodes) { if(tableFilled(codeCount+1)) { int newSize = (codeCount+1)*2; expandT(&st, newSize); bitCount++; } addT(&st, c, k, codeCount); codeCount++; } } // if escape flag is on and k is not yet added to the table if(e && searchT(&st, EMPTY, k, e) < 0) { putBits(bitCount, ESC); // 1 is the index of escape character putBits(8, k); if(codeCount<maxcodes) { if(codeLength(codeCount+1)-codeLength(codeCount)) { int newSize = (codeCount+1)*2; expandT(&st, newSize); bitCount++; } addT(&st, EMPTY, k, codeCount); codeCount++; } firstRead=true; // encode escaped something, don't unget(k) // if this happens } c = EMPTY; // make c empty again if(!firstRead) { ungetc(k, stdin); // put k back to start reading } // a new character else { firstRead = false; } } else { c=ck; // set c to index of next code } } if(c!=EMPTY) { putBits(bitCount, c); } putBits(bitCount, EOFILE); // puts EOF flushBits(); destroyT(&st, codeCount); }
int main (int argc, char **argv) { int *table; int table_size = 4; // 0,1,2,3 are special int nbits = 9; // Always start with 512 item table. int max_bits = 0, prev_code = 0; int maxed = 0; int choose; choose = which(argv); table = calloc( (1 << nbits), sizeof(int)); init_table(table, nbits, &table_size); // Encode if ( choose == 1 ) { // Prove that ncode created the file. putBits(nbits, MAGIC1); putBits(nbits, MAGIC2); // Get max_bits int tmp; tmp = get_arg(argv, argc, 'm'); max_bits = get_m_arg(argv, tmp); if (max_bits < 0) { exit(0); } putBits(nbits, max_bits); // Get ratio int c, check_time; int code_bits = 0, char_bits = 0, count = 0; double ratio; tmp = get_arg(argv, argc, 'r'); check_time = get_r_arg(argv, tmp, &ratio); if (check_time < 0) { exit(0); } // Let's go while ((c = getchar()) != EOF) { char_bits += 8; // Item found, read next char if ( (tmp = item_exists(prev_code, c, table, nbits))) { prev_code = tmp; continue; } // item not found. Add item to table. Output prev_code. // new prev_code is c's index else { code_bits += nbits; count++; if (!maxed) { add_item(prev_code, c, table, nbits, &table_size); } putBits(nbits, prev_code); prev_code = item_exists(0, c, table, nbits); // Resize table if (table_size > (0.99 * TABLE_SIZE) && !maxed) { if (nbits != max_bits) { code_bits += (2 * nbits) + 1; putBits(nbits++, 1); putBits(nbits, c); table = init_new(table, TABLE_SIZE, table_size, nbits); } else { maxed = 1; putBits(nbits, 2); code_bits += nbits; } } // -r if (check_time && !(count % check_time) && (code_bits > ratio * char_bits)) { // re init putBits(nbits, 3); nbits = 9; free(table); table = calloc( (1 << nbits), sizeof(int)); init_table(table, nbits, &table_size); maxed = 0; code_bits = 0; char_bits = 0; } } } putBits(nbits, prev_code); putBits(nbits, 0); flushBits(); free(table); } // Decode else { int i, code, hold = 0, tmp_code, mx=0; len_array outstring; outstring.array = malloc(MAX_LEN * sizeof(int)); // Check that there are no args if (argc != 1) { fprintf(stderr, "Unexpected argument to decode\n"); exit(0); } // Check that this is actually a file we encoded if ( (getBits(nbits) != MAGIC1) || (getBits(nbits) != MAGIC2)) { fprintf(stderr, "Wrong file"); exit(0); } // Let's go max_bits = getBits(nbits); while ( (code = getBits(nbits)) ) { outstring.len = 0; // Table resize if (code == 1) { nbits++; // get the next letter, add and resize code = getBits(nbits); tmp_code = add_item(prev_code, code, table, nbits-1, &table_size); table = init_new(table, TABLE_SIZE, table_size, nbits); hold = 1; continue; } // Size is maxed, set maxed after next add else if (code == 2) { mx = 1; continue; } // Reinit table else if (code == 3) { nbits = 9; free(table); table = calloc( (1 << nbits), sizeof(int)); init_table(table, nbits, &table_size); prev_code = 0; maxed = 0; mx = 0; continue; } // Code in table else if ( (table[code] % 2)) { backtrace(table, code, &outstring); for (i=0; i<outstring.len; i++) { printf("%c", outstring.array[i]); } // If !prev_code, item has len 1 & will be there already // If maxed, table full // If hold, first add after resize - already there if (prev_code && !hold && !maxed) { add_item(prev_code, outstring.array[0], table, nbits, &table_size); } prev_code = code; } // Item not found in table. Item must be the result of // table[prev_code] + table[prev_code][0] // We also MUST be able to add it - no worries about max_bits else { backtrace(table, prev_code, &outstring); outstring.array[outstring.len++] = outstring.array[0]; for (i=0; i<outstring.len; i++) { printf("%c", outstring.array[i]); } // If it is not the first one after a resize if (!hold) { prev_code = add_item(prev_code, outstring.array[0], table, nbits, &table_size); } else { prev_code = tmp_code; } // Check that we the code we get from adding is the expected if (prev_code != code) { fprintf(stderr, "File corrupted\n"); exit(0); } } if (hold) { hold = 0; } if (mx) { mx = 0; maxed = 1; } } free(table); free(outstring.array); } return(0); }
//This will only be called if C, K does NOT already exist in the table int compInsert(int C, int K, Root t, int encoding, int pruning) { //if are encoding and we are about to fill the table, we prepare to double //the size. Note: when decoding, size doubling is taken care of in lzw.c if ((t->numFilled == (1<<t->capacity) -1)&&((encoding == 1)||(pruning == 1))) { if (t->capacity != maxbits) { // We send a special code to be read by decode indicating the double if (pruning == 0) putBits(t->capacity, 3); t->capacity++; t->myTable = realloc(t->myTable, (1<<(t->capacity))*sizeof(struct lzwNode)); } } //If we are for any reason inserting a code past capacity if (C >= (1<<(t)->capacity)) { //DIE("capacity reached."); return 0; } //This should never happen, I think. if ((C >= (t)->numFilled) && (C != 0)) { // DIE("Something weird happened here!!"); return 0; } int end = (t)->myTable[C].numChildren; if (end == 0) { //we don't need to search, because nothing is there (t)->myTable[C].children = malloc(sizeof(int)); (t)->myTable[C].children[0] = (t->numFilled); (t)->myTable[C].numChildren = 1; (t)->myTable[C].count++; //add a new node to the array (for now, we assume there is already //space for it). Set it's values accordingly: (t)->myTable[t->numFilled].character = K; (t)->myTable[t->numFilled].prefix = C; (t)->myTable[t->numFilled].numChildren = 0; (t)->myTable[t->numFilled].children = NULL; (t)->myTable[t->numFilled].count = 1; t->numFilled++; return 1; } (t)->myTable[C].children = realloc((t)->myTable[C].children, (end+1)*sizeof(int)); //enabling binary search: cycle through and slide over to keep ordered int i, iNext; for (i = end-1; i >= 0; i--) { //cycle through the children iNext = (t)->myTable[C].children[i]; if ((t)->myTable[iNext].character < K) { (t)->myTable[C].children[i+1] = (t->numFilled); (t)->myTable[C].numChildren++; if (pruning == 0) (t)->myTable[C].count++; //add a new node to the array (we assume there is already space for //it as coded above). Set it's values accordingly: (t)->myTable[t->numFilled].character = K; (t)->myTable[t->numFilled].prefix = C; (t)->myTable[t->numFilled].numChildren = 0; (t)->myTable[t->numFilled].children = NULL; (t)->myTable[t->numFilled].count = 1; t->numFilled++; return 1; } else if ((t)->myTable[iNext].character > K) { //slide that child over to the right by one (t)->myTable[C].children[i+1] = t->myTable[C].children[i]; continue; } else { //we are REPEATING an insertion if (pruning == 0) //as long as we are not calling this from prune (t)->myTable[C].count++; // INCREMENT HERE! return 1; } } //if the loop finished and we didn't insert, insert at children[0] if (i == -1) { (t)->myTable[C].children[i+1] = (t->numFilled); (t)->myTable[C].numChildren++; if (pruning == 0) (t)->myTable[C].count++; //add a new node to the array (for now, we assume there is already //space for it). Set it's values accordingly: (t)->myTable[t->numFilled].character = K; (t)->myTable[t->numFilled].prefix = C; (t)->myTable[t->numFilled].numChildren = 0; (t)->myTable[t->numFilled].children = NULL; (t)->myTable[t->numFilled].count = 1; t->numFilled++; } return 1; }
void set(uint64_t i, uint64_t v) { putBits(D, i*k+o, b, v); /* assert ( get(i) == v ); */ }
// Compress STDIN into stream of codes // First byte sent in the form [MAXBITS (6 bits)][E_FLAG][P_FLAG] // // The only special code sent is ESCAPE for -e; // everything else is derived in decode. // // Pruning performed as soon as the table is full int encode(int MAXBITS, int E_FLAG, int P_FLAG) { // Send option args encoded as: // MAXBITS: 6 bits (since max value is 20) // E_FLAG: 1 bit // P_FLAG: 1 bit putBits(6, MAXBITS); putBits(1, E_FLAG); putBits(1, P_FLAG); int next_code = 0; // == number of codes assigned == # elts in ARRAY int nBits = 1; // #bits required to send NEXT code if (E_FLAG) next_code = 2; // already assigned 0 to QUIT // 1 to ESCAPE // ============== INITIALIZE TRIE ================ Trie t = createT(); if (!E_FLAG) { // initialize all one-char strings for (int K = 0; K < 256; K++) insertT(t, K, next_code++, 0); nBits = 8; } // ================ ENCODE INPUT ================= Trie C = t; // last node visited int K; while ((K = getchar()) != EOF) { Trie child = getT(C, K); if (child != NULL) { // increment NAP and go down trie sawT(child); C = child; } else { // ============ PUTBITS ========================== if (C == t) { // new 1-char string if (!E_FLAG) DIE_FORMAT("E_FLAG false, yet (EMPTY, K=%d) not in table\n", K); putBits(nBits, ESCAPE); putBits(CHAR_BIT, K); } else { // Output code C putBits(nBits, getCodeT(C)); } // =========== INSERT ============================== // insert new code if table not full if (next_code < (1 << MAXBITS)) { insertT(C, K, next_code++, 1); } // =========== UPDATE NBITS ======================= // Prune as soon as last slot taken if (next_code == (1 << MAXBITS)) { if (P_FLAG) { next_code = prune(&t, E_FLAG); nBits = get_nbits(next_code); } else ; } // Increase NBITS only when #codes assigned // exceeds it else if (next_code > (1 << nBits)) nBits++; // ============ RESET C ===== if (C == t) // new single-char, so skip continue; else { C = getT(t, K); if (C == NULL) { // (EMPTY, K) not in table if (!E_FLAG) DIE_FORMAT("E_FLAG false, yet (EMPTY, K=%d) not in table\n", K); ungetc(K, stdin); // single-char on next insert C = t; } else sawT(C); // increment NAP } } } // Put leftover known prefix if (C != t) { putBits(nBits, getCodeT(C)); } flushBits(); destroyT(t); return 0; }
int ParserLatm::parsePayload(unsigned char* data, int len) { cBitStream bs(data, len * 8); bs.SkipBits(24); // skip header if(!bs.GetBit()) { readStreamMuxConfig(&bs); } int tmp; unsigned int slotLen = 0; do { tmp = bs.GetBits(8); slotLen += tmp; } while(tmp == 255); if(slotLen * 8 > (bs.Length() - (unsigned)bs.Index())) { return len; } if(m_curDts == DVD_NOPTS_VALUE) { return len; } // buffer for converted payload data int payloadlength = slotLen + 7; uint8_t* payload = (uint8_t*)malloc(payloadlength); // 7 bytes of ADTS header int offset = 0; putBits(payload, offset, 0xfff, 12); // Sync marker putBits(payload, offset, 0, 1); // ID 0 = MPEG 4 putBits(payload, offset, 0, 2); // Layer putBits(payload, offset, 1, 1); // Protection absent putBits(payload, offset, 2, 2); // AOT putBits(payload, offset, m_sampleRateIndex, 4); putBits(payload, offset, 1, 1); // Private bit putBits(payload, offset, m_channels, 3); putBits(payload, offset, 1, 1); // Original putBits(payload, offset, 1, 1); // Copy putBits(payload, offset, 1, 1); // Copyright identification bit putBits(payload, offset, 1, 1); // Copyright identification start putBits(payload, offset, slotLen, 13); putBits(payload, offset, 0, 11); // Buffer fullness putBits(payload, offset, 0, 2); // RDB in frame // copy AAC data uint8_t* buf = payload + 7; for(unsigned int i = 0; i < slotLen; i++) { *buf++ = bs.GetBits(8); } // send converted payload packet Parser::sendPayload(payload, payloadlength); // free payload buffer free(payload); return len; }
void encode(FILE* infile, FILE* outfile, unsigned int maxBits, unsigned int window, bool eFlag) { stringTable* table = stringTableNew(maxBits, eFlag); pruneInfo* pi = pruneInfoNew(maxBits); // write maxBits, window, and eFlag to outfile putBits(NBITS_MAXBITS, maxBits, outfile); putBits(NBITS_WINDOW, window, outfile); eFlag ? putBits(NBITS_EFLAG, 1, outfile) : putBits(NBITS_EFLAG, 0, outfile); // the string table is populated with (c, k) pairs; c is the code for the // prefix of the entry, k is the char appended to the end of the prefix unsigned int c = EMPTY_PREFIX; int k; unsigned char nbits = (eFlag) ? 2 : 9; // number of bits sent per code while((k = fgetc(infile)) != EOF) { tableElt* elt = stringTableHashSearch(table, c, k); if(elt) { c = elt->code; } else if(c == EMPTY_PREFIX) { // we're escaping k, so leave the prefix empty escapeChar(table, pi, k, &nbits, outfile); table = checkPrune(table, pi, window, &c, &nbits, outfile); } else { putBits(nbits, c, outfile); pruneInfoSawCode(pi, c); stringTableAdd(table, c, k, NULL); table = checkPrune(table, pi, window, &c, &nbits, outfile); checkNbits(&nbits, table, outfile); tableElt* kCode = stringTableHashSearch(table, EMPTY_PREFIX, k); if(kCode) { c = kCode->code; } else { escapeChar(table, pi, k, &nbits, outfile); c = EMPTY_PREFIX; // since we escaped k, we now have no prefix checkPrune(table, pi, window, &c, &nbits, outfile); } } } if(c != EMPTY_PREFIX) putBits(nbits, c, outfile); putBits(nbits, STOP_CODE, outfile); flushBits(outfile); stringTableDelete(table); pruneInfoDelete(pi); }
int encode(int args[]) { //freopen("hash.h", "r", stdin); Hash *h = malloc(sizeof(Hash)); int size = 1 << (args[1]+1); unsigned int time =1; initialize(h, size, args[3], time); int c=EMPTY, k, latestCode; int bits=(args[3])?3:9; printf("%d %d %d|", args[1], args[2], args[3]); while((k = getchar()) != EOF) if(findInHash(h, c , (char)k) != EMPTY) c = findInHash(h, c , (char)k); else { if(args[3] && findInHash(h, EMPTY, (char)k) == EMPTY) //Time to send escape sequence { if (c!=EMPTY) { putBits(bits, c); h->shadowArray[c]->time=(++time); } putBits(bits, ESCAPE); putBits(CHAR_BIT, k); if(h->numElements < ( 1 << args[1])) { latestCode = insert(h, EMPTY, (char)k, 1); if(latestCode>= (1<<(bits))) { putBits(bits, INCR); bits++; } } c = EMPTY; } else { putBits(bits, c); h->shadowArray[c]->time=(++time); if(h->numElements < ( 1 << args[1])) { latestCode = insert(h, c, (char)k, 1); if(latestCode>= (1<<(bits))) { putBits(bits, INCR); bits++; } } c = findInHash(h, EMPTY, (char)k); } if(args[2] && h->numElements == ( 1 << args[1])-1) { putBits(bits, RESET); putBits(bits, c); prune(args, &h, time); //bitchange c=EMPTY; } } if (c!=EMPTY) putBits(bits, c); flushBits(); //printHash(h); freeHash (h); return 0; }
int main(int argc, char **argv) { clock_t begin, end; double time_spent; begin = clock(); int NUM_FINDCODE_CALLS = 0; int NUM_HASHCELLS_VISITED = 0; int c = 0; //char in (pref, char) int prefix = EMPTY_CODE; int index = EMPTY_CODE; int MAXBITS = 15; //default char DUMP_TO[PATH_MAX]; char INIT_FROM[PATH_MAX]; int PRUNE = -1; Table *stringTable = initStringTable(MAXBITS); //setting params from cmd line argv's STARTING FROM 2 BC ENCODE/DECODE for (int i = 2; i < argc; ++i) { if (strcmp(argv[i], "-m") == 0) { //ERROR CHECK FOR IF NEXT ARGV IS NOT INTEGER STRING??? MAXBITS = atoi(argv[i + 1]); i++; } else if (strcmp(argv[i], "-o") == 0) { if(i + 1 == argc) { fprintf(stderr, "usage: encode [-m MAXBITS | -o NAME | -i NAME | -p USED]* OR decode [-o NAME]*\n"); exit(EXIT_FAILURE); //EDGE CASE: IF -O -O HI, THEN DO WE DUMP TO '-O' AND SIGNAL ERROR ON HI? OR DO WE DUMP TO -O, AND OVERRIDE WITH DUMPING TO 'HI'? } strncpy(DUMP_TO, argv[i + 1], strlen(argv[i + 1])); i++; } else if (strcmp(argv[i], "-i") == 0) { if(i + 1 == argc) { fprintf(stderr, "usage: encode [-m MAXBITS | -o NAME | -i NAME | -p USED]* OR decode [-o NAME]*\n"); exit(EXIT_FAILURE); } strncpy(INIT_FROM, argv[i + 1], strlen(argv[i + 1])); i++; } else if (strcmp(argv[i], "-p") == 0) { if(i + 1 == argc) { fprintf(stderr, "usage: encode [-m MAXBITS | -o NAME | -i NAME | -p USED]* OR decode [-o NAME]*\n"); exit(EXIT_FAILURE); } PRUNE = atoi(argv[i + 1]); //test if not an integer; what if prune is 0? w i++; if(PRUNE){} } else { fprintf(stderr, "usage: encode [-m MAXBITS | -o NAME | -i NAME | -p USED]* OR decode [-o NAME]*\n"); exit(EXIT_FAILURE); } } fprintf(stderr, "argv[0]: %s\n", argv[0]); if(strcmp(argv[1], "encode") == 0) { //ENCODE while((c = getchar()) != EOF) { index = findCode(prefix, c, stringTable, &NUM_FINDCODE_CALLS, &NUM_HASHCELLS_VISITED); if (index != -1) //(pref, char) found in stringTable { prefix = index; (stringTable->table[prefix]->useCount)++; continue; } else { //not found in stringTable putBits(stringTable->nBits, prefix); insertToTable(prefix, c, &stringTable, PRUNE); prefix = findCode(0, c, stringTable, &NUM_FINDCODE_CALLS, &NUM_HASHCELLS_VISITED); //start search again at finalChar of newly found sequence (stringTable->table[prefix]->useCount)++; } } putBits(stringTable->nBits, prefix); flushBits(); // printTable(stringTable, "encode"); // fprintf(stderr, "\nNUM_FINDCODE_CALLS: %d\nNUM_HASHCELLS_VISITED: %d\nAVG_SEARCH_RATIO: %d\n", NUM_FINDCODE_CALLS, NUM_HASHCELLS_VISITED, NUM_HASHCELLS_VISITED / NUM_FINDCODE_CALLS); } else if(strcmp(argv[1], "decode") == 0) { //DECODE char ENCODE_OR_DECODE[25] = "decode"; int oldIndex = 0, firstCharOfNewIndex = 0; //used to build stringTable, 1 step behind encode int newIndex = 0; int cascadingIndex = 0; //used to print a code string recursively int kwkwk = 0; //used in kwkwk case int prunedThisPass = 0; int HIT_THE_LIMIT = 0; while( (newIndex = cascadingIndex = getBits(stringTable->nBits)) != EOF) { //nBits was incremented just before to accomodate increased nBits in ENCODE that hasn't been automatically detected in DECODE //and we decrement it now bc it will be automatically incremented in INSERTTABLE //but if == MAXBITS, then we did not artificially increment nBits last round if(stringTable->last + 1 == stringTable->size && !HIT_THE_LIMIT ) {//2nd condition happens when table is already maxSize, in which case no more doubling or pruning happens if(!prunedThisPass) //when pruning results in an at-limit table stringTable->nBits--; if(stringTable->size != 1<<stringTable->nBits){ fprintf(stderr, "size: %d, nBits: %d\n", stringTable->size, stringTable->nBits); exit(EXIT_FAILURE); } else { } } if(newIndex > stringTable->last) //newIndex is an unknown code (kwkwk abnormal case) { kwkwk = 1; if(newIndex < stringTable->size) stringTable->table[newIndex]->useCount++; //useCount usually incremented in printRecursive function, which will not receive newIndex in this case cascadingIndex = oldIndex; } printRecursive(&cascadingIndex, stringTable); if (kwkwk == 1) { printf("%c", firstCharOfNewIndex); //output should be oldCode, oldCode, firstCharOfOldCode kwkwk = 0; } if(cascadingIndex >= stringTable->size) { fprintf(stderr, "cascadingIndex: %d, size: %d\n", cascadingIndex, stringTable->size); exit(EXIT_FAILURE); } firstCharOfNewIndex = stringTable->table[cascadingIndex]->c; //finalK = char(c) if(oldIndex != 0 && !prunedThisPass) { //every time except first time, and after pruning, add new code to table insertToTable(oldIndex, firstCharOfNewIndex, &stringTable, PRUNE); } prunedThisPass = 0; oldIndex = newIndex; if(stringTable->last + 1 >= stringTable->size) { //decode is one step behind encode; deocde inserts new code every time it reads a code, starting from 2nd code //encode adds a code at every code starting from 1st code. CURRENT CODE + firstChar of NEXT CODE was the last code //encode tried to add to table and PRUNED or DOUBLE'd //=>PRUNING or DOUBLING:: //if DOUBLING: next code will increment nBits //if PRUNING: next code is encoded from a PRUNED table, not CURRENT table (and we don't insert next round) if(stringTable->nBits != stringTable->MAXBITS) { if(stringTable->nBits == 8){ exit(EXIT_FAILURE); } stringTable->nBits++; } else { //next insert exceeds table size, and table size is MAXBITS size, so PRUNE HIT_THE_LIMIT = 1; if(PRUNE != -1) { prune(&stringTable, PRUNE, ENCODE_OR_DECODE); prunedThisPass = 1; if (stringTable->last + 1 == stringTable->size) { fprintf(stderr, "HERE!!! last: %d, size: %d\n", stringTable->last, stringTable->size); char temp[10] = "encode"; printTable(stringTable, temp); } if(stringTable->last + 1 != 1<<stringTable->MAXBITS) HIT_THE_LIMIT = 0; } } } } // printTable(stringTable, "decode"); } moses(stringTable); end = clock(); time_spent = (double)(end - begin) / CLOCKS_PER_SEC; fprintf(stderr, "time_spent: %f\n", time_spent); }