void Loader::loadCode(const char *entryLabel) { int length = codeLength() + 64; // NOTE: Code length is not accurate due to alignment issues machineCode = new unsigned char[length]; unsigned char *currentCode = machineCode; #ifdef WIN32 unsigned long oldProtection; VirtualProtect(machineCode, length, PAGE_EXECUTE_READWRITE, &oldProtection); #elif __unix__ mprotect(machineCode, length, PROT_READ | PROT_WRITE | PROT_EXEC); #endif Instruction *instruction = instructions; while(instruction) { Encoding &encoding = *instruction; encoding.setAddress(currentCode); const char *reference = encoding.getReference(); const char *label = encoding.getLabel(); if(reference) { if(encoding.relativeReference()) { int offset = resolveReference(reference, instruction) - currentCode - encoding.length(currentCode); encoding.setJumpOffset(offset); } else { int address = (int)resolveReference(reference, instruction); // Encoded as memory reference or immediate? if(encoding.hasDisplacement()) { encoding.addDisplacement(address); } else if(encoding.hasImmediate()) { encoding.setImmediate(address); } else { INTERNAL_ERROR; } } } else if(encoding.hasImmediate() && encoding.relativeReference()) { int offset = encoding.getImmediate() - (int)currentCode - encoding.length(currentCode); encoding.setCallOffset(offset); } currentCode += encoding.writeCode(currentCode); instruction = instruction->next(); } }
void JpegCodec::variableLenghtHuffmanCoding(int *input, int size, BitDataBuilder &builder) { for (int i = 1; i < size; i += 2) { const int zeros = input[i]; const int len = codeLength(input[i + 1]); builder.appendData(acHuffmanTable[(zeros << 4) + len], acHuffmanLength[(zeros << 4) + len]); int data = input[i + 1]; if (data < 0) data = ~data; builder.appendData(data, len); } }
const char *Loader::getListing() { if(!machineCode) { return 0; } if(listing) { return listing; } listing = new char[codeLength() * 4]; char *buffer = listing; for(Instruction *instruction = instructions; instruction; instruction = instruction->next()) { buffer += instruction->printCode(buffer); } *(buffer - 1) = '\0'; return listing; }
void JpegCodec::dct(char *data, int width, int height, BitDataBuilder &builder) { const int blockSize = 8; const int bufferSize = blockSize * blockSize; char byteBuffer[bufferSize]; int intBuffer1[bufferSize]; int intBuffer2[bufferSize]; int prevDc = 0; for (int i = 0; i < ceil(float(height) / blockSize); ++i) { for (int j = 0; j < ceil(float(width) / blockSize); ++j) { memset(byteBuffer, 0, bufferSize); memset(intBuffer1, 0, bufferSize); memset(intBuffer2, 0, bufferSize); for (int k = 0; k < blockSize; ++k) { if (i * blockSize + k >= height) break; const int pos = (i * blockSize + k) * width + j * blockSize; const int copySize = fmin(blockSize, width - j * blockSize); memcpy(byteBuffer + blockSize * k, data + pos, copySize); if (copySize < blockSize) memset(byteBuffer + blockSize * k + copySize, byteBuffer[blockSize * k + copySize], blockSize - copySize); } dctBlock(byteBuffer, intBuffer1, blockSize); quantizeBlock(intBuffer1, blockSize); for (int a = 0; a < blockSize; ++a) { for (int b = 0; b < blockSize; ++b) { std::cout << intBuffer1[a * blockSize + b] << " "; } std::cout << std::endl; } const int len = runLengthEncoding(intBuffer1, intBuffer2, blockSize); for (int a = 0; a < len; ++a) { std::cout << intBuffer2[a] << " "; } std::cout << std::endl; int data = intBuffer2[0] - prevDc; prevDc = intBuffer2[0]; const int dcCodeLength = codeLength(data); if (data < 0) data = ~(-data); std::cout << "DC " << dcHuffmanTable[dcCodeLength] << " " << dcHuffmanLength[dcCodeLength] << std::endl; std::cout << data << " " << dcCodeLength << std::endl; builder.appendData(dcHuffmanTable[dcCodeLength], dcHuffmanLength[dcCodeLength]); builder.appendData(data, dcCodeLength); variableLenghtHuffmanCoding(intBuffer2, len, builder); } } }
// 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); }
// decodes using lzw algorithm void decode() { int code, newcode; int maxbits = getFlags(2); int maxcodes = (1 << maxbits); int p = getFlags(1); int e = getFlags(1); Trie st; createT(&st, e); int bitCount = (e) ? 2 : 9; int codeCount = (e) ? 3 : 259; int oldc = EMPTY; bool kwk = false; char baseK; int pruneCount=0, kwkcount=0; while((newcode=code=getBits(bitCount))!=EOFILE) { // under these conditions, a valid prune can occur if(p && code==EMPTY) { pruneCount++; Trie newst; createT(&newst, e); int oldCodeCount=codeCount; codeCount=pruneT(&st, &newst, e, oldCodeCount); destroyT(&st, oldCodeCount); st=newst; bitCount=codeLength(codeCount); oldc=EMPTY; continue; } if(newcode>=codeCount+1) { ERROR("code impossible to decode\n"); } // read an escaped character else if(e && code==ESC) { if(tableFilled(codeCount+1)&&bitCount!=codeLength(codeCount+1)) { if(bitCount<maxbits) { bitCount++; } } code=getBits(8); baseK=(char)code; putchar(baseK); if(codeCount<maxcodes) { if(tableFilled(codeCount+1)) { expandT(&st, (codeCount)*2); } addT(&st, oldc, code, codeCount); codeCount++; // then we need to add the char k as it's own code if(oldc!=EMPTY) { if(tableFilled(codeCount+1)) { expandT(&st, (codeCount)*2); } addT(&st, EMPTY, code, codeCount); codeCount++; if(tableFilled(codeCount)&&bitCount!=codeLength(codeCount)) { if(bitCount<maxbits) { bitCount++; } } } } oldc=EMPTY; } else { // no escape character called, would read c and k normally if(newcode==codeCount) { kwk=true; code=oldc; // omega, need to print k after } baseK=outputCode(&st, code, true); if(kwk) { putchar(baseK); kwkcount++; } // oldc is empty on the first read, and when the e-flag is present // oldc is zero when the last character read was escaped if(oldc!=EMPTY) { if(codeCount<maxcodes) { if(tableFilled(codeCount+1)) { expandT(&st, (codeCount)*2); } addT(&st, oldc, (int)baseK, codeCount); codeCount++; if(kwk) { // we added kwk after seeing it once already in the prev // scan through so we should increase its number of apps st[newcode].appearances++; // this scenario means we have kkk, without w in between // so if(st[st[oldc].prefix].prefix==EMPTY&&kwkcount==1) { st[oldc].appearances--; } kwk=false; } if(tableFilled(codeCount+1)) { if(bitCount<maxbits&&bitCount!=codeLength(codeCount+1)) { bitCount++; } } } } else if(e) { // if e-flag & last char was excaped, increase bit count if // table is filled now if(tableFilled(codeCount+1)) { if(bitCount<maxbits) { bitCount++; } } } oldc = newcode; } } destroyT(&st, codeCount); }
// returns (true) if the codeLength of one more insertion would require one more // bit than the current codeCount bool tableFilled(int codeCount) { return(codeLength(codeCount)-codeLength(codeCount-1) == 1); }