libdeflate 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.gitmodules +3 -0
  4. data/.rspec +2 -0
  5. data/.rubocop.yml +1 -0
  6. data/.rubocop_todo.yml +9 -0
  7. data/.travis.yml +5 -0
  8. data/Gemfile +4 -0
  9. data/LICENSE.txt +21 -0
  10. data/README.md +52 -0
  11. data/Rakefile +15 -0
  12. data/bin/console +14 -0
  13. data/bin/setup +8 -0
  14. data/ext/libdeflate/extconf.rb +14 -0
  15. data/ext/libdeflate/libdeflate/.gitignore +19 -0
  16. data/ext/libdeflate/libdeflate/COPYING +21 -0
  17. data/ext/libdeflate/libdeflate/Makefile +231 -0
  18. data/ext/libdeflate/libdeflate/Makefile.msc +64 -0
  19. data/ext/libdeflate/libdeflate/NEWS +57 -0
  20. data/ext/libdeflate/libdeflate/README.md +170 -0
  21. data/ext/libdeflate/libdeflate/common/common_defs.h +351 -0
  22. data/ext/libdeflate/libdeflate/common/compiler_gcc.h +134 -0
  23. data/ext/libdeflate/libdeflate/common/compiler_msc.h +95 -0
  24. data/ext/libdeflate/libdeflate/lib/adler32.c +213 -0
  25. data/ext/libdeflate/libdeflate/lib/adler32_impl.h +281 -0
  26. data/ext/libdeflate/libdeflate/lib/aligned_malloc.c +57 -0
  27. data/ext/libdeflate/libdeflate/lib/aligned_malloc.h +13 -0
  28. data/ext/libdeflate/libdeflate/lib/bt_matchfinder.h +357 -0
  29. data/ext/libdeflate/libdeflate/lib/crc32.c +368 -0
  30. data/ext/libdeflate/libdeflate/lib/crc32_impl.h +286 -0
  31. data/ext/libdeflate/libdeflate/lib/crc32_table.h +526 -0
  32. data/ext/libdeflate/libdeflate/lib/decompress_impl.h +404 -0
  33. data/ext/libdeflate/libdeflate/lib/deflate_compress.c +2817 -0
  34. data/ext/libdeflate/libdeflate/lib/deflate_compress.h +14 -0
  35. data/ext/libdeflate/libdeflate/lib/deflate_constants.h +66 -0
  36. data/ext/libdeflate/libdeflate/lib/deflate_decompress.c +889 -0
  37. data/ext/libdeflate/libdeflate/lib/gzip_compress.c +95 -0
  38. data/ext/libdeflate/libdeflate/lib/gzip_constants.h +45 -0
  39. data/ext/libdeflate/libdeflate/lib/gzip_decompress.c +130 -0
  40. data/ext/libdeflate/libdeflate/lib/hc_matchfinder.h +405 -0
  41. data/ext/libdeflate/libdeflate/lib/lib_common.h +35 -0
  42. data/ext/libdeflate/libdeflate/lib/matchfinder_avx2.h +53 -0
  43. data/ext/libdeflate/libdeflate/lib/matchfinder_common.h +205 -0
  44. data/ext/libdeflate/libdeflate/lib/matchfinder_neon.h +61 -0
  45. data/ext/libdeflate/libdeflate/lib/matchfinder_sse2.h +53 -0
  46. data/ext/libdeflate/libdeflate/lib/unaligned.h +202 -0
  47. data/ext/libdeflate/libdeflate/lib/x86_cpu_features.c +169 -0
  48. data/ext/libdeflate/libdeflate/lib/x86_cpu_features.h +48 -0
  49. data/ext/libdeflate/libdeflate/lib/zlib_compress.c +87 -0
  50. data/ext/libdeflate/libdeflate/lib/zlib_constants.h +21 -0
  51. data/ext/libdeflate/libdeflate/lib/zlib_decompress.c +91 -0
  52. data/ext/libdeflate/libdeflate/libdeflate.h +274 -0
  53. data/ext/libdeflate/libdeflate/programs/benchmark.c +558 -0
  54. data/ext/libdeflate/libdeflate/programs/checksum.c +197 -0
  55. data/ext/libdeflate/libdeflate/programs/detect.sh +62 -0
  56. data/ext/libdeflate/libdeflate/programs/gzip.c +603 -0
  57. data/ext/libdeflate/libdeflate/programs/prog_util.c +530 -0
  58. data/ext/libdeflate/libdeflate/programs/prog_util.h +162 -0
  59. data/ext/libdeflate/libdeflate/programs/test_checksums.c +135 -0
  60. data/ext/libdeflate/libdeflate/programs/tgetopt.c +118 -0
  61. data/ext/libdeflate/libdeflate/tools/afl-fuzz/Makefile +12 -0
  62. data/ext/libdeflate/libdeflate/tools/afl-fuzz/deflate_compress/fuzz.c +40 -0
  63. data/ext/libdeflate/libdeflate/tools/afl-fuzz/deflate_compress/inputs/0 +0 -0
  64. data/ext/libdeflate/libdeflate/tools/afl-fuzz/deflate_decompress/fuzz.c +28 -0
  65. data/ext/libdeflate/libdeflate/tools/afl-fuzz/deflate_decompress/inputs/0 +3 -0
  66. data/ext/libdeflate/libdeflate/tools/afl-fuzz/gzip_decompress/fuzz.c +28 -0
  67. data/ext/libdeflate/libdeflate/tools/afl-fuzz/gzip_decompress/inputs/0 +0 -0
  68. data/ext/libdeflate/libdeflate/tools/afl-fuzz/prepare_for_fuzz.sh +14 -0
  69. data/ext/libdeflate/libdeflate/tools/afl-fuzz/zlib_decompress/fuzz.c +28 -0
  70. data/ext/libdeflate/libdeflate/tools/afl-fuzz/zlib_decompress/inputs/0 +3 -0
  71. data/ext/libdeflate/libdeflate/tools/android_build.sh +104 -0
  72. data/ext/libdeflate/libdeflate/tools/checksum_benchmarks.sh +76 -0
  73. data/ext/libdeflate/libdeflate/tools/exec_tests.sh +30 -0
  74. data/ext/libdeflate/libdeflate/tools/gen_crc32_multipliers.c +108 -0
  75. data/ext/libdeflate/libdeflate/tools/gen_crc32_table.c +100 -0
  76. data/ext/libdeflate/libdeflate/tools/gzip_tests.sh +412 -0
  77. data/ext/libdeflate/libdeflate/tools/make-windows-releases +21 -0
  78. data/ext/libdeflate/libdeflate/tools/mips_build.sh +9 -0
  79. data/ext/libdeflate/libdeflate/tools/msc_test.bat +3 -0
  80. data/ext/libdeflate/libdeflate/tools/pgo_build.sh +23 -0
  81. data/ext/libdeflate/libdeflate/tools/produce_gzip_benchmark_table.sh +37 -0
  82. data/ext/libdeflate/libdeflate/tools/run_tests.sh +305 -0
  83. data/ext/libdeflate/libdeflate/tools/windows_build.sh +10 -0
  84. data/ext/libdeflate/libdeflate_ext.c +389 -0
  85. data/ext/libdeflate/libdeflate_ext.h +8 -0
  86. data/lib/libdeflate.rb +2 -0
  87. data/lib/libdeflate/version.rb +3 -0
  88. data/libdeflate.gemspec +33 -0
  89. metadata +230 -0
