Beispiel #1
0
		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);
		}
Beispiel #2
0
/* 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);
}
Beispiel #3
0
int main(int argc, char* argv[]){
	int c;
	while ((c=getBits(3)) !=EOF){
		putBits(3, c);
	}
	flushBits();
}
Beispiel #4
0
/* 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)++;
    }
}
Beispiel #5
0
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);

}
Beispiel #7
0
/* 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;
}
Beispiel #8
0
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;
}
Beispiel #9
0
// 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);
}
Beispiel #10
0
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);
}
Beispiel #11
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;
}
Beispiel #12
0
			void set(uint64_t i, uint64_t v) { putBits(D, i*k+o, b, v); /* assert ( get(i) == v ); */ }	
Beispiel #13
0
// 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;
}
Beispiel #15
0
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);
}
Beispiel #16
0
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;
}
Beispiel #17
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);
}