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 #define _FILE_OFFSET_BITS 64
31 #include <stdint.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <zlib.h>
35 #include "igzip_lib.h"
36 #include "huff_codes.h"
37 #include "test.h"
38
39 /*Don't use file larger memory can support because compression and decompression
40 * are done in a stateless manner. */
41 #if __WORDSIZE == 64
42 #define MAX_INPUT_FILE_SIZE 2L * 1024L * 1024L * 1024L
43 #else
44 #define MAX_INPUT_FILE_SIZE 512L * 1024L * 1024L
45 #endif
46
47 int
inflate_multi_pass(uint8_t * compress_buf,uint64_t compress_len,uint8_t * uncompress_buf,uint32_t * uncompress_len)48 inflate_multi_pass(uint8_t *compress_buf, uint64_t compress_len, uint8_t *uncompress_buf,
49 uint32_t *uncompress_len)
50 {
51 struct inflate_state *state = NULL;
52 int ret = 0;
53 uint8_t *comp_tmp = NULL, *uncomp_tmp = NULL;
54 uint32_t comp_tmp_size = 0, uncomp_tmp_size = 0;
55 uint32_t comp_processed = 0, uncomp_processed = 0;
56
57 state = malloc(sizeof(struct inflate_state));
58 if (state == NULL) {
59 printf("Failed to allocate memory\n");
60 exit(0);
61 }
62
63 isal_inflate_init(state);
64
65 state->next_in = NULL;
66 state->next_out = NULL;
67 state->avail_in = 0;
68 state->avail_out = 0;
69
70 while (1) {
71 if (state->avail_in == 0) {
72 comp_tmp_size = rand() % (compress_len + 1);
73
74 if (comp_tmp_size >= compress_len - comp_processed)
75 comp_tmp_size = compress_len - comp_processed;
76
77 if (comp_tmp_size != 0) {
78 if (comp_tmp != NULL)
79 free(comp_tmp);
80
81 comp_tmp = malloc(comp_tmp_size);
82
83 if (comp_tmp == NULL) {
84 printf("Failed to allocate memory\n");
85 exit(0);
86 }
87
88 memcpy(comp_tmp, compress_buf + comp_processed, comp_tmp_size);
89 comp_processed += comp_tmp_size;
90
91 state->next_in = comp_tmp;
92 state->avail_in = comp_tmp_size;
93 }
94 }
95
96 if (state->avail_out == 0) {
97 /* Save uncompressed data into uncompress_buf */
98 if (uncomp_tmp != NULL) {
99 memcpy(uncompress_buf + uncomp_processed, uncomp_tmp,
100 uncomp_tmp_size);
101 uncomp_processed += uncomp_tmp_size;
102 }
103
104 uncomp_tmp_size = rand() % (*uncompress_len + 1);
105
106 /* Limit size of buffer to be smaller than maximum */
107 if (uncomp_tmp_size > *uncompress_len - uncomp_processed)
108 uncomp_tmp_size = *uncompress_len - uncomp_processed;
109
110 if (uncomp_tmp_size != 0) {
111
112 if (uncomp_tmp != NULL) {
113 fflush(0);
114 free(uncomp_tmp);
115 }
116
117 uncomp_tmp = malloc(uncomp_tmp_size);
118 if (uncomp_tmp == NULL) {
119 printf("Failed to allocate memory\n");
120 exit(0);
121 }
122
123 state->avail_out = uncomp_tmp_size;
124 state->next_out = uncomp_tmp;
125 }
126 }
127
128 ret = isal_inflate(state);
129
130 if (state->block_state == ISAL_BLOCK_FINISH || ret != 0) {
131 memcpy(uncompress_buf + uncomp_processed, uncomp_tmp, uncomp_tmp_size);
132 *uncompress_len = state->total_out;
133 break;
134 }
135 }
136
137 if (comp_tmp != NULL) {
138 free(comp_tmp);
139 comp_tmp = NULL;
140 }
141 if (uncomp_tmp != NULL) {
142 free(uncomp_tmp);
143 uncomp_tmp = NULL;
144 }
145
146 free(state);
147 return ret;
148 }
149
150 int
test(uint8_t * compressed_stream,uint64_t * compressed_length,uint8_t * uncompressed_stream,uint32_t uncompressed_length,uint8_t * uncompressed_test_stream,uint32_t uncompressed_test_stream_length)151 test(uint8_t *compressed_stream, uint64_t *compressed_length, uint8_t *uncompressed_stream,
152 uint32_t uncompressed_length, uint8_t *uncompressed_test_stream,
153 uint32_t uncompressed_test_stream_length)
154 {
155 int ret;
156 ret = compress2(compressed_stream, (uLongf *) compressed_length, uncompressed_stream,
157 uncompressed_length, 6);
158 if (ret) {
159 printf("Failed compressing input with exit code %d", ret);
160 return ret;
161 }
162
163 ret = inflate_multi_pass(compressed_stream + 2, *compressed_length - 2 - 4,
164 uncompressed_test_stream, &uncompressed_test_stream_length);
165 switch (ret) {
166 case 0:
167 break;
168 case ISAL_END_INPUT:
169 printf(" did not decompress all input\n");
170 return ISAL_END_INPUT;
171 break;
172 case ISAL_INVALID_BLOCK:
173 printf(" invalid header\n");
174 return ISAL_INVALID_BLOCK;
175 break;
176 case ISAL_INVALID_SYMBOL:
177 printf(" invalid symbol\n");
178 return ISAL_INVALID_SYMBOL;
179 break;
180 case ISAL_OUT_OVERFLOW:
181 printf(" out buffer overflow\n");
182 return ISAL_OUT_OVERFLOW;
183 break;
184 case ISAL_INVALID_LOOKBACK:
185 printf("Invalid lookback distance");
186 return ISAL_INVALID_LOOKBACK;
187 break;
188 default:
189 printf(" error\n");
190 return -1;
191 break;
192 }
193
194 if (uncompressed_test_stream_length != uncompressed_length) {
195 printf("incorrect amount of data was decompressed from compressed data\n");
196 printf("%d decompressed of %d compressed", uncompressed_test_stream_length,
197 uncompressed_length);
198 return -1;
199 }
200 if (memcmp(uncompressed_stream, uncompressed_test_stream, uncompressed_length)) {
201 int i;
202 for (i = 0; i < uncompressed_length; i++) {
203 if (uncompressed_stream[i] != uncompressed_test_stream[i]) {
204 printf("first error at %d, 0x%x != 0x%x\n", i,
205 uncompressed_stream[i], uncompressed_test_stream[i]);
206 }
207 }
208 printf(" decompressed data is not the same as the compressed data\n");
209 return -1;
210 }
211
212 return 0;
213 }
214
215 int
main(int argc,char ** argv)216 main(int argc, char **argv)
217 {
218 int i, j, ret = 0, fin_ret = 0;
219 FILE *file = NULL;
220 uint64_t compressed_length, file_length;
221 uint64_t uncompressed_length, uncompressed_test_stream_length;
222 uint8_t *uncompressed_stream = NULL;
223 uint8_t *compressed_stream = NULL;
224 uint8_t *uncompressed_test_stream = NULL;
225
226 if (argc == 1)
227 printf("Error, no input file\n");
228 for (i = 1; i < argc; i++) {
229
230 file = NULL;
231 uncompressed_stream = NULL;
232 compressed_stream = NULL;
233 uncompressed_test_stream = NULL;
234
235 file = fopen(argv[i], "r");
236 if (file == NULL) {
237 printf("Error opening file %s\n", argv[i]);
238 return 1;
239 } else
240 printf("Starting file %s", argv[i]);
241 fflush(0);
242 file_length = get_filesize(file);
243 if (file_length > MAX_INPUT_FILE_SIZE) {
244 printf("\nFile too large to run on this test,"
245 " Max 512MB for 32bit OS, 2GB for 64bit OS.\n");
246 printf(" ... Fail\n");
247 fclose(file);
248 continue;
249 }
250
251 compressed_length = compressBound(file_length);
252
253 if (file_length != 0) {
254 uncompressed_stream = malloc(file_length);
255 uncompressed_test_stream = malloc(file_length);
256 }
257
258 compressed_stream = malloc(compressed_length);
259 if (uncompressed_stream == NULL && file_length != 0) {
260 printf("\nFailed to allocate input memory\n");
261 exit(0);
262 }
263
264 if (compressed_stream == NULL) {
265 printf("\nFailed to allocate output memory\n");
266 exit(0);
267 }
268
269 if (uncompressed_test_stream == NULL && file_length != 0) {
270 printf("\nFailed to allocate decompressed memory\n");
271 exit(0);
272 }
273
274 uncompressed_length = (uncompressed_stream == NULL)
275 ? 0
276 : fread(uncompressed_stream, 1, file_length, file);
277 uncompressed_test_stream_length = uncompressed_length;
278 ret = test(compressed_stream, &compressed_length, uncompressed_stream,
279 uncompressed_length, uncompressed_test_stream,
280 uncompressed_test_stream_length);
281 if (ret) {
282 for (j = 0; j < compressed_length; j++) {
283 if ((j & 31) == 0)
284 printf("\n");
285 else
286 printf(" ");
287 printf("0x%02x,", compressed_stream[j]);
288 }
289 printf("\n");
290 }
291
292 fflush(0);
293 fclose(file);
294 if (compressed_stream != NULL)
295 free(compressed_stream);
296 if (uncompressed_stream != NULL)
297 free(uncompressed_stream);
298 if (uncompressed_test_stream != NULL)
299 free(uncompressed_test_stream);
300 if (ret) {
301 printf(" ... Fail with exit code %d\n", ret);
302 return ret;
303 } else
304 printf(" ... Pass\n");
305 fin_ret |= ret;
306 }
307 return fin_ret;
308 }
309