/
vector_tile_compression.ipp
93 lines (83 loc) · 2.77 KB
/
vector_tile_compression.ipp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
// zlib
#include <zlib.h>
// std
#include <stdexcept>
namespace mapnik
{
namespace vector_tile_impl
{
// decodes both zlib and gzip
// http://stackoverflow.com/a/1838702/2333354
void zlib_decompress(const char * data, std::size_t size, std::string & output)
{
z_stream inflate_s;
inflate_s.zalloc = Z_NULL;
inflate_s.zfree = Z_NULL;
inflate_s.opaque = Z_NULL;
inflate_s.avail_in = 0;
inflate_s.next_in = Z_NULL;
inflateInit2(&inflate_s, 32 + 15);
inflate_s.next_in = (Bytef *)data;
inflate_s.avail_in = size;
size_t length = 0;
do {
output.resize(length + 2 * size);
inflate_s.avail_out = 2 * size;
inflate_s.next_out = (Bytef *)(output.data() + length);
int ret = inflate(&inflate_s, Z_FINISH);
if (ret != Z_STREAM_END && ret != Z_OK && ret != Z_BUF_ERROR)
{
std::string error_msg = inflate_s.msg;
inflateEnd(&inflate_s);
throw std::runtime_error(error_msg);
}
length += (2 * size - inflate_s.avail_out);
} while (inflate_s.avail_out == 0);
inflateEnd(&inflate_s);
output.resize(length);
}
void zlib_decompress(std::string const& input, std::string & output)
{
zlib_decompress(input.data(),input.size(),output);
}
void zlib_compress(const char * data, std::size_t size, std::string & output, bool gzip, int level, int strategy)
{
z_stream deflate_s;
deflate_s.zalloc = Z_NULL;
deflate_s.zfree = Z_NULL;
deflate_s.opaque = Z_NULL;
deflate_s.avail_in = 0;
deflate_s.next_in = Z_NULL;
int windowsBits = 15;
if (gzip)
{
windowsBits = windowsBits | 16;
}
if (deflateInit2(&deflate_s, level, Z_DEFLATED, windowsBits, 8, strategy) != Z_OK)
{
throw std::runtime_error("deflate init failed");
}
deflate_s.next_in = (Bytef *)data;
deflate_s.avail_in = size;
size_t length = 0;
do {
size_t increase = size / 2 + 1024;
output.resize(length + increase);
deflate_s.avail_out = increase;
deflate_s.next_out = (Bytef *)(output.data() + length);
// From http://www.zlib.net/zlib_how.html
// "deflate() has a return value that can indicate errors, yet we do not check it here.
// Why not? Well, it turns out that deflate() can do no wrong here."
// Basically only possible error is from deflateInit not working properly
deflate(&deflate_s, Z_FINISH);
length += (increase - deflate_s.avail_out);
} while (deflate_s.avail_out == 0);
deflateEnd(&deflate_s);
output.resize(length);
}
void zlib_compress(std::string const& input, std::string & output, bool gzip, int level, int strategy)
{
zlib_compress(input.data(),input.size(),output,gzip,level,strategy);
}
} // end ns vector_tile_impl
} // end ns mapnik