]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /********************************************************************** |
2 | Copyright(c) 2011-2016 Intel Corporation All rights reserved. | |
3 | ||
4 | Redistribution and use in source and binary forms, with or without | |
5 | modification, are permitted provided that the following conditions | |
6 | are met: | |
7 | * Redistributions of source code must retain the above copyright | |
8 | notice, this list of conditions and the following disclaimer. | |
9 | * Redistributions in binary form must reproduce the above copyright | |
10 | notice, this list of conditions and the following disclaimer in | |
11 | the documentation and/or other materials provided with the | |
12 | distribution. | |
13 | * Neither the name of Intel Corporation nor the names of its | |
14 | contributors may be used to endorse or promote products derived | |
15 | from this software without specific prior written permission. | |
16 | ||
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
28 | **********************************************************************/ | |
29 | ||
30 | #include <stdint.h> | |
31 | #include <stdio.h> | |
32 | #include <zlib.h> | |
224ce89b | 33 | #include "igzip_lib.h" |
7c673cae FG |
34 | #include "huff_codes.h" |
35 | ||
36 | /*Don't use file larger memory can support because compression and decompression | |
37 | * are done in a stateless manner. */ | |
38 | #define MAX_INPUT_FILE_SIZE 2L*1024L*1024L*1024L | |
39 | ||
224ce89b WB |
40 | int inflate_multi_pass(uint8_t * compress_buf, uint64_t compress_len, |
41 | uint8_t * uncompress_buf, uint32_t * uncompress_len) | |
42 | { | |
43 | struct inflate_state *state = NULL; | |
44 | int ret = 0; | |
45 | uint8_t *comp_tmp = NULL, *uncomp_tmp = NULL; | |
46 | uint32_t comp_tmp_size = 0, uncomp_tmp_size = 0; | |
47 | uint32_t comp_processed = 0, uncomp_processed = 0; | |
48 | ||
49 | state = malloc(sizeof(struct inflate_state)); | |
50 | if (state == NULL) { | |
51 | printf("Failed to allocate memory\n"); | |
52 | exit(0); | |
53 | } | |
54 | ||
55 | isal_inflate_init(state); | |
56 | ||
57 | state->next_in = NULL; | |
58 | state->next_out = NULL; | |
59 | state->avail_in = 0; | |
60 | state->avail_out = 0; | |
61 | ||
62 | while (1) { | |
63 | if (state->avail_in == 0) { | |
64 | comp_tmp_size = rand() % (compress_len + 1); | |
65 | ||
66 | if (comp_tmp_size >= compress_len - comp_processed) | |
67 | comp_tmp_size = compress_len - comp_processed; | |
68 | ||
69 | if (comp_tmp_size != 0) { | |
70 | if (comp_tmp != NULL) { | |
71 | free(comp_tmp); | |
72 | comp_tmp = NULL; | |
73 | } | |
74 | ||
75 | comp_tmp = malloc(comp_tmp_size); | |
76 | ||
77 | if (comp_tmp == NULL) { | |
78 | printf("Failed to allocate memory\n"); | |
79 | exit(0); | |
80 | } | |
81 | ||
82 | memcpy(comp_tmp, compress_buf + comp_processed, comp_tmp_size); | |
83 | comp_processed += comp_tmp_size; | |
84 | ||
85 | state->next_in = comp_tmp; | |
86 | state->avail_in = comp_tmp_size; | |
87 | } | |
88 | } | |
89 | ||
90 | if (state->avail_out == 0) { | |
91 | /* Save uncompressed data into uncompress_buf */ | |
92 | if (uncomp_tmp != NULL) { | |
93 | memcpy(uncompress_buf + uncomp_processed, uncomp_tmp, | |
94 | uncomp_tmp_size); | |
95 | uncomp_processed += uncomp_tmp_size; | |
96 | } | |
97 | ||
98 | uncomp_tmp_size = rand() % (*uncompress_len + 1); | |
99 | ||
100 | /* Limit size of buffer to be smaller than maximum */ | |
101 | if (uncomp_tmp_size > *uncompress_len - uncomp_processed) | |
102 | uncomp_tmp_size = *uncompress_len - uncomp_processed; | |
103 | ||
104 | if (uncomp_tmp_size != 0) { | |
105 | ||
106 | if (uncomp_tmp != NULL) { | |
107 | fflush(0); | |
108 | free(uncomp_tmp); | |
109 | uncomp_tmp = NULL; | |
110 | } | |
111 | ||
112 | uncomp_tmp = malloc(uncomp_tmp_size); | |
113 | if (uncomp_tmp == NULL) { | |
114 | printf("Failed to allocate memory\n"); | |
115 | exit(0); | |
116 | } | |
117 | ||
118 | state->avail_out = uncomp_tmp_size; | |
119 | state->next_out = uncomp_tmp; | |
120 | } | |
121 | } | |
122 | ||
123 | ret = isal_inflate(state); | |
124 | ||
125 | if (state->block_state == ISAL_BLOCK_FINISH || ret != 0) { | |
126 | memcpy(uncompress_buf + uncomp_processed, uncomp_tmp, uncomp_tmp_size); | |
127 | *uncompress_len = state->total_out; | |
128 | break; | |
129 | } | |
130 | } | |
131 | ||
132 | if (comp_tmp != NULL) { | |
133 | free(comp_tmp); | |
134 | comp_tmp = NULL; | |
135 | } | |
136 | if (uncomp_tmp != NULL) { | |
137 | free(uncomp_tmp); | |
138 | uncomp_tmp = NULL; | |
139 | } | |
140 | ||
141 | free(state); | |
142 | return ret; | |
143 | } | |
144 | ||
145 | int test(uint8_t * compressed_stream, | |
146 | uint64_t * compressed_length, | |
147 | uint8_t * uncompressed_stream, uint32_t uncompressed_length, | |
148 | uint8_t * uncompressed_test_stream, uint32_t uncompressed_test_stream_length) | |
7c673cae | 149 | { |
7c673cae FG |
150 | int ret; |
151 | ret = | |
224ce89b WB |
152 | compress2(compressed_stream, compressed_length, |
153 | uncompressed_stream, uncompressed_length, 6); | |
7c673cae FG |
154 | if (ret) { |
155 | printf("Failed compressing input with exit code %d", ret); | |
156 | return ret; | |
157 | } | |
158 | ||
224ce89b WB |
159 | ret = |
160 | inflate_multi_pass(compressed_stream + 2, | |
161 | *compressed_length - 2 - 4, | |
162 | uncompressed_test_stream, &uncompressed_test_stream_length); | |
7c673cae FG |
163 | switch (ret) { |
164 | case 0: | |
165 | break; | |
224ce89b | 166 | case ISAL_END_INPUT: |
7c673cae | 167 | printf(" did not decompress all input\n"); |
224ce89b | 168 | return ISAL_END_INPUT; |
7c673cae | 169 | break; |
224ce89b | 170 | case ISAL_INVALID_BLOCK: |
7c673cae | 171 | printf(" invalid header\n"); |
224ce89b | 172 | return ISAL_INVALID_BLOCK; |
7c673cae | 173 | break; |
224ce89b | 174 | case ISAL_INVALID_SYMBOL: |
7c673cae | 175 | printf(" invalid symbol\n"); |
224ce89b | 176 | return ISAL_INVALID_SYMBOL; |
7c673cae | 177 | break; |
224ce89b | 178 | case ISAL_OUT_OVERFLOW: |
7c673cae | 179 | printf(" out buffer overflow\n"); |
224ce89b | 180 | return ISAL_OUT_OVERFLOW; |
7c673cae | 181 | break; |
224ce89b | 182 | case ISAL_INVALID_LOOKBACK: |
7c673cae | 183 | printf("Invalid lookback distance"); |
224ce89b | 184 | return ISAL_INVALID_LOOKBACK; |
7c673cae FG |
185 | break; |
186 | default: | |
187 | printf(" error\n"); | |
188 | return -1; | |
189 | break; | |
190 | } | |
191 | ||
224ce89b | 192 | if (uncompressed_test_stream_length != uncompressed_length) { |
7c673cae | 193 | printf("incorrect amount of data was decompressed from compressed data\n"); |
224ce89b WB |
194 | printf("%d decompressed of %d compressed", |
195 | uncompressed_test_stream_length, uncompressed_length); | |
7c673cae FG |
196 | return -1; |
197 | } | |
198 | if (memcmp(uncompressed_stream, uncompressed_test_stream, uncompressed_length)) { | |
224ce89b WB |
199 | int i; |
200 | for (i = 0; i < uncompressed_length; i++) { | |
201 | if (uncompressed_stream[i] != uncompressed_test_stream[i]) { | |
202 | printf("first error at %d, 0x%x != 0x%x\n", i, | |
203 | uncompressed_stream[i], uncompressed_test_stream[i]); | |
204 | } | |
205 | } | |
7c673cae FG |
206 | printf(" decompressed data is not the same as the compressed data\n"); |
207 | return -1; | |
208 | } | |
224ce89b | 209 | |
7c673cae FG |
210 | return 0; |
211 | } | |
212 | ||
213 | int main(int argc, char **argv) | |
214 | { | |
215 | int i, j, ret = 0, fin_ret = 0; | |
224ce89b WB |
216 | FILE *file = NULL; |
217 | uint64_t compressed_length, file_length; | |
218 | uint64_t uncompressed_length, uncompressed_test_stream_length; | |
219 | uint8_t *uncompressed_stream = NULL; | |
220 | uint8_t *compressed_stream = NULL; | |
221 | uint8_t *uncompressed_test_stream = NULL; | |
7c673cae FG |
222 | |
223 | if (argc == 1) | |
224 | printf("Error, no input file\n"); | |
7c673cae FG |
225 | for (i = 1; i < argc; i++) { |
226 | file = fopen(argv[i], "r"); | |
227 | if (file == NULL) { | |
228 | printf("Error opening file %s\n", argv[i]); | |
229 | return 1; | |
230 | } else | |
231 | printf("Starting file %s", argv[i]); | |
224ce89b | 232 | fflush(0); |
7c673cae FG |
233 | fseek(file, 0, SEEK_END); |
234 | file_length = ftell(file); | |
235 | fseek(file, 0, SEEK_SET); | |
236 | file_length -= ftell(file); | |
237 | if (file_length > MAX_INPUT_FILE_SIZE) { | |
238 | printf("File too large to run on this test\n"); | |
239 | fclose(file); | |
240 | continue; | |
241 | } | |
224ce89b | 242 | |
7c673cae | 243 | compressed_length = compressBound(file_length); |
224ce89b WB |
244 | if (file_length != 0) { |
245 | uncompressed_stream = malloc(file_length); | |
246 | uncompressed_test_stream = malloc(file_length); | |
247 | } | |
7c673cae | 248 | compressed_stream = malloc(compressed_length); |
224ce89b | 249 | if (uncompressed_stream == NULL && file_length != 0) { |
7c673cae FG |
250 | printf("Failed to allocate memory\n"); |
251 | exit(0); | |
252 | } | |
253 | ||
254 | if (compressed_stream == NULL) { | |
255 | printf("Failed to allocate memory\n"); | |
256 | exit(0); | |
257 | } | |
258 | ||
259 | if (uncompressed_test_stream == NULL) { | |
260 | printf("Failed to allocate memory\n"); | |
261 | exit(0); | |
262 | } | |
263 | ||
264 | uncompressed_length = fread(uncompressed_stream, 1, file_length, file); | |
224ce89b | 265 | uncompressed_test_stream_length = uncompressed_length; |
7c673cae FG |
266 | ret = |
267 | test(compressed_stream, &compressed_length, uncompressed_stream, | |
224ce89b WB |
268 | uncompressed_length, uncompressed_test_stream, |
269 | uncompressed_test_stream_length); | |
7c673cae FG |
270 | if (ret) { |
271 | for (j = 0; j < compressed_length; j++) { | |
272 | if ((j & 31) == 0) | |
273 | printf("\n"); | |
274 | else | |
275 | printf(" "); | |
276 | printf("0x%02x,", compressed_stream[j]); | |
7c673cae FG |
277 | } |
278 | printf("\n"); | |
7c673cae FG |
279 | } |
280 | ||
224ce89b | 281 | fflush(0); |
7c673cae FG |
282 | fclose(file); |
283 | free(compressed_stream); | |
224ce89b WB |
284 | if (uncompressed_stream != NULL) |
285 | free(uncompressed_stream); | |
286 | if (uncompressed_test_stream != NULL) | |
287 | free(uncompressed_test_stream); | |
7c673cae FG |
288 | if (ret) { |
289 | printf(" ... Fail with exit code %d\n", ret); | |
290 | return ret; | |
291 | } else | |
292 | printf(" ... Pass\n"); | |
7c673cae FG |
293 | fin_ret |= ret; |
294 | } | |
295 | return fin_ret; | |
296 | } |