int64_t ZipReader_Impl::deflate_read(void *data, int64_t size, bool read_all) { zs.next_out = (unsigned char *)data; zs.avail_out = size; // Continue feeding zlib data until we get our data: while (zs.avail_out > 0) { // zlib needs more data: if (zs.avail_in == 0 && compressed_pos < local_header.compressed_size) { // Read some compressed data: int received_input = 0; while (received_input < 16 * 1024) { received_input += input.receive(zbuffer, int(min((int64_t)16 * 1024, local_header.compressed_size - compressed_pos)), true); if (compressed_pos + received_input == local_header.compressed_size) break; } compressed_pos += received_input; zs.next_in = (unsigned char *)zbuffer; zs.avail_in = received_input; } // Decompress data: int result = mz_inflate(&zs, (compressed_pos == local_header.compressed_size) ? MZ_FINISH : MZ_NO_FLUSH); if (result == MZ_STREAM_END) break; if (result == MZ_NEED_DICT) throw Exception("Zlib inflate wants a dictionary!"); if (result == MZ_DATA_ERROR) throw Exception("Zip data stream is corrupted"); if (result == MZ_STREAM_ERROR) throw Exception("Zip stream structure was inconsistent!"); if (result == MZ_MEM_ERROR) throw Exception("Zlib did not have enough memory to decompress file!"); if (result == MZ_BUF_ERROR) throw Exception("Not enough data in buffer when Z_FINISH was used"); if (result != MZ_OK) throw Exception("Zlib inflate failed while decompressing zip file!"); } return size - zs.avail_out; }
source_result::status drive(bool flush = false) { if (empty()) return source_result::eos; int deflate_flags = flush ? MZ_SYNC_FLUSH : MZ_NO_FLUSH; while (true) { if (str.avail_in == 0 && pull) { cur_ = end_; auto s = next_piece_(); if (s == source_result::ok) { str.avail_in = (unsigned int)buf_left(); sassert(str.avail_in > 0); str.next_in = (unsigned char*)cur_; } else if (s != source_result::eos) { return s; } } if (str.avail_out == 0) { cur_out->size_ = str.next_out - cur_out->data; return source_result::ok; } int ret; if (compress) ret = mz_deflate(&str, deflate_flags); else ret = mz_inflate(&str, deflate_flags); if (ret == MZ_STREAM_END) { cur_out->size_ = str.next_out - cur_out->data; close(); return source_result::ok; } else if (ret != MZ_OK) { throw std::runtime_error("Error while deflating"); } else if (deflate_flags == MZ_SYNC_FLUSH && str.avail_in == 0) { cur_out->size_ = str.next_out - cur_out->data; return source_result::ok; } } }
static int lmz_inflator_deflator_impl(lua_State* L, lmz_stream_t* stream) { mz_streamp miniz_stream = &(stream->stream); size_t data_size; const char* data = luaL_checklstring(L, 2, &data_size); int flush = luaL_checkoption(L, 3, "no", flush_types); miniz_stream->avail_in = data_size; miniz_stream->next_in = (const unsigned char*)data; luaL_Buffer buf; luaL_buffinit(L, &buf); while (1) { char* buffer = luaL_prepbuffer(&buf); memset(buffer, 0, LUAL_BUFFERSIZE); miniz_stream->avail_out = LUAL_BUFFERSIZE; miniz_stream->next_out = (unsigned char*)buffer; size_t before = miniz_stream->total_out; int status; if (stream->mode) { status = mz_inflate(miniz_stream, flush); } else { status = mz_deflate(miniz_stream, flush); } size_t added = miniz_stream->total_out - before; luaL_addsize(&buf, added); switch (status) { case MZ_OK: case MZ_STREAM_END: luaL_pushresult(&buf); return 1; case MZ_STREAM_ERROR: case MZ_DATA_ERROR: case MZ_PARAM_ERROR: luaL_pushresult(&buf); lua_pushnil(L); lua_insert(L, -2); lua_pushstring(L, mz_error(status)); lua_insert(L, -2); return 3; case MZ_BUF_ERROR: if (stream->mode) { // not enough input luaL_pushresult(&buf); lua_pushnil(L); lua_insert(L, -2); lua_pushstring(L, "Not enough input data"); lua_insert(L, -2); return 3; } break; } } }
void map_chunk_compressed_StoC::handle(char* buff, size_t byte_num) { GS_ASSERT(client_chunk_alias_list[chunk_alias] == -1); stream.next_in = (unsigned char*) buff; stream.avail_in = byte_num; stream.next_out = (unsigned char*) decompression_buffer; stream.avail_out = DECOMPRESSION_BUFFER_SIZE; int status = mz_inflate(&stream, MZ_SYNC_FLUSH); if (status != MZ_OK) { printf("inflate() failed with status %d!\n", status); return; } int size = DECOMPRESSION_BUFFER_SIZE - stream.avail_out; //printf("compressed chunk: %d bytes decompressed to %d bytes \n", byte_num, size); /* Handle */ client_chunk_alias_list[chunk_alias] = chunk_index; //printf("received chunk: index = %d compressed \n", chunk_index); GS_ASSERT(main_map->chunk[chunk_index] == NULL); GS_ASSERT(MAP_CHUNK_XDIM == 32 && MAP_CHUNK_YDIM == 32); int cx = chunk_index % MAP_CHUNK_XDIM; int cy = chunk_index / MAP_CHUNK_XDIM; main_map->load_chunk(cx, cy); class MapChunk* m = main_map->chunk[chunk_index]; int _size = sizeof(struct MapElement)*16*16*TERRAIN_MAP_HEIGHT; if (size != _size) printf("map_chunk_compressed_StoC::handle, warning: invalid size!\n"); memcpy((char *) m->e, decompression_buffer, _size); m->refresh_height_cache(); //refesh height cache after memcpy main_map->chunk_received(cx,cy); }
St go (int level /* Zip level; 0 to mean unzip */, int ifd, int ofd) { uint8_t x[chunkSize], y[chunkSize]; z_stream s; memset (&s, 0, sizeof (z_stream)); int windowBits = -MZ_DEFAULT_WINDOW_BITS; if (level == 0 ? inflateInit2 (&s, windowBits) : deflateInit2 (&s, level, MZ_DEFLATED, windowBits, 6, MZ_DEFAULT_STRATEGY)) { errx (-1, "failed"); } for (;;) { int n, fin = 0; n = read (ifd, x + s.avail_in, chunkSize - s.avail_in); if (n < 0) err (n, "failed to read"); s.next_in = x; s.next_out = y; s.avail_in += n; s.avail_out = chunkSize; retry: switch (level == 0 ? mz_inflate (&s, MZ_SYNC_FLUSH) : mz_deflate (&s, n > 0 ? MZ_FINISH : MZ_SYNC_FLUSH)) { int n; case MZ_STREAM_END: fin = 1; case MZ_OK: write (ofd, y, chunkSize - s.avail_out); s.avail_in = 0; if (fin) return (St) { .l = level == 0 ? s.total_out : s.total_in, .crc32 = s.crc32 }; break; case MZ_BUF_ERROR: continue; case MZ_DATA_ERROR: errx (-1, "not flated data"); case MZ_PARAM_ERROR: errx (-1, "failed"); } } } ssize_t readn (int fd, void *x, size_t n) { int n0 = n; while (n > 0) { int m = read (fd, x, n); if (m < 0) return m; n -= m; x = (uint8_t *)x + m; } return n0; }
DataBuffer ZLibCompression::decompress(const DataBuffer &data, bool raw) { const int window_bits = 15; DataBuffer zbuffer(1024*1024); IODevice_Memory output; mz_stream zs = { nullptr }; int result = mz_inflateInit2(&zs, raw ? -window_bits : window_bits); if (result != MZ_OK) throw Exception("Zlib inflateInit failed"); zs.next_in = (unsigned char *) data.get_data(); zs.avail_in = data.get_size(); // Continue feeding zlib data until we get our data: while (true) { zs.next_out = (unsigned char *) zbuffer.get_data(); zs.avail_out = zbuffer.get_size(); // Decompress data: int result = mz_inflate(&zs, 0); if (result == MZ_NEED_DICT) throw Exception("Zlib inflate wants a dictionary!"); if (result == MZ_DATA_ERROR) throw Exception("Zip data stream is corrupted"); if (result == MZ_STREAM_ERROR) throw Exception("Zip stream structure was inconsistent!"); if (result == MZ_MEM_ERROR) throw Exception("Zlib did not have enough memory to decompress file!"); if (result == MZ_BUF_ERROR) throw Exception("Not enough data in buffer when Z_FINISH was used"); if (result != MZ_OK && result != MZ_STREAM_END) throw Exception("Zlib inflate failed while decompressing zip file!"); output.write(zbuffer.get_data(), zbuffer.get_size() - zs.avail_out); if (result == MZ_STREAM_END) break; } mz_inflateEnd(&zs); return output.get_data(); }
int ZipIODevice_FileEntry::lowlevel_read(void *data, int size, bool read_all) { switch (file_header.compression_method) { case zip_compress_store: // no compression { int received = iodevice.receive(data, int(min((int64_t)size, file_header.uncompressed_size - pos)), read_all); pos += received; return received; } break; case zip_compress_deflate: zs.next_out = (unsigned char *)data; zs.avail_out = size; // Continue feeding zlib data until we get our data: while (zs.avail_out > 0) { // zlib needs more data: if (zs.avail_in == 0 && compressed_pos < file_header.compressed_size) { // Read some compressed data: int received_input = 0; while (received_input < 16 * 1024) { received_input += iodevice.receive(zbuffer, int(min((int64_t)16 * 1024, file_header.compressed_size - compressed_pos)), true); if (compressed_pos + received_input == file_header.compressed_size) break; } compressed_pos += received_input; zs.next_in = (unsigned char *)zbuffer; zs.avail_in = received_input; } // Decompress data: int result = mz_inflate(&zs, 0); if (result == MZ_STREAM_END) break; if (result == MZ_NEED_DICT) throw Exception("Zlib inflate wants a dictionary!"); if (result == MZ_DATA_ERROR) throw Exception("Zip data stream is corrupted"); if (result == MZ_STREAM_ERROR) throw Exception("Zip stream structure was inconsistent!"); if (result == MZ_MEM_ERROR) throw Exception("Zlib did not have enough memory to decompress file!"); if (result == MZ_BUF_ERROR) throw Exception("Not enough data in buffer when Z_FINISH was used"); if (result != MZ_OK) throw Exception("Zlib inflate failed while decompressing zip file!"); } pos += size - zs.avail_out; return size - zs.avail_out; case zip_compress_shrunk: case zip_compress_expand_factor_1: case zip_compress_expand_factor_2: case zip_compress_expand_factor_3: case zip_compress_expand_factor_4: case zip_compress_implode: case zip_compress_tokenize: case zip_compress_deflate64: case zip_compress_pkware_implode: break; } return 0; }