@@ -0,0 +1,169 @@
1
+ /*
2
+ * x86_cpu_features.c - feature detection for x86 processors
3
+ *
4
+ * Originally public domain; changes after 2016-09-07 are copyrighted.
5
+ *
6
+ * Copyright 2016 Eric Biggers
7
+ *
8
+ * Permission is hereby granted, free of charge, to any person
9
+ * obtaining a copy of this software and associated documentation
10
+ * files (the "Software"), to deal in the Software without
11
+ * restriction, including without limitation the rights to use,
12
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
13
+ * copies of the Software, and to permit persons to whom the
14
+ * Software is furnished to do so, subject to the following
15
+ * conditions:
16
+ *
17
+ * The above copyright notice and this permission notice shall be
18
+ * included in all copies or substantial portions of the Software.
19
+ *
20
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
22
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
24
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
25
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27
+ * OTHER DEALINGS IN THE SOFTWARE.
28
+ */
29
+
30
+ #include "x86_cpu_features.h"
31
+
32
+ #if X86_CPU_FEATURES_ENABLED
33
+
34
+ #define DEBUG 0
35
+
36
+ #if DEBUG
37
+ # include <stdio.h>
38
+ #endif
39
+
40
+ u32 _x86_cpu_features = 0;
41
+
42
+ /* With old GCC versions we have to manually save and restore the x86_32 PIC
43
+ * register (ebx). See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47602 */
44
+ #if defined(__i386__) && defined(__PIC__)
45
+ # define EBX_CONSTRAINT "=r"
46
+ #else
47
+ # define EBX_CONSTRAINT "=b"
48
+ #endif
49
+
50
+ /* Execute the CPUID instruction. */
51
+ static inline void
52
+ cpuid(u32 leaf, u32 subleaf, u32 *a, u32 *b, u32 *c, u32 *d)
53
+ {
54
+ __asm__(".ifnc %%ebx, %1; mov %%ebx, %1; .endif\n"
55
+ "cpuid \n"
56
+ ".ifnc %%ebx, %1; xchg %%ebx, %1; .endif\n"
57
+ : "=a" (*a), EBX_CONSTRAINT (*b), "=c" (*c), "=d" (*d)
58
+ : "a" (leaf), "c" (subleaf));
59
+ }
60
+
61
+ /* Read an extended control register. */
62
+ static inline u64
63
+ read_xcr(u32 index)
64
+ {
65
+ u32 edx, eax;
66
+
67
+ /* Execute the "xgetbv" instruction. Old versions of binutils do not
68
+ * recognize this instruction, so list the raw bytes instead. */
69
+ __asm__ (".byte 0x0f, 0x01, 0xd0" : "=d" (edx), "=a" (eax) : "c" (index));
70
+
71
+ return ((u64)edx << 32) | eax;
72
+ }
73
+
74
+ #define IS_SET(reg, bit) ((reg) & ((u32)1 << (bit)))
75
+
76
+ /* Initialize _x86_cpu_features with bits for interesting processor features. */
77
+ void
78
+ x86_setup_cpu_features(void)
79
+ {
80
+ u32 features = 0;
81
+ u32 dummy1, dummy2, dummy3, dummy4;
82
+ u32 max_function;
83
+ u32 features_1, features_2, features_3, features_4;
84
+ bool os_saves_ymm_regs = false;
85
+
86
+ /* Get maximum supported function */
87
+ cpuid(0, 0, &max_function, &dummy2, &dummy3, &dummy4);
88
+ if (max_function < 1)
89
+ goto out;
90
+
91
+ /* Standard feature flags */
92
+ cpuid(1, 0, &dummy1, &dummy2, &features_2, &features_1);
93
+
94
+ if (IS_SET(features_1, 25))
95
+ features |= X86_CPU_FEATURE_SSE;
96
+
97
+ if (IS_SET(features_1, 26))
98
+ features |= X86_CPU_FEATURE_SSE2;
99
+
100
+ if (IS_SET(features_2, 0))
101
+ features |= X86_CPU_FEATURE_SSE3;
102
+
103
+ if (IS_SET(features_2, 1))
104
+ features |= X86_CPU_FEATURE_PCLMULQDQ;
105
+
106
+ if (IS_SET(features_2, 9))
107
+ features |= X86_CPU_FEATURE_SSSE3;
108
+
109
+ if (IS_SET(features_2, 19))
110
+ features |= X86_CPU_FEATURE_SSE4_1;
111
+
112
+ if (IS_SET(features_2, 20))
113
+ features |= X86_CPU_FEATURE_SSE4_2;
114
+
115
+ if (IS_SET(features_2, 27)) /* OSXSAVE set? */
116
+ if ((read_xcr(0) & 0x6) == 0x6)
117
+ os_saves_ymm_regs = true;
118
+
119
+ if (os_saves_ymm_regs && IS_SET(features_2, 28))
120
+ features |= X86_CPU_FEATURE_AVX;
121
+
122
+ if (max_function < 7)
123
+ goto out;
124
+
125
+ /* Extended feature flags */
126
+ cpuid(7, 0, &dummy1, &features_3, &features_4, &dummy4);
127
+
128
+ if (IS_SET(features_3, 3))
129
+ features |= X86_CPU_FEATURE_BMI;
130
+
131
+ if (os_saves_ymm_regs && IS_SET(features_3, 5))
132
+ features |= X86_CPU_FEATURE_AVX2;
133
+
134
+ if (IS_SET(features_3, 8))
135
+ features |= X86_CPU_FEATURE_BMI2;
136
+
137
+ out:
138
+
139
+ #if DEBUG
140
+ printf("Detected x86 CPU features: ");
141
+ if (features & X86_CPU_FEATURE_SSE)
142
+ printf("SSE ");
143
+ if (features & X86_CPU_FEATURE_SSE2)
144
+ printf("SSE2 ");
145
+ if (features & X86_CPU_FEATURE_SSE3)
146
+ printf("SSE3 ");
147
+ if (features & X86_CPU_FEATURE_PCLMULQDQ)
148
+ printf("PCLMULQDQ ");
149
+ if (features & X86_CPU_FEATURE_SSSE3)
150
+ printf("SSSE3 ");
151
+ if (features & X86_CPU_FEATURE_SSE4_1)
152
+ printf("SSE4.1 ");
153
+ if (features & X86_CPU_FEATURE_SSE4_2)
154
+ printf("SSE4.2 ");
155
+ if (features & X86_CPU_FEATURE_BMI)
156
+ printf("BMI ");
157
+ if (features & X86_CPU_FEATURE_AVX)
158
+ printf("AVX ");
159
+ if (features & X86_CPU_FEATURE_BMI2)
160
+ printf("BMI2 ");
161
+ if (features & X86_CPU_FEATURE_AVX2)
162
+ printf("AVX2 ");
163
+ printf("\n");
164
+ #endif /* DEBUG */
165
+
166
+ _x86_cpu_features = features | X86_CPU_FEATURES_KNOWN;
167
+ }
168
+
169
+ #endif /* X86_CPU_FEATURES_ENABLED */
@@ -0,0 +1,48 @@
1
+ /*
2
+ * x86_cpu_features.h - feature detection for x86 processors
3
+ */
4
+
5
+ #ifndef LIB_X86_CPU_FEATURES_H
6
+ #define LIB_X86_CPU_FEATURES_H
7
+
8
+ #include "lib_common.h"
9
+
10
+ #if defined(__x86_64__) && COMPILER_SUPPORTS_TARGET_FUNCTION_ATTRIBUTE
11
+ # define X86_CPU_FEATURES_ENABLED 1
12
+ #else
13
+ # define X86_CPU_FEATURES_ENABLED 0
14
+ #endif
15
+
16
+ #if X86_CPU_FEATURES_ENABLED
17
+
18
+ #define X86_CPU_FEATURE_SSE 0x00000001
19
+ #define X86_CPU_FEATURE_SSE2 0x00000002
20
+ #define X86_CPU_FEATURE_SSE3 0x00000004
21
+ #define X86_CPU_FEATURE_PCLMULQDQ 0x00000008
22
+ #define X86_CPU_FEATURE_SSSE3 0x00000010
23
+ #define X86_CPU_FEATURE_SSE4_1 0x00000020
24
+ #define X86_CPU_FEATURE_SSE4_2 0x00000040
25
+ #define X86_CPU_FEATURE_AVX 0x00000080
26
+ #define X86_CPU_FEATURE_BMI 0x00000100
27
+ #define X86_CPU_FEATURE_AVX2 0x00000200
28
+ #define X86_CPU_FEATURE_BMI2 0x00000400
29
+
30
+ #define X86_CPU_FEATURES_KNOWN 0x80000000
31
+
32
+ extern u32 _x86_cpu_features;
33
+
34
+ extern void
35
+ x86_setup_cpu_features(void);
36
+
37
+ /* Does the processor have the specified feature(s)? */
38
+ static inline bool
39
+ x86_have_cpu_features(u32 features)
40
+ {
41
+ if (_x86_cpu_features == 0)
42
+ x86_setup_cpu_features();
43
+ return (_x86_cpu_features & features) == features;
44
+ }
45
+
46
+ #endif /* X86_CPU_FEATURES_ENABLED */
47
+
48
+ #endif /* LIB_X86_CPU_FEATURES_H */
@@ -0,0 +1,87 @@
1
+ /*
2
+ * zlib_compress.c - compress with a zlib wrapper
3
+ *
4
+ * Originally public domain; changes after 2016-09-07 are copyrighted.
5
+ *
6
+ * Copyright 2016 Eric Biggers
7
+ *
8
+ * Permission is hereby granted, free of charge, to any person
9
+ * obtaining a copy of this software and associated documentation
10
+ * files (the "Software"), to deal in the Software without
11
+ * restriction, including without limitation the rights to use,
12
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
13
+ * copies of the Software, and to permit persons to whom the
14
+ * Software is furnished to do so, subject to the following
15
+ * conditions:
16
+ *
17
+ * The above copyright notice and this permission notice shall be
18
+ * included in all copies or substantial portions of the Software.
19
+ *
20
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
22
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
24
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
25
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27
+ * OTHER DEALINGS IN THE SOFTWARE.
28
+ */
29
+
30
+ #include "deflate_compress.h"
31
+ #include "unaligned.h"
32
+ #include "zlib_constants.h"
33
+
34
+ #include "libdeflate.h"
35
+
36
+ LIBDEFLATEAPI size_t
37
+ libdeflate_zlib_compress(struct libdeflate_compressor *c,
38
+ const void *in, size_t in_size,
39
+ void *out, size_t out_nbytes_avail)
40
+ {
41
+ u8 *out_next = out;
42
+ u16 hdr;
43
+ unsigned compression_level;
44
+ unsigned level_hint;
45
+ size_t deflate_size;
46
+
47
+ if (out_nbytes_avail <= ZLIB_MIN_OVERHEAD)
48
+ return 0;
49
+
50
+ /* 2 byte header: CMF and FLG */
51
+ hdr = (ZLIB_CM_DEFLATE << 8) | (ZLIB_CINFO_32K_WINDOW << 12);
52
+ compression_level = deflate_get_compression_level(c);
53
+ if (compression_level < 2)
54
+ level_hint = ZLIB_FASTEST_COMPRESSION;
55
+ else if (compression_level < 6)
56
+ level_hint = ZLIB_FAST_COMPRESSION;
57
+ else if (compression_level < 8)
58
+ level_hint = ZLIB_DEFAULT_COMPRESSION;
59
+ else
60
+ level_hint = ZLIB_SLOWEST_COMPRESSION;
61
+ hdr |= level_hint << 6;
62
+ hdr |= 31 - (hdr % 31);
63
+
64
+ put_unaligned_be16(hdr, out_next);
65
+ out_next += 2;
66
+
67
+ /* Compressed data */
68
+ deflate_size = libdeflate_deflate_compress(c, in, in_size, out_next,
69
+ out_nbytes_avail - ZLIB_MIN_OVERHEAD);
70
+ if (deflate_size == 0)
71
+ return 0;
72
+ out_next += deflate_size;
73
+
74
+ /* ADLER32 */
75
+ put_unaligned_be32(libdeflate_adler32(1, in, in_size), out_next);
76
+ out_next += 4;
77
+
78
+ return out_next - (u8 *)out;
79
+ }
80
+
81
+ LIBDEFLATEAPI size_t
82
+ libdeflate_zlib_compress_bound(struct libdeflate_compressor *c,
83
+ size_t in_nbytes)
84
+ {
85
+ return ZLIB_MIN_OVERHEAD +
86
+ libdeflate_deflate_compress_bound(c, in_nbytes);
87
+ }
@@ -0,0 +1,21 @@
1
+ /*
2
+ * zlib_constants.h - constants for the zlib wrapper format
3
+ */
4
+
5
+ #ifndef LIB_ZLIB_CONSTANTS_H
6
+ #define LIB_ZLIB_CONSTANTS_H
7
+
8
+ #define ZLIB_MIN_HEADER_SIZE 2
9
+ #define ZLIB_FOOTER_SIZE 4
10
+ #define ZLIB_MIN_OVERHEAD (ZLIB_MIN_HEADER_SIZE + ZLIB_FOOTER_SIZE)
11
+
12
+ #define ZLIB_CM_DEFLATE 8
13
+
14
+ #define ZLIB_CINFO_32K_WINDOW 7
15
+
16
+ #define ZLIB_FASTEST_COMPRESSION 0
17
+ #define ZLIB_FAST_COMPRESSION 1
18
+ #define ZLIB_DEFAULT_COMPRESSION 2
19
+ #define ZLIB_SLOWEST_COMPRESSION 3
20
+
21
+ #endif /* LIB_ZLIB_CONSTANTS_H */
@@ -0,0 +1,91 @@
1
+ /*
2
+ * zlib_decompress.c - decompress with a zlib wrapper
3
+ *
4
+ * Originally public domain; changes after 2016-09-07 are copyrighted.
5
+ *
6
+ * Copyright 2016 Eric Biggers
7
+ *
8
+ * Permission is hereby granted, free of charge, to any person
9
+ * obtaining a copy of this software and associated documentation
10
+ * files (the "Software"), to deal in the Software without
11
+ * restriction, including without limitation the rights to use,
12
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
13
+ * copies of the Software, and to permit persons to whom the
14
+ * Software is furnished to do so, subject to the following
15
+ * conditions:
16
+ *
17
+ * The above copyright notice and this permission notice shall be
18
+ * included in all copies or substantial portions of the Software.
19
+ *
20
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
22
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
24
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
25
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27
+ * OTHER DEALINGS IN THE SOFTWARE.
28
+ */
29
+
30
+ #include "unaligned.h"
31
+ #include "zlib_constants.h"
32
+
33
+ #include "libdeflate.h"
34
+
35
+ LIBDEFLATEAPI enum libdeflate_result
36
+ libdeflate_zlib_decompress(struct libdeflate_decompressor *d,
37
+ const void *in, size_t in_nbytes,
38
+ void *out, size_t out_nbytes_avail,
39
+ size_t *actual_out_nbytes_ret)
40
+ {
41
+ const u8 *in_next = in;
42
+ const u8 * const in_end = in_next + in_nbytes;
43
+ u16 hdr;
44
+ size_t actual_out_nbytes;
45
+ enum libdeflate_result result;
46
+
47
+ if (in_nbytes < ZLIB_MIN_OVERHEAD)
48
+ return LIBDEFLATE_BAD_DATA;
49
+
50
+ /* 2 byte header: CMF and FLG */
51
+ hdr = get_unaligned_be16(in_next);
52
+ in_next += 2;
53
+
54
+ /* FCHECK */
55
+ if ((hdr % 31) != 0)
56
+ return LIBDEFLATE_BAD_DATA;
57
+
58
+ /* CM */
59
+ if (((hdr >> 8) & 0xF) != ZLIB_CM_DEFLATE)
60
+ return LIBDEFLATE_BAD_DATA;
61
+
62
+ /* CINFO */
63
+ if ((hdr >> 12) > ZLIB_CINFO_32K_WINDOW)
64
+ return LIBDEFLATE_BAD_DATA;
65
+
66
+ /* FDICT */
67
+ if ((hdr >> 5) & 1)
68
+ return LIBDEFLATE_BAD_DATA;
69
+
70
+ /* Compressed data */
71
+ result = libdeflate_deflate_decompress(d, in_next,
72
+ in_end - ZLIB_FOOTER_SIZE - in_next,
73
+ out, out_nbytes_avail,
74
+ actual_out_nbytes_ret);
75
+ if (result != LIBDEFLATE_SUCCESS)
76
+ return result;
77
+
78
+ if (actual_out_nbytes_ret)
79
+ actual_out_nbytes = *actual_out_nbytes_ret;
80
+ else
81
+ actual_out_nbytes = out_nbytes_avail;
82
+
83
+ in_next = in_end - ZLIB_FOOTER_SIZE;
84
+
85
+ /* ADLER32 */
86
+ if (libdeflate_adler32(1, out, actual_out_nbytes) !=
87
+ get_unaligned_be32(in_next))
88
+ return LIBDEFLATE_BAD_DATA;
89
+
90
+ return LIBDEFLATE_SUCCESS;
91
+ }
@@ -0,0 +1,274 @@
1
+ /*
2
+ * libdeflate.h - public header for libdeflate
3
+ */
4
+
5
+ #ifndef LIBDEFLATE_H
6
+ #define LIBDEFLATE_H
7
+
8
+ #ifdef __cplusplus
9
+ extern "C" {
10
+ #endif
11
+
12
+ #define LIBDEFLATE_VERSION_MAJOR 0
13
+ #define LIBDEFLATE_VERSION_MINOR 7
14
+ #define LIBDEFLATE_VERSION_STRING "0.7"
15
+
16
+ #include <stddef.h>
17
+ #include <stdint.h>
18
+
19
+ /*
20
+ * On Windows, if you want to link to the DLL version of libdeflate, then
21
+ * #define LIBDEFLATE_DLL.
22
+ */
23
+ #ifdef LIBDEFLATE_DLL
24
+ # ifdef BUILDING_LIBDEFLATE
25
+ # define LIBDEFLATEAPI LIBEXPORT
26
+ # elif defined(_WIN32) || defined(__CYGWIN__)
27
+ # define LIBDEFLATEAPI __declspec(dllimport)
28
+ # endif
29
+ #endif
30
+ #ifndef LIBDEFLATEAPI
31
+ # define LIBDEFLATEAPI
32
+ #endif
33
+
34
+ /* ========================================================================== */
35
+ /* Compression */
36
+ /* ========================================================================== */
37
+
38
+ struct libdeflate_compressor;
39
+
40
+ /*
41
+ * libdeflate_alloc_compressor() allocates a new compressor that supports
42
+ * DEFLATE, zlib, and gzip compression. 'compression_level' is the compression
43
+ * level on a zlib-like scale but with a higher maximum value (1 = fastest, 6 =
44
+ * medium/default, 9 = slow, 12 = slowest). The return value is a pointer to
45
+ * the new compressor, or NULL if out of memory.
46
+ *
47
+ * Note: for compression, the sliding window size is defined at compilation time
48
+ * to 32768, the largest size permissible in the DEFLATE format. It cannot be
49
+ * changed at runtime.
50
+ *
51
+ * A single compressor is not safe to use by multiple threads concurrently.
52
+ * However, different threads may use different compressors concurrently.
53
+ */
54
+ LIBDEFLATEAPI struct libdeflate_compressor *
55
+ libdeflate_alloc_compressor(int compression_level);
56
+
57
+ /*
58
+ * libdeflate_deflate_compress() performs raw DEFLATE compression on a buffer of
59
+ * data. The function attempts to compress 'in_nbytes' bytes of data located at
60
+ * 'in' and write the results to 'out', which has space for 'out_nbytes_avail'
61
+ * bytes. The return value is the compressed size in bytes, or 0 if the data
62
+ * could not be compressed to 'out_nbytes_avail' bytes or fewer.
63
+ */
64
+ LIBDEFLATEAPI size_t
65
+ libdeflate_deflate_compress(struct libdeflate_compressor *compressor,
66
+ const void *in, size_t in_nbytes,
67
+ void *out, size_t out_nbytes_avail);
68
+
69
+ /*
70
+ * libdeflate_deflate_compress_bound() returns a worst-case upper bound on the
71
+ * number of bytes of compressed data that may be produced by compressing any
72
+ * buffer of length less than or equal to 'in_nbytes' using
73
+ * libdeflate_deflate_compress() with the specified compressor. Mathematically,
74
+ * this bound will necessarily be a number greater than or equal to 'in_nbytes'.
75
+ * It may be an overestimate of the true upper bound. The return value is
76
+ * guaranteed to be the same for all invocations with the same compressor and
77
+ * same 'in_nbytes'.
78
+ *
79
+ * As a special case, 'compressor' may be NULL. This causes the bound to be
80
+ * taken across *any* libdeflate_compressor that could ever be allocated with
81
+ * this build of the library, with any options.
82
+ *
83
+ * Note that this function is not necessary in many applications. With
84
+ * block-based compression, it is usually preferable to separately store the
85
+ * uncompressed size of each block and to store any blocks that did not compress
86
+ * to less than their original size uncompressed. In that scenario, there is no
87
+ * need to know the worst-case compressed size, since the maximum number of
88
+ * bytes of compressed data that may be used would always be one less than the
89
+ * input length. You can just pass a buffer of that size to
90
+ * libdeflate_deflate_compress() and store the data uncompressed if
91
+ * libdeflate_deflate_compress() returns 0, indicating that the compressed data
92
+ * did not fit into the provided output buffer.
93
+ */
94
+ LIBDEFLATEAPI size_t
95
+ libdeflate_deflate_compress_bound(struct libdeflate_compressor *compressor,
96
+ size_t in_nbytes);
97
+
98
+ /*
99
+ * Like libdeflate_deflate_compress(), but stores the data in the zlib wrapper
100
+ * format.
101
+ */
102
+ LIBDEFLATEAPI size_t
103
+ libdeflate_zlib_compress(struct libdeflate_compressor *compressor,
104
+ const void *in, size_t in_nbytes,
105
+ void *out, size_t out_nbytes_avail);
106
+
107
+ /*
108
+ * Like libdeflate_deflate_compress_bound(), but assumes the data will be
109
+ * compressed with libdeflate_zlib_compress() rather than with
110
+ * libdeflate_deflate_compress().
111
+ */
112
+ LIBDEFLATEAPI size_t
113
+ libdeflate_zlib_compress_bound(struct libdeflate_compressor *compressor,
114
+ size_t in_nbytes);
115
+
116
+ /*
117
+ * Like libdeflate_deflate_compress(), but stores the data in the gzip wrapper
118
+ * format.
119
+ */
120
+ LIBDEFLATEAPI size_t
121
+ libdeflate_gzip_compress(struct libdeflate_compressor *compressor,
122
+ const void *in, size_t in_nbytes,
123
+ void *out, size_t out_nbytes_avail);
124
+
125
+ /*
126
+ * Like libdeflate_deflate_compress_bound(), but assumes the data will be
127
+ * compressed with libdeflate_gzip_compress() rather than with
128
+ * libdeflate_deflate_compress().
129
+ */
130
+ LIBDEFLATEAPI size_t
131
+ libdeflate_gzip_compress_bound(struct libdeflate_compressor *compressor,
132
+ size_t in_nbytes);
133
+
134
+ /*
135
+ * libdeflate_free_compressor() frees a compressor that was allocated with
136
+ * libdeflate_alloc_compressor(). If a NULL pointer is passed in, no action is
137
+ * taken.
138
+ */
139
+ LIBDEFLATEAPI void
140
+ libdeflate_free_compressor(struct libdeflate_compressor *compressor);
141
+
142
+ /* ========================================================================== */
143
+ /* Decompression */
144
+ /* ========================================================================== */
145
+
146
+ struct libdeflate_decompressor;
147
+
148
+ /*
149
+ * libdeflate_alloc_decompressor() allocates a new decompressor that can be used
150
+ * for DEFLATE, zlib, and gzip decompression. The return value is a pointer to
151
+ * the new decompressor, or NULL if out of memory.
152
+ *
153
+ * This function takes no parameters, and the returned decompressor is valid for
154
+ * decompressing data that was compressed at any compression level and with any
155
+ * sliding window size.
156
+ *
157
+ * A single decompressor is not safe to use by multiple threads concurrently.
158
+ * However, different threads may use different decompressors concurrently.
159
+ */
160
+ LIBDEFLATEAPI struct libdeflate_decompressor *
161
+ libdeflate_alloc_decompressor(void);
162
+
163
+ /*
164
+ * Result of a call to libdeflate_deflate_decompress(),
165
+ * libdeflate_zlib_decompress(), or libdeflate_gzip_decompress().
166
+ */
167
+ enum libdeflate_result {
168
+ /* Decompression was successful. */
169
+ LIBDEFLATE_SUCCESS = 0,
170
+
171
+ /* Decompressed failed because the compressed data was invalid, corrupt,
172
+ * or otherwise unsupported. */
173
+ LIBDEFLATE_BAD_DATA = 1,
174
+
175
+ /* A NULL 'actual_out_nbytes_ret' was provided, but the data would have
176
+ * decompressed to fewer than 'out_nbytes_avail' bytes. */
177
+ LIBDEFLATE_SHORT_OUTPUT = 2,
178
+
179
+ /* The data would have decompressed to more than 'out_nbytes_avail'
180
+ * bytes. */
181
+ LIBDEFLATE_INSUFFICIENT_SPACE = 3,
182
+ };
183
+
184
+ /*
185
+ * libdeflate_deflate_decompress() decompresses 'in_nbytes' bytes of
186
+ * raw DEFLATE-compressed data at 'in' and writes the uncompressed data to
187
+ * 'out', which is a buffer of at least 'out_nbytes_avail' bytes. If
188
+ * decompression was successful, then 0 (LIBDEFLATE_SUCCESS) is returned;
189
+ * otherwise, a nonzero result code such as LIBDEFLATE_BAD_DATA is returned. If
190
+ * a nonzero result code is returned, then the contents of the output buffer are
191
+ * undefined.
192
+ *
193
+ * libdeflate_deflate_decompress() can be used in cases where the actual
194
+ * uncompressed size is known (recommended) or unknown (not recommended):
195
+ *
196
+ * - If the actual uncompressed size is known, then pass the actual
197
+ * uncompressed size as 'out_nbytes_avail' and pass NULL for
198
+ * 'actual_out_nbytes_ret'. This makes libdeflate_deflate_decompress() fail
199
+ * with LIBDEFLATE_SHORT_OUTPUT if the data decompressed to fewer than the
200
+ * specified number of bytes.
201
+ *
202
+ * - If the actual uncompressed size is unknown, then provide a non-NULL
203
+ * 'actual_out_nbytes_ret' and provide a buffer with some size
204
+ * 'out_nbytes_avail' that you think is large enough to hold all the
205
+ * uncompressed data. In this case, if the data decompresses to less than
206
+ * or equal to 'out_nbytes_avail' bytes, then
207
+ * libdeflate_deflate_decompress() will write the actual uncompressed size
208
+ * to *actual_out_nbytes_ret and return 0 (LIBDEFLATE_SUCCESS). Otherwise,
209
+ * it will return LIBDEFLATE_INSUFFICIENT_SPACE if the provided buffer was
210
+ * not large enough but no other problems were encountered, or another
211
+ * nonzero result code if decompression failed for another reason.
212
+ */
213
+ LIBDEFLATEAPI enum libdeflate_result
214
+ libdeflate_deflate_decompress(struct libdeflate_decompressor *decompressor,
215
+ const void *in, size_t in_nbytes,
216
+ void *out, size_t out_nbytes_avail,
217
+ size_t *actual_out_nbytes_ret);
218
+
219
+ /*
220
+ * Like libdeflate_deflate_decompress(), but assumes the zlib wrapper format
221
+ * instead of raw DEFLATE.
222
+ */
223
+ LIBDEFLATEAPI enum libdeflate_result
224
+ libdeflate_zlib_decompress(struct libdeflate_decompressor *decompressor,
225
+ const void *in, size_t in_nbytes,
226
+ void *out, size_t out_nbytes_avail,
227
+ size_t *actual_out_nbytes_ret);
228
+
229
+ /*
230
+ * Like libdeflate_deflate_decompress(), but assumes the gzip wrapper format
231
+ * instead of raw DEFLATE.
232
+ */
233
+ LIBDEFLATEAPI enum libdeflate_result
234
+ libdeflate_gzip_decompress(struct libdeflate_decompressor *decompressor,
235
+ const void *in, size_t in_nbytes,
236
+ void *out, size_t out_nbytes_avail,
237
+ size_t *actual_out_nbytes_ret);
238
+
239
+ /*
240
+ * libdeflate_free_decompressor() frees a decompressor that was allocated with
241
+ * libdeflate_alloc_decompressor(). If a NULL pointer is passed in, no action
242
+ * is taken.
243
+ */
244
+ LIBDEFLATEAPI void
245
+ libdeflate_free_decompressor(struct libdeflate_decompressor *decompressor);
246
+
247
+ /* ========================================================================== */
248
+ /* Checksums */
249
+ /* ========================================================================== */
250
+
251
+ /*
252
+ * libdeflate_adler32() updates a running Adler-32 checksum with 'len' bytes of
253
+ * data and returns the updated checksum. When starting a new checksum, the
254
+ * required initial value for 'adler' is 1. This value is also returned when
255
+ * 'buffer' is specified as NULL.
256
+ */
257
+ LIBDEFLATEAPI uint32_t
258
+ libdeflate_adler32(uint32_t adler32, const void *buffer, size_t len);
259
+
260
+
261
+ /*
262
+ * libdeflate_crc32() updates a running CRC-32 checksum with 'len' bytes of data
263
+ * and returns the updated checksum. When starting a new checksum, the required
264
+ * initial value for 'crc' is 0. This value is also returned when 'buffer' is
265
+ * specified as NULL.
266
+ */
267
+ LIBDEFLATEAPI uint32_t
268
+ libdeflate_crc32(uint32_t crc, const void *buffer, size_t len);
269
+
270
+ #ifdef __cplusplus
271
+ }
272
+ #endif
273
+
274
+ #endif /* LIBDEFLATE_H */