MCPcopy Create free account
hub / github.com/OpenRCT2/OpenRCT2 / zlibDecompress

Function zlibDecompress

src/openrct2/core/Compression.cpp:85–141  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

83 }
84
85 bool zlibDecompress(IStream& source, uint64_t sourceLength, IStream& dest, uint64_t decompressLength, ZlibHeaderType header)
86 {
87 if (sourceLength > source.GetLength() - source.GetPosition())
88 throw IOException("Not Enough Data to Decompress");
89
90 StreamReadBuffer sourceBuf(source, sourceLength, kZlibChunkSize);
91 StreamWriteBuffer destBuf(dest, decompressLength, kZlibChunkSize);
92
93 z_stream strm{};
94 int ret = inflateInit2(&strm, kZlibWindowBits[static_cast<int>(header)]);
95 if (ret != Z_OK)
96 {
97 LOG_ERROR("Failed to initialise stream");
98 return false;
99 }
100
101 do
102 {
103 auto readBlock = sourceBuf.ReadBlock(source, kZlibMaxChunkSize);
104 strm.next_in = static_cast<const Bytef*>(readBlock.first);
105 strm.avail_in = static_cast<uInt>(readBlock.second);
106
107 do
108 {
109 if (!destBuf)
110 {
111 LOG_ERROR("Decompressed data larger than expected");
112 inflateEnd(&strm);
113 return false;
114 }
115
116 auto writeBlock = destBuf.WriteBlockStart(kZlibMaxChunkSize);
117 strm.next_out = static_cast<Bytef*>(writeBlock.first);
118 strm.avail_out = static_cast<uInt>(writeBlock.second);
119
120 ret = inflate(&strm, sourceBuf ? Z_NO_FLUSH : Z_FINISH);
121 if (ret == Z_STREAM_ERROR)
122 {
123 LOG_ERROR("Failed to decompress data");
124 inflateEnd(&strm);
125 return false;
126 }
127
128 destBuf.WriteBlockCommit(dest, writeBlock.second - strm.avail_out);
129 } while (strm.avail_in > 0);
130 } while (sourceBuf);
131
132 if (destBuf)
133 {
134 LOG_ERROR("Decompressed data smaller than expected");
135 inflateEnd(&strm);
136 return false;
137 }
138
139 inflateEnd(&strm);
140 return true;
141 }
142

Callers 2

DecompressFileMethod · 0.85
OrcaStreamMethod · 0.85

Calls 6

IOExceptionClass · 0.85
ReadBlockMethod · 0.80
WriteBlockStartMethod · 0.80
WriteBlockCommitMethod · 0.80
GetLengthMethod · 0.45
GetPositionMethod · 0.45

Tested by

no test coverage detected