bool inflateZlibInstallShield(byte *dst, uint dstLen, const byte *src, uint srcLen) { if (!dst || !dstLen || !src || !srcLen) return false; // See if we have sync bytes. If so, just use our function for that. if (srcLen >= 4 && READ_BE_UINT32(src + srcLen - 4) == 0xFFFF) return inflateZlibHeaderless(dst, dstLen, src, srcLen); // Otherwise, we have some custom code we get to use here. byte *temp = (byte *)malloc(kTempBufSize); uint32 bytesRead = 0, bytesProcessed = 0; while (bytesRead < srcLen) { uint16 chunkSize = READ_LE_UINT16(src + bytesRead); bytesRead += 2; // Initialize zlib z_stream stream; stream.next_in = const_cast<byte *>(src + bytesRead); stream.avail_in = chunkSize; stream.next_out = temp; stream.avail_out = kTempBufSize; stream.zalloc = Z_NULL; stream.zfree = Z_NULL; stream.opaque = Z_NULL; // Negative MAX_WBITS tells zlib there's no zlib header int err = inflateInit2(&stream, -MAX_WBITS); if (err != Z_OK) return false; err = inflate(&stream, Z_FINISH); if (err != Z_OK && err != Z_STREAM_END) { inflateEnd(&stream); free(temp); return false; } memcpy(dst + bytesProcessed, temp, stream.total_out); bytesProcessed += stream.total_out; inflateEnd(&stream); bytesRead += chunkSize; } free(temp); return true; }
uint32 CdfArchive::BlockDecode(uint8 *dst, uint32 a_dst_size, const uint8 *a_src, uint32 a_src_size) const { uint32 dst_size = 0; uint16 data_type = READ_LE_UINT16(a_src); const uint8 *src = a_src + sizeof(uint16); uint32 src_size = a_src_size - sizeof(uint16); // data uncompressed, just copy contents if(data_type == 0) { memcpy(dst, src, src_size); dst_size = src_size; } // deflate compression used else if(data_type == 8) dst_size = inflateZlibHeaderless((byte *)dst, a_dst_size, src, src_size); return dst_size; }