public static int Decode(byte[] src, int srcpos, byte[] dst, int dstpos, int srclen, bool reverse = false) { int dstofs = dstpos; while (srcpos < srclen) { int cmd = FastBinaryStream.ReadByte(src, ref srcpos); // case 2 if ((cmd & 0x80) == 0) { int count = ((cmd & 0x70) >> 4) + 3; int relpos = ((cmd & 0x0f) << 8) + FastBinaryStream.ReadByte(src, ref srcpos); if (dstpos + count > dst.Length) { return(dstpos); } ReplicatePrevious(dst, ref dstpos, dstpos - relpos, count); } // case 1 else if ((cmd & 0x40) == 0) { int count = cmd & 0x3f; if (count == 0) { break; } FastBinaryStream.Copy(src, ref srcpos, dst, ref dstpos, count); } else { cmd &= 0x3f; // case 4 if (cmd == 0x3e) { var count = FastBinaryStream.ReadWord(src, ref srcpos); var color = FastBinaryStream.ReadByte(src, ref srcpos); for (int end = dstpos + count; dstpos < end; dstpos++) { dst[dstpos] = color; } } // case 5 else if (cmd == 0x3f) { int count = FastBinaryStream.ReadWord(src, ref srcpos); int cpypos = FastBinaryStream.ReadWord(src, ref srcpos) + dstofs; if (reverse) { cpypos = dstpos - cpypos; } if (cpypos >= dstpos) { throw new IndexOutOfRangeException("cpypos >= dstpos"); } for (int end = dstpos + count; dstpos < end; dstpos++) { dst[dstpos] = dst[cpypos++]; } } // case 3 else { int count = cmd + 3; int cpypos = FastBinaryStream.ReadWord(src, ref srcpos) + dstofs; if (reverse) { cpypos = dstpos - cpypos; } if (cpypos >= dstpos) { throw new IndexOutOfRangeException("cpypos >= dstpos"); } for (int end = dstpos + count; dstpos < end; dstpos++) { dst[dstpos] = dst[cpypos++]; } } } } return(dstpos); }
public static void Decode(byte[] src, int srclen, byte[] dst, byte[] bse) { int srcpos = 0; int dstpos = 0; int bsepos = 0; int count = 0; while (srcpos < srclen) { int cmd = FastBinaryStream.ReadByte(src, ref srcpos); if ((cmd & 0x80) == 0) { // 00000000 c*8 v*8 = xor next c bytes with v if (cmd == 0) { count = FastBinaryStream.ReadByte(src, ref srcpos); byte color = FastBinaryStream.ReadByte(src, ref srcpos); while (count-- > 0) { dst[dstpos++] = (byte)(bse[bsepos++] ^ color); } } // 0ccccccc = xor the next c bytes from source with those in base else { count = cmd; while (count-- > 0) { dst[dstpos++] = (byte)(src[srcpos++] ^ bse[bsepos++]); } } } else { count = cmd & 0x7f; if (count == 0) { count = FastBinaryStream.ReadWord(src, ref srcpos); cmd = count >> 8; // 10000000 0ccccccc c*8 = large copy base to dest for count if ((cmd & 0x80) == 0) { if (count == 0) { return; } FastBinaryStream.Copy(bse, ref bsepos, dst, ref dstpos, count); } else { count &= 0x3fff; // 10000000 10cccccc c*8 = xor the next c bytes from source with those in base if ((cmd & 0x40) == 0) { while (count-- > 0) { dst[dstpos++] = (byte)(src[srcpos++] ^ bse[bsepos++]); } } // 10000000 11cccccc c*8 v*8 else { byte fill = src[srcpos++]; while (count-- > 0) { dst[dstpos++] = (byte)(bse[bsepos++] ^ fill); } } } } // 1ccccccc = small copy base to dest for count else { FastBinaryStream.Copy(bse, ref bsepos, dst, ref dstpos, count); } } } }