Signed-off-by: Jordan Justen <jordan.l.jus...@intel.com> --- src/util/Makefile.sources | 4 +- src/util/meson.build | 2 + src/util/u_zlib.c | 154 ++++++++++++++++++++++++++++++++++++++++++++++ src/util/u_zlib.h | 50 +++++++++++++++ 4 files changed, 209 insertions(+), 1 deletion(-) create mode 100644 src/util/u_zlib.c create mode 100644 src/util/u_zlib.h
diff --git a/src/util/Makefile.sources b/src/util/Makefile.sources index 104ecae8ed3..3666e536201 100644 --- a/src/util/Makefile.sources +++ b/src/util/Makefile.sources @@ -56,7 +56,9 @@ MESA_UTIL_FILES := \ u_string.h \ u_thread.h \ u_vector.c \ - u_vector.h + u_vector.h \ + u_zlib.c \ + u_zlib.h MESA_UTIL_GENERATED_FILES = \ format_srgb.c diff --git a/src/util/meson.build b/src/util/meson.build index ac86c9e111e..340b07c265d 100644 --- a/src/util/meson.build +++ b/src/util/meson.build @@ -81,6 +81,8 @@ files_mesa_util = files( 'u_thread.h', 'u_vector.c', 'u_vector.h', + 'u_zlib.c', + 'u_zlib.h', ) install_data('drirc', install_dir : get_option('sysconfdir')) diff --git a/src/util/u_zlib.c b/src/util/u_zlib.c new file mode 100644 index 00000000000..2d961cfaa75 --- /dev/null +++ b/src/util/u_zlib.c @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2017 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifdef HAVE_ZLIB + +#include "u_zlib.h" + +#include <assert.h> +#include <unistd.h> +#include <zlib.h> + +static ssize_t +write_all(int fd, const void *buf, size_t count) +{ + const char *out = buf; + ssize_t written; + size_t done; + + for (done = 0; done < count; done += written) { + written = write(fd, out + done, count - done); + if (written == -1) + return -1; + } + return done; +} + +/* From the zlib docs: + * "If the memory is available, buffers sizes on the order of 128K or 256K + * bytes should be used." + */ +#define BUFSIZE 256 * 1024 + +/** + * Compresses cache entry in memory and writes it to disk. Returns the size + * of the data written to disk. + */ +size_t +zlib_deflate_to_fd(const void *in_data, size_t in_data_size, int fd) +{ + unsigned char out[BUFSIZE]; + + /* allocate deflate state */ + z_stream strm; + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + strm.next_in = (uint8_t *) in_data; + strm.avail_in = in_data_size; + + int ret = deflateInit(&strm, Z_BEST_COMPRESSION); + if (ret != Z_OK) + return 0; + + /* compress until end of in_data */ + size_t compressed_size = 0; + int flush; + do { + int remaining = in_data_size - BUFSIZE; + flush = remaining > 0 ? Z_NO_FLUSH : Z_FINISH; + in_data_size -= BUFSIZE; + + /* Run deflate() on input until the output buffer is not full (which + * means there is no more data to deflate). + */ + do { + strm.avail_out = BUFSIZE; + strm.next_out = out; + + ret = deflate(&strm, flush); /* no bad return value */ + assert(ret != Z_STREAM_ERROR); /* state not clobbered */ + + size_t have = BUFSIZE - strm.avail_out; + compressed_size += have; + + ssize_t written = write_all(fd, out, have); + if (written == -1) { + (void)deflateEnd(&strm); + return 0; + } + } while (strm.avail_out == 0); + + /* all input should be used */ + assert(strm.avail_in == 0); + + } while (flush != Z_FINISH); + + /* stream should be complete */ + assert(ret == Z_STREAM_END); + + /* clean up and return */ + (void)deflateEnd(&strm); + return compressed_size; +} + +/** + * Decompresses cache entry, returns true if successful. + */ +bool +zlib_inflate(uint8_t *in_data, size_t in_data_size, uint8_t *out_data, + size_t out_data_size) +{ + z_stream strm; + + /* allocate inflate state */ + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + strm.next_in = in_data; + strm.avail_in = in_data_size; + strm.next_out = out_data; + strm.avail_out = out_data_size; + + int ret = inflateInit(&strm); + if (ret != Z_OK) + return false; + + ret = inflate(&strm, Z_NO_FLUSH); + assert(ret != Z_STREAM_ERROR); /* state not clobbered */ + + /* Unless there was an error we should have decompressed everything in one + * go as we know the uncompressed file size. + */ + if (ret != Z_STREAM_END) { + (void)inflateEnd(&strm); + return false; + } + assert(strm.avail_out == 0); + + /* clean up and return */ + (void)inflateEnd(&strm); + return true; +} + +#endif /* HAVE_ZLIB */ diff --git a/src/util/u_zlib.h b/src/util/u_zlib.h new file mode 100644 index 00000000000..6546564f6f7 --- /dev/null +++ b/src/util/u_zlib.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2017 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef UTIL_ZLIB_H +#define UTIL_ZLIB_H + +#ifdef HAVE_ZLIB + +#include <stdbool.h> +#include <stdint.h> +#include <stdio.h> + +#ifdef __cplusplus +extern "C" { +#endif + +size_t +zlib_deflate_to_fd(const void *in_data, size_t in_data_size, int fd); + +bool +zlib_inflate(uint8_t *in_data, size_t in_data_size, uint8_t *out_data, + size_t out_data_size); + +#ifdef __cplusplus +} +#endif + +#endif /* HAVE_ZLIB_H */ + +#endif /* UTIL_ZLIB_H */ -- 2.14.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev