diff options
| author | bruvzg <7645683+bruvzg@users.noreply.github.com> | 2020-08-11 12:10:23 +0300 |
|---|---|---|
| committer | bruvzg <7645683+bruvzg@users.noreply.github.com> | 2020-11-26 13:55:27 +0200 |
| commit | b9f441e81e89728f284f61991e14748208817efd (patch) | |
| tree | a3729bf0b71f11b324d2dff8838e914780917701 /thirdparty/graphite/src/Decompressor.cpp | |
| parent | 493da99269b3a111cf58e0352495e25ee49c5f84 (diff) | |
| download | redot-engine-b9f441e81e89728f284f61991e14748208817efd.tar.gz | |
[Complex Text Layouts] Add third-party TextServer dependencies (ICU, HarfBuzz, Graphite).
Diffstat (limited to 'thirdparty/graphite/src/Decompressor.cpp')
| -rw-r--r-- | thirdparty/graphite/src/Decompressor.cpp | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/thirdparty/graphite/src/Decompressor.cpp b/thirdparty/graphite/src/Decompressor.cpp new file mode 100644 index 0000000000..42dc9113e5 --- /dev/null +++ b/thirdparty/graphite/src/Decompressor.cpp @@ -0,0 +1,125 @@ +/* GRAPHITE2 LICENSING + + Copyright 2015, SIL International + All rights reserved. + + This library is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should also have received a copy of the GNU Lesser General Public + License along with this library in the file named "LICENSE". + If not, write to the Free Software Foundation, 51 Franklin Street, + Suite 500, Boston, MA 02110-1335, USA or visit their web page on the + internet at http://www.fsf.org/licenses/lgpl.html. + +Alternatively, the contents of this file may be used under the terms of the +Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public +License, as published by the Free Software Foundation, either version 2 +of the License or (at your option) any later version. +*/ +#include <cassert> + +#include "inc/Decompressor.h" +#include "inc/Compression.h" + +using namespace lz4; + +namespace { + +inline +u32 read_literal(u8 const * &s, u8 const * const e, u32 l) { + if (l == 15 && s != e) + { + u8 b = 0; + do { l += b = *s++; } while(b==0xff && s != e); + } + return l; +} + +bool read_sequence(u8 const * &src, u8 const * const end, u8 const * &literal, + u32 & literal_len, u32 & match_len, u32 & match_dist) +{ + u8 const token = *src++; + + literal_len = read_literal(src, end, token >> 4); + literal = src; + src += literal_len; + + // Normal exit for end of stream, wrap arround check and parital match check. + if (src > end - sizeof(u16) || src < literal) + return false; + + match_dist = *src++; + match_dist |= *src++ << 8; + match_len = read_literal(src, end, token & 0xf) + MINMATCH; + + // Malformed stream check. + return src <= end-MINCODA; +} + +} + +int lz4::decompress(void const *in, size_t in_size, void *out, size_t out_size) +{ + if (out_size <= in_size || in_size < MINSRCSIZE) + return -1; + + u8 const * src = static_cast<u8 const *>(in), + * literal = 0, + * const src_end = src + in_size; + + u8 * dst = static_cast<u8*>(out), + * const dst_end = dst + out_size; + + // Check the in and out size hasn't wrapped around. + if (src >= src_end || dst >= dst_end) + return -1; + + u32 literal_len = 0, + match_len = 0, + match_dist = 0; + + while (read_sequence(src, src_end, literal, literal_len, match_len, + match_dist)) + { + if (literal_len != 0) + { + // Copy in literal. At this point the a minimal literal + minminal + // match plus the coda (1 + 2 + 5) must be 8 bytes or more allowing + // us to remain within the src buffer for an overrun_copy on + // machines upto 64 bits. + if (align(literal_len) > out_size) + return -1; + dst = overrun_copy(dst, literal, literal_len); + out_size -= literal_len; + } + + // Copy, possibly repeating, match from earlier in the + // decoded output. + u8 const * const pcpy = dst - match_dist; + if (pcpy < static_cast<u8*>(out) + || match_len > unsigned(out_size - LASTLITERALS) + // Wrap around checks: + || out_size < LASTLITERALS || pcpy >= dst) + return -1; + if (dst > pcpy+sizeof(unsigned long) + && align(match_len) <= out_size) + dst = overrun_copy(dst, pcpy, match_len); + else + dst = safe_copy(dst, pcpy, match_len); + out_size -= match_len; + } + + if (literal > src_end - literal_len || literal_len > out_size) + return -1; + dst = fast_copy(dst, literal, literal_len); + + return int(dst - (u8*)out); +} |
