blob: f37208b84ec808200753cc6e1a02f1003cf7644b [file] [log] [blame]
Tom Cherry1a796bc2020-05-13 09:28:37 -07001/*
2 * Copyright (C) 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "CompressionEngine.h"
18
19#include <limits>
20
21#include <android-base/logging.h>
22#include <zlib.h>
23#include <zstd.h>
24
25CompressionEngine& CompressionEngine::GetInstance() {
26 CompressionEngine* engine = new ZstdCompressionEngine();
27 return *engine;
28}
29
30bool ZlibCompressionEngine::Compress(std::span<uint8_t> in, std::vector<uint8_t>& out) {
31 z_stream strm;
32 strm.zalloc = Z_NULL;
33 strm.zfree = Z_NULL;
34 strm.opaque = Z_NULL;
35 int ret = deflateInit(&strm, Z_DEFAULT_COMPRESSION);
36 if (ret != Z_OK) {
37 LOG(FATAL) << "deflateInit() failed";
38 }
39
40 CHECK_LE(in.size(), static_cast<int64_t>(std::numeric_limits<uint32_t>::max()));
41 uint32_t out_size = deflateBound(&strm, in.size());
42
43 out.resize(out_size);
44 strm.avail_in = in.size();
45 strm.next_in = const_cast<uint8_t*>(in.data());
46 strm.avail_out = out_size;
47 strm.next_out = out.data();
48 ret = deflate(&strm, Z_FINISH);
49 CHECK_EQ(ret, Z_STREAM_END);
50
51 uint32_t compressed_data_size = strm.total_out;
52 deflateEnd(&strm);
53 out.resize(compressed_data_size);
54
55 return true;
56}
57
58bool ZlibCompressionEngine::Decompress(const std::vector<uint8_t>& in, std::vector<uint8_t>& out,
59 size_t out_size) {
60 out.resize(out_size);
61
62 z_stream strm;
63 strm.zalloc = Z_NULL;
64 strm.zfree = Z_NULL;
65 strm.opaque = Z_NULL;
66 strm.avail_in = in.size();
67 strm.next_in = const_cast<uint8_t*>(in.data());
68 strm.avail_out = out.size();
69 strm.next_out = out.data();
70
71 inflateInit(&strm);
72 int ret = inflate(&strm, Z_NO_FLUSH);
73
74 CHECK_EQ(strm.avail_in, 0U);
75 CHECK_EQ(strm.avail_out, 0U);
76 CHECK_EQ(ret, Z_STREAM_END);
77 inflateEnd(&strm);
78
79 return true;
80}
81
82bool ZstdCompressionEngine::Compress(std::span<uint8_t> in, std::vector<uint8_t>& out) {
83 size_t out_size = ZSTD_compressBound(in.size());
84 out.resize(out_size);
85
86 out_size = ZSTD_compress(out.data(), out_size, in.data(), in.size(), 1);
87 if (ZSTD_isError(out_size)) {
88 LOG(FATAL) << "ZSTD_compress failed: " << ZSTD_getErrorName(out_size);
89 }
90 out.resize(out_size);
91
92 return true;
93}
94
95bool ZstdCompressionEngine::Decompress(const std::vector<uint8_t>& in, std::vector<uint8_t>& out,
96 size_t out_size) {
97 out.resize(out_size);
98 size_t result = ZSTD_decompress(out.data(), out.size(), in.data(), in.size());
99 if (ZSTD_isError(result)) {
100 LOG(FATAL) << "ZSTD_decompress failed: " << ZSTD_getErrorName(result);
101 }
102 CHECK_EQ(result, out.size());
103 return true;
104}