bool DecodeData() { Decoded.reserve(MAX_DECODED_SIZE); while (!Stream.Eof() && Decoded.size() < MAX_DECODED_SIZE) { //%0 - put byte if (!Stream.GetBit()) { Decoded.push_back(Stream.GetByte()); continue; } uint_t len = Stream.GetLen(); len += 2; if (2 == len) { const uint_t disp = Stream.GetByte() + 1; if (!CopyFromBack(disp, Decoded, 2)) { return false; } continue; } if (5 == len) { const uint_t data = Stream.GetByte(); if (0xff == data) { break; } if (0xfe == data) { len = Stream.GetLEWord(); } else { len = data + 17; } } else if (len > 5) { --len; } const uint_t disp = GetOffset(); if (!CopyFromBack(disp, Decoded, len)) { return false; } } const uint8_t* const lastBytes = Header.BitStream + Stream.GetProcessedBytes(); std::copy(lastBytes, lastBytes + LAST_BYTES_COUNT, std::back_inserter(Decoded)); return true; }
void DecodeRLE(const uint8_t* data, std::size_t size, Dump& result) { Dump tmp; tmp.reserve(MAX_SECTOR_SIZE); ByteStream stream(data, size); while (!stream.Eof()) { const uint_t len = 2 * stream.GetByte(); Require(!stream.Eof()); const uint_t count = stream.GetByte(); Require(count != 0); const bool isRLE = len != 0; const uint_t blockSize = isRLE ? len : count; Require(stream.GetRestBytes() >= blockSize); for (uint_t idx = 0; idx != blockSize; ++idx) { tmp.push_back(stream.GetByte()); } if (isRLE) { Require(CopyFromBack(len, tmp, len * (count - 1))); } } result.swap(tmp); }
bool DecodeData() { // The main concern is to decode data as much as possible, skipping defenitely invalid structure Decoded.reserve(2 * fromLE(Header.SizeOfPacked)); //assume that first byte always exists due to header format while (!Stream.Eof() && Decoded.size() < MAX_DECODED_SIZE) { const uint_t data = Stream.GetByte(); if (0x80 == data) { //exit break; } //at least one more byte required if (Stream.Eof()) { return false; } const uint_t code = data & 0xc0; if (0x80 == code) { uint_t len = data & 0x3f; assert(len); for (; len && !Stream.Eof(); --len) { Decoded.push_back(Stream.GetByte()); } if (len) { return false; } } else if (0xc0 == code) { const std::size_t len = (data & 0x3f) + 3; const uint8_t data = Stream.GetByte(); std::fill_n(std::back_inserter(Decoded), len, data); } else { const std::size_t len = ((data & 0xf0) >> 4) + 3; const uint_t offset = 256 * (data & 0x0f) + Stream.GetByte(); if (!CopyFromBack(offset, Decoded, len)) { return false; } } } while (!Stream.Eof()) { Decoded.push_back(Stream.GetByte()); } return true; }
void DecodeR2P(const uint8_t* data, std::size_t size, Dump& result) { Require(size % sizeof(R2PEntry) == 0); Dump tmp; tmp.reserve(MAX_SECTOR_SIZE); for (const R2PEntry* it = safe_ptr_cast<const R2PEntry*>(data), *lim = it + size / sizeof(*it); it != lim; ++it) { const uint_t count = fromLE(it->Count); Require(count != 0); tmp.push_back(it->Data[0]); tmp.push_back(it->Data[1]); Require(CopyFromBack(sizeof(it->Data), tmp, sizeof(it->Data) * (count - 1))); } result.swap(tmp); }