summaryrefslogtreecommitdiff
path: root/Build/source/libs/graphite2/graphite2-1.3.0/src/Decompressor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/graphite2/graphite2-1.3.0/src/Decompressor.cpp')
-rw-r--r--Build/source/libs/graphite2/graphite2-1.3.0/src/Decompressor.cpp102
1 files changed, 102 insertions, 0 deletions
diff --git a/Build/source/libs/graphite2/graphite2-1.3.0/src/Decompressor.cpp b/Build/source/libs/graphite2/graphite2-1.3.0/src/Decompressor.cpp
new file mode 100644
index 00000000000..919678a640b
--- /dev/null
+++ b/Build/source/libs/graphite2/graphite2-1.3.0/src/Decompressor.cpp
@@ -0,0 +1,102 @@
+/* Copyright (c) 2012, Siyuan Fu <fusiyuan2010@gmail.com>
+ Copyright (c) 2015, SIL International
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ 3. Neither the name of the copyright holder nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+*/
+#include <cassert>
+
+#include "inc/Decompressor.h"
+#include "inc/Shrinker.h"
+
+using namespace shrinker;
+
+namespace {
+
+u8 const LONG_DIST = 0x10;
+u8 const MATCH_LEN = 0x0f;
+
+template <int M>
+inline
+u32 read_literal(u8 const * &s, u8 const * const e, u32 l) {
+ if (unlikely(l == M))
+ {
+ u8 b = 0;
+ do { l += b = *s++; } while(b==0xff && s != e);
+ }
+ return l;
+}
+
+bool read_directive(u8 const * &src, u8 const * const end, u32 & literal_len, u32 & match_len, u32 & match_dist)
+{
+ u8 const flag = *src++;
+
+ literal_len = read_literal<7>(src, end, flag >> 5);
+ match_len = read_literal<15>(src, end, flag & MATCH_LEN);
+
+ match_dist = *src++;
+ if (flag & LONG_DIST)
+ match_dist |= ((*src++) << 8);
+
+ return match_dist != 0xffff;
+}
+
+}
+
+int shrinker::decompress(void const *in, size_t in_size, void *out, size_t out_size)
+{
+ u8 const * src = static_cast<u8 const *>(in),
+ * const src_end = src + in_size;
+
+ u8 * dst = static_cast<u8*>(out),
+ * const dst_end = dst + out_size;
+
+ u32 literal_len = 0,
+ match_len = 0,
+ match_dist = 0;
+
+ while (read_directive(src, src_end, literal_len, match_len, match_dist))
+ {
+ // Copy in literal
+ if (unlikely(dst + literal_len + sizeof(unsigned long) > dst_end)) return -1;
+ dst = memcpy_nooverlap(dst, src, literal_len);
+ src += literal_len;
+
+ // Copy, possibly repeating, match from earlier in the
+ // decoded output.
+ u8 const * const pcpy = dst - match_dist - 1;
+ if (unlikely(pcpy < static_cast<u8*>(out)
+ || dst + match_len + MINMATCH + sizeof(unsigned long) > dst_end)) return -1;
+ dst = memcpy_(dst, pcpy, match_len + MINMATCH);
+ }
+
+ if (unlikely(dst + literal_len > dst_end)) return -1;
+ dst = memcpy_nooverlap_surpass(dst, src, literal_len);
+
+ return dst - (u8*)out;
+}
+