summaryrefslogtreecommitdiff
path: root/google
diff options
context:
space:
mode:
authorSam Maier <smaier@chromium.org>2019-11-08 17:43:30 +0000
committerCommit Bot <commit-bot@chromium.org>2019-11-08 17:43:30 +0000
commitf4f46747bd5c68320126fea54d6993ae0b5c3edd (patch)
treeb8dcd0ac080bed0528aff38d3e694d7fa96f9238 /google
parent63bb48cebaec69415fef04dec77d1bd505d05d31 (diff)
downloadzlib-f4f46747bd5c68320126fea54d6993ae0b5c3edd.tar.gz
Adding support for remaining deflate wrappers (zlib | raw) to
compression_utils_portable This allows client code to select the wrapper format used which may be faster (e.g. zlib format on older ARMv7 and early ARMv8 SoCs) depending on the application. The wrapper format selection code was partially taken from zlib_bench.cc. Bug: 833361 Change-Id: I8a317e6abc8bd2d66f2e940406badfd7e930e809 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1904505 Reviewed-by: Adenilson Cavalcanti <cavalcantii@chromium.org> Commit-Queue: Adenilson Cavalcanti <cavalcantii@chromium.org> Cr-Original-Commit-Position: refs/heads/master@{#713870} Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src Cr-Mirrored-Commit: 8549d411737d978d478f1c4aa13ded47721dbcc9
Diffstat (limited to 'google')
-rw-r--r--google/compression_utils.cc4
-rw-r--r--google/compression_utils_portable.cc71
-rw-r--r--google/compression_utils_portable.h24
3 files changed, 78 insertions, 21 deletions
diff --git a/google/compression_utils.cc b/google/compression_utils.cc
index d1218d7..9f63a84 100644
--- a/google/compression_utils.cc
+++ b/google/compression_utils.cc
@@ -42,7 +42,7 @@ bool GzipCompress(base::StringPiece input, std::string* output) {
const uLongf input_size = static_cast<uLongf>(input.size());
uLongf compressed_data_size =
- zlib_internal::GZipExpectedCompressedSize(input_size);
+ zlib_internal::GzipExpectedCompressedSize(input_size);
Bytef* compressed_data;
if (!base::UncheckedMalloc(compressed_data_size,
@@ -109,7 +109,7 @@ bool GzipUncompress(base::StringPiece input, std::string* output) {
}
uint32_t GetUncompressedSize(base::StringPiece compressed_data) {
- return zlib_internal::GetUncompressedSize(
+ return zlib_internal::GetGzipUncompressedSize(
bit_cast<Bytef*>(compressed_data.data()), compressed_data.length());
}
diff --git a/google/compression_utils_portable.cc b/google/compression_utils_portable.cc
index f4f36b6..21338b5 100644
--- a/google/compression_utils_portable.cc
+++ b/google/compression_utils_portable.cc
@@ -28,13 +28,13 @@ const int kZlibMemoryLevel = 8;
// The expected compressed size is based on the input size factored by
// internal Zlib constants (e.g. window size, etc) plus the wrapper
// header size.
-uLongf GZipExpectedCompressedSize(uLongf input_size) {
+uLongf GzipExpectedCompressedSize(uLongf input_size) {
return kGzipZlibHeaderDifferenceBytes + compressBound(input_size);
}
// The expected decompressed size is stored in the last
-// 4 bytes of |input| in LE.
-uint32_t GetUncompressedSize(const Bytef* compressed_data, size_t length) {
+// 4 bytes of |input| in LE. See https://tools.ietf.org/html/rfc1952#page-5
+uint32_t GetGzipUncompressedSize(const Bytef* compressed_data, size_t length) {
uint32_t size;
if (length < sizeof(size))
return 0;
@@ -47,15 +47,39 @@ uint32_t GetUncompressedSize(const Bytef* compressed_data, size_t length) {
#endif
}
-// This code is taken almost verbatim from third_party/zlib/compress.c. The only
-// difference is deflateInit2() is called which sets the window bits to be > 16.
-// That causes a gzip header to be emitted rather than a zlib header.
+// The number of window bits determines the type of wrapper to use - see
+// https://cs.chromium.org/chromium/src/third_party/zlib/zlib.h?l=566
+inline int ZlibStreamWrapperType(WrapperType type) {
+ if (type == ZLIB) // zlib DEFLATE stream wrapper
+ return MAX_WBITS;
+ if (type == GZIP) // gzip DEFLATE stream wrapper
+ return MAX_WBITS + kWindowBitsToGetGzipHeader;
+ if (type == ZRAW) // no wrapper, use raw DEFLATE
+ return -MAX_WBITS;
+ return 0;
+}
+
int GzipCompressHelper(Bytef* dest,
uLongf* dest_length,
const Bytef* source,
uLong source_length,
void* (*malloc_fn)(size_t),
void (*free_fn)(void*)) {
+ return CompressHelper(GZIP, dest, dest_length, source, source_length,
+ malloc_fn, free_fn);
+}
+
+// This code is taken almost verbatim from third_party/zlib/compress.c. The only
+// difference is deflateInit2() is called which allows different window bits to
+// be set. > 16 causes a gzip header to be emitted rather than a zlib header,
+// and negative causes no header to emitted.
+int CompressHelper(WrapperType wrapper_type,
+ Bytef* dest,
+ uLongf* dest_length,
+ const Bytef* source,
+ uLong source_length,
+ void* (*malloc_fn)(size_t),
+ void (*free_fn)(void*)) {
z_stream stream;
// FIXME(cavalcantii): z_const is not defined as 'const'.
@@ -94,17 +118,21 @@ int GzipCompressHelper(Bytef* dest,
stream.opaque = static_cast<voidpf>(0);
}
- gz_header gzip_header;
- memset(&gzip_header, 0, sizeof(gzip_header));
int err = deflateInit2(&stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED,
- MAX_WBITS + kWindowBitsToGetGzipHeader,
- kZlibMemoryLevel, Z_DEFAULT_STRATEGY);
+ ZlibStreamWrapperType(wrapper_type), kZlibMemoryLevel,
+ Z_DEFAULT_STRATEGY);
if (err != Z_OK)
return err;
- err = deflateSetHeader(&stream, &gzip_header);
- if (err != Z_OK)
- return err;
+ // This has to exist outside of the if statement to prevent it going off the
+ // stack before deflate(), which will use this object.
+ gz_header gzip_header;
+ if (wrapper_type == GZIP) {
+ memset(&gzip_header, 0, sizeof(gzip_header));
+ err = deflateSetHeader(&stream, &gzip_header);
+ if (err != Z_OK)
+ return err;
+ }
err = deflate(&stream, Z_FINISH);
if (err != Z_STREAM_END) {
@@ -117,13 +145,22 @@ int GzipCompressHelper(Bytef* dest,
return err;
}
-// This code is taken almost verbatim from third_party/zlib/uncompr.c. The only
-// difference is inflateInit2() is called which sets the window bits to be > 16.
-// That causes a gzip header to be parsed rather than a zlib header.
int GzipUncompressHelper(Bytef* dest,
uLongf* dest_length,
const Bytef* source,
uLong source_length) {
+ return UncompressHelper(GZIP, dest, dest_length, source, source_length);
+}
+
+// This code is taken almost verbatim from third_party/zlib/uncompr.c. The only
+// difference is inflateInit2() is called which allows different window bits to
+// be set. > 16 causes a gzip header to be emitted rather than a zlib header,
+// and negative causes no header to emitted.
+int UncompressHelper(WrapperType wrapper_type,
+ Bytef* dest,
+ uLongf* dest_length,
+ const Bytef* source,
+ uLong source_length) {
z_stream stream;
// FIXME(cavalcantii): z_const is not defined as 'const'.
@@ -140,7 +177,7 @@ int GzipUncompressHelper(Bytef* dest,
stream.zalloc = static_cast<alloc_func>(0);
stream.zfree = static_cast<free_func>(0);
- int err = inflateInit2(&stream, MAX_WBITS + kWindowBitsToGetGzipHeader);
+ int err = inflateInit2(&stream, ZlibStreamWrapperType(wrapper_type));
if (err != Z_OK)
return err;
diff --git a/google/compression_utils_portable.h b/google/compression_utils_portable.h
index 5f8b46e..7c3753b 100644
--- a/google/compression_utils_portable.h
+++ b/google/compression_utils_portable.h
@@ -17,9 +17,15 @@
namespace zlib_internal {
-uLongf GZipExpectedCompressedSize(uLongf input_size);
+enum WrapperType {
+ ZLIB,
+ GZIP,
+ ZRAW,
+};
-uint32_t GetUncompressedSize(const Bytef* compressed_data, size_t length);
+uLongf GzipExpectedCompressedSize(uLongf input_size);
+
+uint32_t GetGzipUncompressedSize(const Bytef* compressed_data, size_t length);
int GzipCompressHelper(Bytef* dest,
uLongf* dest_length,
@@ -28,11 +34,25 @@ int GzipCompressHelper(Bytef* dest,
void* (*malloc_fn)(size_t),
void (*free_fn)(void*));
+int CompressHelper(WrapperType wrapper_type,
+ Bytef* dest,
+ uLongf* dest_length,
+ const Bytef* source,
+ uLong source_length,
+ void* (*malloc_fn)(size_t),
+ void (*free_fn)(void*));
+
int GzipUncompressHelper(Bytef* dest,
uLongf* dest_length,
const Bytef* source,
uLong source_length);
+int UncompressHelper(WrapperType wrapper_type,
+ Bytef* dest,
+ uLongf* dest_length,
+ const Bytef* source,
+ uLong source_length);
+
} // namespace zlib_internal
#endif // THIRD_PARTY_ZLIB_GOOGLE_COMPRESSION_UTILS_PORTABLE_H_