diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /gfx/angle/checkout/third_party/zlib/google | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'gfx/angle/checkout/third_party/zlib/google')
-rw-r--r-- | gfx/angle/checkout/third_party/zlib/google/compression_utils_portable.cc | 205 | ||||
-rw-r--r-- | gfx/angle/checkout/third_party/zlib/google/compression_utils_portable.h | 63 |
2 files changed, 268 insertions, 0 deletions
diff --git a/gfx/angle/checkout/third_party/zlib/google/compression_utils_portable.cc b/gfx/angle/checkout/third_party/zlib/google/compression_utils_portable.cc new file mode 100644 index 0000000000..49d6bfe9ea --- /dev/null +++ b/gfx/angle/checkout/third_party/zlib/google/compression_utils_portable.cc @@ -0,0 +1,205 @@ +/* compression_utils_portable.cc + * + * Copyright 2019 The Chromium Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the Chromium source repository LICENSE file. + */ + +#include "compression_utils_portable.h" + +#include <stddef.h> +#include <stdlib.h> +#include <string.h> + +namespace zlib_internal { + +// The difference in bytes between a zlib header and a gzip header. +const size_t kGzipZlibHeaderDifferenceBytes = 16; + +// Pass an integer greater than the following get a gzip header instead of a +// zlib header when calling deflateInit2() and inflateInit2(). +const int kWindowBitsToGetGzipHeader = 16; + +// This describes the amount of memory zlib uses to compress data. It can go +// from 1 to 9, with 8 being the default. For details, see: +// http://www.zlib.net/manual.html (search for memLevel). +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) { + return kGzipZlibHeaderDifferenceBytes + compressBound(input_size); +} + +// The expected decompressed size is stored in the last +// 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; + + memcpy(&size, &compressed_data[length - sizeof(size)], sizeof(size)); +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + return size; +#else + return __builtin_bswap32(size); +#endif +} + +// 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, + Z_DEFAULT_COMPRESSION, 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. +// +// Compression level can be a number from 1-9, with 1 being the fastest, 9 being +// the best compression. The default, which the GZIP helper uses, is 6. +int CompressHelper(WrapperType wrapper_type, + Bytef* dest, + uLongf* dest_length, + const Bytef* source, + uLong source_length, + int compression_level, + void* (*malloc_fn)(size_t), + void (*free_fn)(void*)) { + if (compression_level < 0 || compression_level > 9) { + compression_level = Z_DEFAULT_COMPRESSION; + } + + z_stream stream; + + // FIXME(cavalcantii): z_const is not defined as 'const'. + stream.next_in = static_cast<z_const Bytef*>(const_cast<Bytef*>(source)); + stream.avail_in = static_cast<uInt>(source_length); + stream.next_out = dest; + stream.avail_out = static_cast<uInt>(*dest_length); + if (static_cast<uLong>(stream.avail_out) != *dest_length) + return Z_BUF_ERROR; + + // Cannot convert capturing lambdas to function pointers directly, hence the + // structure. + struct MallocFreeFunctions { + void* (*malloc_fn)(size_t); + void (*free_fn)(void*); + } malloc_free = {malloc_fn, free_fn}; + + if (malloc_fn) { + if (!free_fn) + return Z_BUF_ERROR; + + auto zalloc = [](void* opaque, uInt items, uInt size) { + return reinterpret_cast<MallocFreeFunctions*>(opaque)->malloc_fn(items * + size); + }; + auto zfree = [](void* opaque, void* address) { + return reinterpret_cast<MallocFreeFunctions*>(opaque)->free_fn(address); + }; + + stream.zalloc = static_cast<alloc_func>(zalloc); + stream.zfree = static_cast<free_func>(zfree); + stream.opaque = static_cast<voidpf>(&malloc_free); + } else { + stream.zalloc = static_cast<alloc_func>(0); + stream.zfree = static_cast<free_func>(0); + stream.opaque = static_cast<voidpf>(0); + } + + int err = deflateInit2(&stream, compression_level, Z_DEFLATED, + ZlibStreamWrapperType(wrapper_type), kZlibMemoryLevel, + Z_DEFAULT_STRATEGY); + 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) { + deflateEnd(&stream); + return err == Z_OK ? Z_BUF_ERROR : err; + } + *dest_length = stream.total_out; + + err = deflateEnd(&stream); + return err; +} + +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'. + stream.next_in = static_cast<z_const Bytef*>(const_cast<Bytef*>(source)); + stream.avail_in = static_cast<uInt>(source_length); + if (static_cast<uLong>(stream.avail_in) != source_length) + return Z_BUF_ERROR; + + stream.next_out = dest; + stream.avail_out = static_cast<uInt>(*dest_length); + if (static_cast<uLong>(stream.avail_out) != *dest_length) + return Z_BUF_ERROR; + + stream.zalloc = static_cast<alloc_func>(0); + stream.zfree = static_cast<free_func>(0); + + int err = inflateInit2(&stream, ZlibStreamWrapperType(wrapper_type)); + if (err != Z_OK) + return err; + + err = inflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) { + inflateEnd(&stream); + if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0)) + return Z_DATA_ERROR; + return err; + } + *dest_length = stream.total_out; + + err = inflateEnd(&stream); + return err; +} + +} // namespace zlib_internal diff --git a/gfx/angle/checkout/third_party/zlib/google/compression_utils_portable.h b/gfx/angle/checkout/third_party/zlib/google/compression_utils_portable.h new file mode 100644 index 0000000000..92b033e889 --- /dev/null +++ b/gfx/angle/checkout/third_party/zlib/google/compression_utils_portable.h @@ -0,0 +1,63 @@ +/* compression_utils_portable.h + * + * Copyright 2019 The Chromium Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the Chromium source repository LICENSE file. + */ +#ifndef THIRD_PARTY_ZLIB_GOOGLE_COMPRESSION_UTILS_PORTABLE_H_ +#define THIRD_PARTY_ZLIB_GOOGLE_COMPRESSION_UTILS_PORTABLE_H_ + +#include <stdint.h> + +/* TODO(cavalcantii): remove support for Chromium ever building with a system + * zlib. + */ +#if defined(USE_SYSTEM_ZLIB) +#include <zlib.h> +/* AOSP build requires relative paths. */ +#else +#include "zlib.h" +#endif + +namespace zlib_internal { + +enum WrapperType { + ZLIB, + GZIP, + ZRAW, +}; + +uLongf GzipExpectedCompressedSize(uLongf input_size); + +uint32_t GetGzipUncompressedSize(const Bytef* compressed_data, size_t length); + +int GzipCompressHelper(Bytef* dest, + uLongf* dest_length, + const Bytef* source, + uLong source_length, + 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, + int compression_level, + 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_ |