/*static*/ int DreamGrafix::UnpackLZW(const uint8_t* srcBuf, long srcLen, uint8_t* dstBuf, long dstLen) { uint16_t finChar, oldCode, inCode, freeCode, maxCode, k; uint16_t nBitMod1, nBitMask; int bitOffset; uint16_t hashNext[4096]; uint16_t hashChar[4096]; uint8_t* pOrigDst = dstBuf; int iCode; uint16_t stack[32768]; int stackIdx = 0; /* initialize table and code reader */ INIT_TABLE(); bitOffset = 0; while (true) { if (dstBuf - pOrigDst > dstLen) { LOGI("LZW overrun"); return -1; } int A; int Y; READ_CODE(); if (iCode == kEofCode) { break; } if (iCode == kClearCode) { // Got Clear INIT_TABLE(); READ_CODE(); oldCode = iCode; k = iCode; finChar = iCode; *dstBuf++ = (uint8_t) iCode; continue; } A = inCode = iCode; if (iCode < freeCode) { goto inTable; } stack[stackIdx] = finChar; stackIdx++; A = oldCode; inTable: if (A < 256) { goto gotChar; } while (A >= 256) { Y = A; A = hashChar[Y]; stack[stackIdx] = A; stackIdx++; A = hashNext[Y]; } gotChar: A &= 0xFF; finChar = A; k = A; Y = 0; dstBuf[Y++] = A; while (stackIdx) { stackIdx--; A = stack[stackIdx]; dstBuf[Y++] = A; } dstBuf += Y; ADD_CODE(); oldCode = inCode; if (freeCode < maxCode) { continue; // goto nextCode; } if (12 == nBitMod1) { continue; // goto nextCode; } nBitMod1++; nBitMask = bitMasks[nBitMod1]; //printf("nBitMod1 = %d, nBitMask = %04x\n", // nBitMod1, nBitMask); maxCode <<= 1; } return dstBuf - pOrigDst; }
/* add the tail of while */ int fytheCodegenWhileTail(struct Buffer_char *buf) { int ret = buf->bufused; ADD_CODE(*buf, start_While_Tail, end_While_Tail); return ret; }
/* add the mid of while */ int fytheCodegenWhileMid(struct Buffer_char *buf) { int ret = buf->bufused; ADD_CODE(*buf, start_While_Mid, start_While_Body); return ret; }
/* add the head of while */ int fytheCodegenWhileHead(struct Buffer_char *buf) { int ret = buf->bufused; ADD_CODE(*buf, start_While_Head, start_While_Cond); return ret; }
/* add the mid of if */ int fytheCodegenIfMid(struct Buffer_char *buf) { int ret = buf->bufused; ADD_CODE(*buf, start_If_Mid, start_If_False); return ret; }
/* add the head of if */ int fytheCodegenIfHead(struct Buffer_char *buf) { int ret = buf->bufused; ADD_CODE(*buf, start_If_Head, start_If_True); return ret; }