int DecompBlock(unsigned char *cdata, unsigned char *buffer, int maxlen) { unsigned char *bpos = buffer, *bpos2, tmp; while(*cdata != 0xFF) { int cmdtype = *cdata >> 5; int len = (*cdata & 0x1F) + 1; if(cmdtype == 7) { cmdtype = (*cdata & 0x1C) >> 2; len = ((*cdata & 3) << 8) + *(cdata + 1) + 1; cdata++; } if(bpos + len > &buffer[maxlen]) return -1; cdata++; if(cmdtype >= 4) { bpos2 = &buffer[(*cdata << 8) + *(cdata + 1)]; if(bpos2 >= &buffer[maxlen]) return -1; cdata += 2; } switch(cmdtype) { case 0: memcpy(bpos, cdata, len); cdata += len; bpos += len; break; case 1: memset(bpos, *cdata++, len); bpos += len; break; case 2: if(bpos + 2 * len > &buffer[maxlen]) return -1; while(len--) { *(short *)bpos = *(short *)cdata; bpos += 2; } cdata += 2; break; case 3: tmp = *cdata++; while(len--) *bpos++ = tmp++; break; case 4: if(bpos2 + len > &buffer[maxlen]) return -1; memcpy(bpos, bpos2, len); bpos += len; break; case 5: if(bpos2 + len > &buffer[maxlen]) return -1; while(len--) { tmp = *bpos2++; /* reverse the bits */ tmp = ((tmp >> 1) & 0x55) | ((tmp << 1) & 0xAA); tmp = ((tmp >> 2) & 0x33) | ((tmp << 2) & 0xCC); tmp = ((tmp >> 4) & 0x0F) | ((tmp << 4) & 0xF0); *bpos++ = tmp; } break; case 6: if(bpos2 - len + 1 < buffer) return -1; while(len--) *bpos++ = *bpos2--; break; case 7: return -1; } } return bpos - buffer; }