xref: /isa-l/igzip/igzip_rand_test.c (revision 5be1ba2215613379677fb85cccb327627bdac6a0)
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 <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <assert.h>
35 #include "igzip_lib.h"
36 #include "checksum_test_ref.h"
37 #include "inflate_std_vects.h"
38 #include <math.h>
39 #include "test.h"
40 #include "unaligned.h"
41 
42 #ifndef RANDOMS
43 # define RANDOMS   0x40
44 #endif
45 #ifndef TEST_SEED
46 # define TEST_SEED 0x1234
47 #endif
48 
49 #define MAX_BITS_COUNT 20
50 #define MIN_BITS_COUNT 8
51 
52 #define IBUF_SIZE  (1024*1024)
53 
54 #define MAX_LARGE_COMP_BUF_SIZE (1024*1024)
55 
56 #define PAGE_SIZE 4*1024
57 
58 #define MAX_FILE_SIZE 0x7fff8fff
59 
60 #define str1 "Short test string"
61 #define str2 "one two three four five six seven eight nine ten eleven twelve " \
62 		 "thirteen fourteen fifteen sixteen"
63 
64 #define TYPE0_HDR_SIZE 5	/* Size of a type 0 blocks header in bytes */
65 #define TYPE0_MAX_SIZE 65535	/* Max length of a type 0 block in bytes (excludes the header) */
66 
67 #define MAX_LOOPS 20
68 /* Defines for the possible error conditions */
69 enum IGZIP_TEST_ERROR_CODES {
70 	IGZIP_COMP_OK = 0,
71 
72 	MALLOC_FAILED,
73 	FILE_READ_FAILED,
74 
75 	COMPRESS_INCORRECT_STATE,
76 	COMPRESS_INPUT_STREAM_INTEGRITY_ERROR,
77 	COMPRESS_OUTPUT_STREAM_INTEGRITY_ERROR,
78 	COMPRESS_END_OF_STREAM_NOT_SET,
79 	COMPRESS_ALL_INPUT_FAIL,
80 	COMPRESS_OUT_BUFFER_OVERFLOW,
81 	COMPRESS_LOOP_COUNT_OVERFLOW,
82 	COMPRESS_GENERAL_ERROR,
83 
84 	INFLATE_END_OF_INPUT,
85 	INFLATE_INVALID_BLOCK_HEADER,
86 	INFLATE_INVALID_SYMBOL,
87 	INFLATE_OUT_BUFFER_OVERFLOW,
88 	INFLATE_LEFTOVER_INPUT,
89 	INFLATE_INCORRECT_OUTPUT_SIZE,
90 	INFLATE_INVALID_LOOK_BACK_DISTANCE,
91 	INFLATE_INPUT_STREAM_INTEGRITY_ERROR,
92 	INFLATE_OUTPUT_STREAM_INTEGRITY_ERROR,
93 	INVALID_GZIP_HEADER,
94 	INCORRECT_GZIP_TRAILER,
95 	INVALID_ZLIB_HEADER,
96 	INCORRECT_ZLIB_TRAILER,
97 
98 	UNSUPPORTED_METHOD,
99 
100 	INFLATE_GENERAL_ERROR,
101 
102 	INVALID_FLUSH_ERROR,
103 
104 	OVERFLOW_TEST_ERROR,
105 	RESULT_ERROR
106 };
107 
108 static const int hdr_bytes = 300;
109 
110 static const uint32_t gzip_trl_bytes = 8;
111 static const uint32_t zlib_trl_bytes = 4;
112 static const int gzip_extra_bytes = 18;	/* gzip_hdr_bytes + gzip_trl_bytes */
113 static const int zlib_extra_bytes = 6;	/* zlib_hdr_bytes + zlib_trl_bytes */
114 
115 int inflate_type = 0;
116 
117 struct isal_hufftables *hufftables = NULL;
118 struct isal_hufftables *hufftables_subset = NULL;
119 
120 #define HISTORY_SIZE 32*1024
121 #define MIN_LENGTH 3
122 #define MIN_DIST 1
123 
124 /* Create random compressible data. This is achieved by randomly choosing a
125  * random character, or to repeat previous data in the stream for a random
126  * length and look back distance. The probability of a random character or a
127  * repeat being chosen is semi-randomly chosen by setting max_repeat_data to be
128  * differing values */
129 void create_rand_repeat_data(uint8_t * data, int size)
130 {
131 	uint32_t next_data;
132 	uint8_t *data_start = data;
133 	uint32_t length, distance;
134 	uint32_t symbol_count = rand() % 255 + 1, swaps_left, tmp;
135 	uint32_t max_repeat_data = symbol_count;
136 	uint8_t symbols[256], *symbols_next, swap_val;
137 
138 	/* An array of the powers of 2 (except the final element which is 0) */
139 	const uint32_t power_of_2_array[] = {
140 		0x00000001, 0x00000002, 0x00000004, 0x00000008,
141 		0x00000010, 0x00000020, 0x00000040, 0x00000080,
142 		0x00000100, 0x00000200, 0x00000400, 0x00000800,
143 		0x00001000, 0x00002000, 0x00004000, 0x00008000,
144 		0x00010000, 0x00020000, 0x00040000, 0x00080000,
145 		0x00100000, 0x00200000, 0x00400000, 0x00800000,
146 		0x01000000, 0x02000000, 0x04000000, 0x08000000,
147 		0x10000000, 0x20000000, 0x40000000, 0x00000000
148 	};
149 
150 	uint32_t power = rand() % sizeof(power_of_2_array) / sizeof(uint32_t);
151 
152 	if (symbol_count > 128) {
153 		memset(symbols, 1, sizeof(symbols));
154 		swap_val = 0;
155 		swaps_left = 256 - symbol_count;
156 	} else {
157 		memset(symbols, 0, sizeof(symbols));
158 		swap_val = 1;
159 		swaps_left = symbol_count;
160 	}
161 
162 	while (swaps_left > 0) {
163 		tmp = rand() % 256;
164 		if (symbols[tmp] != swap_val) {
165 			symbols[tmp] = swap_val;
166 			swaps_left--;
167 		}
168 	}
169 
170 	symbols_next = symbols;
171 	for (tmp = 0; tmp < 256; tmp++) {
172 		if (symbols[tmp]) {
173 			*symbols_next = tmp;
174 			symbols_next++;
175 		}
176 	}
177 
178 	max_repeat_data += power_of_2_array[power];
179 
180 	if (size > 0) {
181 		size--;
182 		*data++ = rand();
183 	}
184 
185 	while (size > 0) {
186 		next_data = rand() % max_repeat_data;
187 		if (next_data < symbol_count) {
188 			*data++ = symbols[next_data];
189 			size--;
190 		} else if (size < 3) {
191 			*data++ = symbols[rand() % symbol_count];
192 			size--;
193 		} else {
194 			length = (rand() % 256) + MIN_LENGTH;
195 			if (length > size)
196 				length = (rand() % (size - 2)) + MIN_LENGTH;
197 
198 			distance = (rand() % HISTORY_SIZE) + MIN_DIST;
199 			if (distance > data - data_start)
200 				distance = (rand() % (data - data_start)) + MIN_DIST;
201 
202 			size -= length;
203 			if (distance <= length) {
204 				while (length-- > 0) {
205 					*data = *(data - distance);
206 					data++;
207 				}
208 			} else {
209 				memcpy(data, data - distance, length);
210 				data += length;
211 			}
212 		}
213 	}
214 }
215 
216 void create_rand_dict(uint8_t * dict, uint32_t dict_len, uint8_t * buf, uint32_t buf_len)
217 {
218 	uint32_t dict_chunk_size, buf_chunk_size;
219 	while (dict_len > 0) {
220 		dict_chunk_size = rand() % IGZIP_K;
221 		dict_chunk_size = (dict_len >= dict_chunk_size) ? dict_chunk_size : dict_len;
222 
223 		buf_chunk_size = rand() % IGZIP_K;
224 		buf_chunk_size = (buf_len >= buf_chunk_size) ? buf_chunk_size : buf_len;
225 
226 		if (rand() % 3 == 0 && buf_len >= dict_len)
227 			memcpy(dict, buf, dict_chunk_size);
228 		else
229 			create_rand_repeat_data(dict, dict_chunk_size);
230 
231 		dict_len -= dict_chunk_size;
232 		dict += dict_chunk_size;
233 		buf_len -= buf_chunk_size;
234 		buf += buf_chunk_size;
235 	}
236 
237 }
238 
239 int get_rand_data_length(void)
240 {
241 	int max_mask =
242 	    (1 << ((rand() % (MAX_BITS_COUNT - MIN_BITS_COUNT)) + MIN_BITS_COUNT)) - 1;
243 	return rand() & max_mask;
244 }
245 
246 int get_rand_level(void)
247 {
248 	return ISAL_DEF_MIN_LEVEL + rand() % (ISAL_DEF_MAX_LEVEL - ISAL_DEF_MIN_LEVEL + 1);
249 
250 }
251 
252 int get_rand_level_buf_size(int level)
253 {
254 	int size;
255 	switch (level) {
256 	case 3:
257 		size = rand() % IBUF_SIZE + ISAL_DEF_LVL3_MIN;
258 		break;
259 	case 2:
260 		size = rand() % IBUF_SIZE + ISAL_DEF_LVL2_MIN;
261 		break;
262 	case 1:
263 	default:
264 		size = rand() % IBUF_SIZE + ISAL_DEF_LVL1_MIN;
265 	}
266 	return size;
267 }
268 
269 void print_error(int error_code)
270 {
271 	switch (error_code) {
272 	case IGZIP_COMP_OK:
273 		break;
274 	case MALLOC_FAILED:
275 		printf("error: failed to allocate memory\n");
276 		break;
277 	case FILE_READ_FAILED:
278 		printf("error: failed to read in file\n");
279 		break;
280 	case COMPRESS_INCORRECT_STATE:
281 		printf("error: incorrect stream internal state\n");
282 		break;
283 	case COMPRESS_INPUT_STREAM_INTEGRITY_ERROR:
284 		printf("error: inconsistent stream input buffer\n");
285 		break;
286 	case COMPRESS_OUTPUT_STREAM_INTEGRITY_ERROR:
287 		printf("error: inconsistent stream output buffer\n");
288 		break;
289 	case COMPRESS_END_OF_STREAM_NOT_SET:
290 		printf("error: end of stream not set\n");
291 		break;
292 	case COMPRESS_ALL_INPUT_FAIL:
293 		printf("error: not all input data compressed\n");
294 		break;
295 	case COMPRESS_OUT_BUFFER_OVERFLOW:
296 		printf("error: output buffer overflow while compressing data\n");
297 		break;
298 	case COMPRESS_GENERAL_ERROR:
299 		printf("error: compression failed\n");
300 		break;
301 	case INFLATE_END_OF_INPUT:
302 		printf("error: did not decompress all input\n");
303 		break;
304 	case INFLATE_INVALID_BLOCK_HEADER:
305 		printf("error: invalid header\n");
306 		break;
307 	case INFLATE_INVALID_SYMBOL:
308 		printf("error: invalid symbol found when decompressing input\n");
309 		break;
310 	case INFLATE_OUT_BUFFER_OVERFLOW:
311 		printf("error: output buffer overflow while decompressing data\n");
312 		break;
313 	case INFLATE_GENERAL_ERROR:
314 		printf("error: decompression failed\n");
315 		break;
316 	case INFLATE_LEFTOVER_INPUT:
317 		printf("error: the trailer of igzip output contains junk\n");
318 		break;
319 	case INFLATE_INCORRECT_OUTPUT_SIZE:
320 		printf("error: incorrect amount of data was decompressed\n");
321 		break;
322 	case INFLATE_INVALID_LOOK_BACK_DISTANCE:
323 		printf("error: invalid look back distance found while decompressing\n");
324 		break;
325 	case INFLATE_INPUT_STREAM_INTEGRITY_ERROR:
326 		printf("error: inconsistent input buffer\n");
327 		break;
328 	case INFLATE_OUTPUT_STREAM_INTEGRITY_ERROR:
329 		printf("error: inconsistent output buffer\n");
330 		break;
331 	case INVALID_GZIP_HEADER:
332 		printf("error: incorrect gzip header found when inflating data\n");
333 		break;
334 	case INCORRECT_GZIP_TRAILER:
335 		printf("error: incorrect gzip trailer found when inflating data\n");
336 		break;
337 	case INVALID_ZLIB_HEADER:
338 		printf("error: incorrect zlib header found when inflating data\n");
339 		break;
340 	case INCORRECT_ZLIB_TRAILER:
341 		printf("error: incorrect zlib trailer found when inflating data\n");
342 		break;
343 	case UNSUPPORTED_METHOD:
344 		printf("error: invalid compression method in wrapper header\n");
345 		break;
346 	case INVALID_FLUSH_ERROR:
347 		printf("error: invalid flush did not cause compression to error\n");
348 		break;
349 	case RESULT_ERROR:
350 		printf("error: decompressed data is not the same as the compressed data\n");
351 		break;
352 	case OVERFLOW_TEST_ERROR:
353 		printf("error: overflow undetected\n");
354 		break;
355 	default:
356 		printf("error: unknown error code\n");
357 	}
358 }
359 
360 void print_uint8_t(uint8_t * array, uint64_t length)
361 {
362 	const int line_size = 16;
363 	int i;
364 
365 	printf("Length = %lu", length);
366 	for (i = 0; i < length; i++) {
367 		if ((i % line_size) == 0)
368 			printf("\n0x%08x\t", i);
369 		else
370 			printf(" ");
371 		printf("0x%02x,", array[i]);
372 	}
373 	printf("\n");
374 }
375 
376 uint32_t check_gzip_trl(uint64_t gzip_trl, uint32_t inflate_crc, uint8_t * uncompress_buf,
377 			uint32_t uncompress_len)
378 {
379 	uint64_t trl, ret = 0;
380 	uint32_t crc;
381 
382 	crc = crc32_gzip_refl_ref(0, uncompress_buf, uncompress_len);
383 	trl = ((uint64_t) uncompress_len << 32) | crc;
384 
385 	if (crc != inflate_crc || trl != gzip_trl)
386 		ret = INCORRECT_GZIP_TRAILER;
387 
388 	return ret;
389 }
390 
391 uint32_t check_zlib_trl(uint32_t zlib_trl, uint32_t inflate_adler, uint8_t * uncompress_buf,
392 			uint32_t uncompress_len)
393 {
394 	uint32_t trl, ret = 0;
395 	uint32_t adler;
396 
397 	adler = adler_ref(1, uncompress_buf, uncompress_len);
398 
399 	trl =
400 	    (adler >> 24) | ((adler >> 8) & 0xFF00) | (adler << 24) | ((adler & 0xFF00) << 8);
401 
402 	if (adler != inflate_adler || trl != zlib_trl) {
403 		ret = INCORRECT_ZLIB_TRAILER;
404 	}
405 
406 	return ret;
407 }
408 
409 int inflate_stateless_pass(uint8_t * compress_buf, uint64_t compress_len,
410 			   uint8_t * uncompress_buf, uint32_t * uncompress_len,
411 			   uint32_t gzip_flag)
412 {
413 	struct inflate_state state;
414 	int ret = 0, offset = 0;
415 	struct isal_gzip_header gz_hdr;
416 	struct isal_zlib_header z_hdr;
417 
418 	state.next_in = compress_buf;
419 	state.avail_in = compress_len;
420 	state.next_out = uncompress_buf;
421 	state.avail_out = *uncompress_len;
422 
423 	if (gzip_flag == IGZIP_GZIP) {
424 		if (rand() % 2 == 0) {
425 			memset(&gz_hdr, 0, sizeof(gz_hdr));
426 			isal_inflate_reset(&state);
427 			state.tmp_in_size = 0;
428 			gzip_flag = ISAL_GZIP_NO_HDR_VER;
429 
430 			isal_read_gzip_header(&state, &gz_hdr);
431 		}
432 	} else if (gzip_flag == IGZIP_ZLIB) {
433 		if (rand() % 2 == 0) {
434 			memset(&z_hdr, 0, sizeof(z_hdr));
435 			isal_inflate_reset(&state);
436 			gzip_flag = ISAL_ZLIB_NO_HDR_VER;
437 			isal_read_zlib_header(&state, &z_hdr);
438 		}
439 	}
440 
441 	state.crc_flag = gzip_flag;
442 
443 	ret = isal_inflate_stateless(&state);
444 
445 	*uncompress_len = state.total_out;
446 
447 	if (gzip_flag) {
448 		if (gzip_flag == IGZIP_GZIP || gzip_flag == IGZIP_GZIP_NO_HDR
449 		    || gzip_flag == ISAL_GZIP_NO_HDR_VER) {
450 			if (gzip_flag == IGZIP_GZIP || gzip_flag == ISAL_GZIP_NO_HDR_VER)
451 				offset = gzip_trl_bytes;
452 
453 			if (!ret)
454 				ret =
455 				    check_gzip_trl(load_u64(state.next_in - offset),
456 						   state.crc, uncompress_buf, *uncompress_len);
457 			else if (ret == ISAL_INCORRECT_CHECKSUM)
458 				ret = INCORRECT_GZIP_TRAILER;
459 			state.avail_in -= (gzip_trl_bytes - offset);
460 		} else if (gzip_flag == IGZIP_ZLIB || gzip_flag == IGZIP_ZLIB_NO_HDR
461 			   || gzip_flag == ISAL_ZLIB_NO_HDR_VER) {
462 			if (gzip_flag == IGZIP_ZLIB || gzip_flag == ISAL_ZLIB_NO_HDR_VER)
463 				offset = zlib_trl_bytes;
464 
465 			if (!ret)
466 				ret =
467 				    check_zlib_trl(load_u32(state.next_in - offset),
468 						   state.crc, uncompress_buf, *uncompress_len);
469 			else if (ret == ISAL_INCORRECT_CHECKSUM)
470 				ret = INCORRECT_ZLIB_TRAILER;
471 			state.avail_in -= (zlib_trl_bytes - offset);
472 
473 		}
474 
475 	}
476 
477 	if (ret == 0 && state.avail_in != 0)
478 		ret = INFLATE_LEFTOVER_INPUT;
479 
480 	return ret;
481 }
482 
483 /* Check if that the state of the data stream is consistent */
484 int inflate_state_valid_check(struct inflate_state *state, uint8_t * in_buf, uint32_t in_size,
485 			      uint8_t * out_buf, uint32_t out_size, uint32_t in_processed,
486 			      uint32_t out_processed, uint32_t data_size)
487 {
488 	uint32_t in_buffer_size, total_out, out_buffer_size;
489 
490 	in_buffer_size = (in_size == 0) ? 0 : state->next_in - in_buf + state->avail_in;
491 
492 	/* Check for a consistent amount of data processed */
493 	if (in_buffer_size != in_size)
494 		return INFLATE_INPUT_STREAM_INTEGRITY_ERROR;
495 
496 	total_out =
497 	    (out_size == 0) ? out_processed : out_processed + (state->next_out - out_buf);
498 	out_buffer_size = (out_size == 0) ? 0 : state->next_out - out_buf + state->avail_out;
499 
500 	/* Check for a consistent amount of data compressed */
501 	if (total_out != state->total_out || out_buffer_size != out_size)
502 		return INFLATE_OUTPUT_STREAM_INTEGRITY_ERROR;
503 
504 	return 0;
505 }
506 
507 /* Performs compression with checks to discover and verify the state of the
508  * stream
509  * state: inflate data structure which has been initialized to use
510  * in_buf and out_buf as the buffers
511  * compress_len: size of all input compressed data
512  * data_size: size of all available output buffers
513  * in_buf: next buffer of data to be inflated
514  * in_size: size of in_buf
515  * out_buf: next out put buffer where data is stored
516  * out_size: size of out_buf
517  * in_processed: the amount of input data which has been loaded into buffers
518  * to be inflated, this includes the data in in_buf
519  * out_processed: the amount of output data which has been decompressed and stored,
520  * this does not include the data in the current out_buf
521 */
522 int isal_inflate_with_checks(struct inflate_state *state, uint32_t compress_len,
523 			     uint32_t data_size, uint8_t * in_buf, uint32_t in_size,
524 			     uint32_t in_processed, uint8_t * out_buf, uint32_t out_size,
525 			     uint32_t out_processed)
526 {
527 	int ret, stream_check = 0;
528 
529 	ret = isal_inflate(state);
530 
531 	/* Verify the stream is in a valid state when no errors occured */
532 	if (ret >= 0) {
533 		stream_check =
534 		    inflate_state_valid_check(state, in_buf, in_size, out_buf, out_size,
535 					      in_processed, out_processed, data_size);
536 	}
537 
538 	if (stream_check != 0)
539 		return stream_check;
540 
541 	return ret;
542 
543 }
544 
545 int inflate_multi_pass(uint8_t * compress_buf, uint64_t compress_len,
546 		       uint8_t * uncompress_buf, uint32_t * uncompress_len, uint32_t gzip_flag,
547 		       uint8_t * dict, uint32_t dict_len, uint32_t hist_bits)
548 {
549 	struct inflate_state *state = NULL;
550 	int ret = 0;
551 	uint8_t *comp_tmp = NULL, *uncomp_tmp = NULL;
552 	uint32_t comp_tmp_size = 0, uncomp_tmp_size = 0;
553 	uint32_t comp_processed = 0, uncomp_processed = 0;
554 	int32_t read_in_old = 0;
555 	uint32_t reset_test_flag = 0;
556 
557 	state = malloc(sizeof(struct inflate_state));
558 	if (state == NULL) {
559 		printf("Failed to allocate memory\n");
560 		exit(0);
561 	}
562 
563 	create_rand_repeat_data((uint8_t *) state, sizeof(state));
564 	isal_inflate_init(state);
565 
566 	if (rand() % 4 == 0) {
567 		/* Test reset */
568 		reset_test_flag = 1;
569 		create_rand_repeat_data((uint8_t *) state, sizeof(state));
570 	}
571 
572 	if (gzip_flag == IGZIP_GZIP_NO_HDR) {
573 		if (rand() % 2 == 0)
574 			compress_len -= gzip_trl_bytes;
575 		else
576 			gzip_flag = ISAL_GZIP_NO_HDR_VER;
577 	} else if (gzip_flag == IGZIP_ZLIB_NO_HDR) {
578 		if (rand() % 2 == 0)
579 			compress_len -= zlib_trl_bytes;
580 		else
581 			gzip_flag = ISAL_ZLIB_NO_HDR_VER;
582 	}
583 
584 	state->next_in = NULL;
585 	state->next_out = NULL;
586 	state->avail_in = 0;
587 	state->avail_out = 0;
588 	state->crc_flag = gzip_flag;
589 	state->hist_bits = hist_bits;
590 
591 	if (reset_test_flag)
592 		isal_inflate_reset(state);
593 
594 	if (dict != NULL)
595 		isal_inflate_set_dict(state, dict, dict_len);
596 
597 	while (1) {
598 		if (state->avail_in == 0) {
599 			comp_tmp_size = rand() % (compress_len + 1);
600 
601 			if (comp_tmp_size >= compress_len - comp_processed)
602 				comp_tmp_size = compress_len - comp_processed;
603 
604 			if (comp_tmp_size != 0) {
605 				if (comp_tmp != NULL) {
606 					free(comp_tmp);
607 					comp_tmp = NULL;
608 				}
609 
610 				comp_tmp = malloc(comp_tmp_size);
611 
612 				if (comp_tmp == NULL) {
613 					printf("Failed to allocate memory\n");
614 					return MALLOC_FAILED;
615 				}
616 
617 				memcpy(comp_tmp, compress_buf + comp_processed, comp_tmp_size);
618 				comp_processed += comp_tmp_size;
619 
620 				state->next_in = comp_tmp;
621 				state->avail_in = comp_tmp_size;
622 			}
623 		}
624 
625 		if (state->avail_out == 0) {
626 			/* Save uncompressed data into uncompress_buf */
627 			if (uncomp_tmp != NULL) {
628 				memcpy(uncompress_buf + uncomp_processed, uncomp_tmp,
629 				       uncomp_tmp_size);
630 				uncomp_processed += uncomp_tmp_size;
631 			}
632 
633 			uncomp_tmp_size = rand() % (*uncompress_len + 1);
634 
635 			/* Limit size of buffer to be smaller than maximum */
636 			if (uncomp_tmp_size > *uncompress_len - uncomp_processed)
637 				uncomp_tmp_size = *uncompress_len - uncomp_processed;
638 
639 			if (uncomp_tmp_size != 0) {
640 
641 				if (uncomp_tmp != NULL) {
642 					fflush(0);
643 					free(uncomp_tmp);
644 					uncomp_tmp = NULL;
645 				}
646 
647 				uncomp_tmp = malloc(uncomp_tmp_size);
648 				if (uncomp_tmp == NULL) {
649 					printf("Failed to allocate memory\n");
650 					return MALLOC_FAILED;
651 				}
652 
653 				state->avail_out = uncomp_tmp_size;
654 				state->next_out = uncomp_tmp;
655 			}
656 		}
657 #ifdef VERBOSE
658 		printf("Pre inflate\n");
659 		printf
660 		    ("compressed_size = 0x%05lx, in_processed = 0x%05x, in_size = 0x%05x, avail_in = 0x%05x\n",
661 		     compress_len, comp_processed, comp_tmp_size, state->avail_in);
662 		printf
663 		    ("data_size       = 0x%05x, out_processed  = 0x%05x, out_size  = 0x%05x, avail_out  = 0x%05x, total_out  = 0x%05x\n",
664 		     *uncompress_len, uncomp_processed, uncomp_tmp_size, state->avail_out,
665 		     state->total_out);
666 #endif
667 
668 		ret = isal_inflate_with_checks(state, compress_len, *uncompress_len, comp_tmp,
669 					       comp_tmp_size, comp_processed, uncomp_tmp,
670 					       uncomp_tmp_size, uncomp_processed);
671 
672 #ifdef VERBOSE
673 		printf("Post inflate\n");
674 		printf
675 		    ("compressed_size = 0x%05lx, in_processed = 0x%05x, in_size = 0x%05x, avail_in = 0x%05x\n",
676 		     compress_len, comp_processed, comp_tmp_size, state->avail_in);
677 		printf
678 		    ("data_size       = 0x%05x, out_processed  = 0x%05x, out_size  = 0x%05x, avail_out  = 0x%05x, total_out  = 0x%05x\n",
679 		     *uncompress_len, uncomp_processed, uncomp_tmp_size, state->avail_out,
680 		     state->total_out);
681 #endif
682 
683 		if (state->block_state == ISAL_BLOCK_FINISH || ret != 0) {
684 			memcpy(uncompress_buf + uncomp_processed, uncomp_tmp, uncomp_tmp_size);
685 			*uncompress_len = state->total_out;
686 			break;
687 		}
688 
689 		if (*uncompress_len - uncomp_processed == 0 && state->avail_out == 0
690 		    && state->tmp_out_valid - state->tmp_out_processed > 0) {
691 			ret = ISAL_OUT_OVERFLOW;
692 			break;
693 		}
694 
695 		if (compress_len - comp_processed == 0 && state->avail_in == 0
696 		    && (state->block_state != ISAL_BLOCK_INPUT_DONE)
697 		    && state->tmp_out_valid - state->tmp_out_processed == 0) {
698 			if (state->read_in_length == read_in_old) {
699 				ret = ISAL_END_INPUT;
700 				break;
701 			}
702 			read_in_old = state->read_in_length;
703 		}
704 	}
705 
706 	if (gzip_flag) {
707 		if (!ret) {
708 			if (gzip_flag == IGZIP_GZIP || gzip_flag == IGZIP_GZIP_NO_HDR
709 			    || gzip_flag == ISAL_GZIP_NO_HDR_VER) {
710 				if (gzip_flag == ISAL_GZIP_NO_HDR_VER
711 				    || gzip_flag == IGZIP_GZIP)
712 					compress_len -= gzip_trl_bytes;
713 				ret =
714 				    check_gzip_trl(load_u64(compress_buf + compress_len),
715 						   state->crc, uncompress_buf,
716 						   *uncompress_len);
717 			} else if (gzip_flag == IGZIP_ZLIB_NO_HDR) {
718 				if (gzip_flag == IGZIP_ZLIB
719 				    || gzip_flag == ISAL_ZLIB_NO_HDR_VER)
720 					compress_len -= zlib_trl_bytes;
721 				ret =
722 				    check_zlib_trl(load_u32(compress_buf + compress_len),
723 						   state->crc, uncompress_buf,
724 						   *uncompress_len);
725 			}
726 		}
727 	}
728 	if (ret == 0 && state->avail_in != 0)
729 		ret = INFLATE_LEFTOVER_INPUT;
730 
731 	if (comp_tmp != NULL) {
732 		free(comp_tmp);
733 		comp_tmp = NULL;
734 	}
735 
736 	if (uncomp_tmp != NULL) {
737 		free(uncomp_tmp);
738 		uncomp_tmp = NULL;
739 	}
740 
741 	free(state);
742 	return ret;
743 }
744 
745 int inflate_ret_to_code(int ret)
746 {
747 	switch (ret) {
748 	case ISAL_DECOMP_OK:
749 		return 0;
750 	case ISAL_END_INPUT:
751 		return INFLATE_END_OF_INPUT;
752 	case ISAL_OUT_OVERFLOW:
753 		return INFLATE_OUT_BUFFER_OVERFLOW;
754 	case ISAL_INVALID_BLOCK:
755 		return INFLATE_INVALID_BLOCK_HEADER;
756 	case ISAL_INVALID_SYMBOL:
757 		return INFLATE_INVALID_SYMBOL;
758 	case ISAL_INVALID_LOOKBACK:
759 		return INFLATE_INVALID_LOOK_BACK_DISTANCE;
760 	default:
761 		return INFLATE_GENERAL_ERROR;
762 	}
763 }
764 
765 /* Inflate the  compressed data and check that the decompressed data agrees with the input data */
766 int inflate_check(uint8_t * z_buf, uint32_t z_size, uint8_t * in_buf, uint32_t in_size,
767 		  uint32_t gzip_flag, uint8_t * dict, uint32_t dict_len, uint32_t hist_bits)
768 {
769 	/* Test inflate with reference inflate */
770 
771 	int ret = 0;
772 	uint32_t test_size = in_size;
773 	uint8_t *test_buf = NULL;
774 	int mem_result = 0;
775 	int gzip_hdr_result = 0, gzip_trl_result = 0;
776 
777 	if (in_size > 0) {
778 		assert(in_buf != NULL);
779 		test_buf = malloc(test_size);
780 		if (test_buf == NULL)
781 			return MALLOC_FAILED;
782 	}
783 
784 	if (test_buf != NULL)
785 		memset(test_buf, 0xff, test_size);
786 
787 	if (inflate_type == 0 && dict == NULL) {
788 		ret = inflate_stateless_pass(z_buf, z_size, test_buf, &test_size, gzip_flag);
789 		inflate_type = 1;
790 	} else {
791 		ret =
792 		    inflate_multi_pass(z_buf, z_size, test_buf, &test_size, gzip_flag, dict,
793 				       dict_len, hist_bits);
794 		inflate_type = 0;
795 	}
796 
797 	if (test_buf != NULL)
798 		mem_result = memcmp(in_buf, test_buf, in_size);
799 
800 #ifdef VERBOSE
801 	int i;
802 	if (mem_result)
803 		for (i = 0; i < in_size; i++) {
804 			if (in_buf[i] != test_buf[i]) {
805 				printf
806 				    ("First incorrect data at 0x%x of 0x%x, 0x%x != 0x%x\n",
807 				     i, in_size, in_buf[i], test_buf[i]);
808 				break;
809 			}
810 		}
811 #endif
812 
813 	if (test_buf != NULL)
814 		free(test_buf);
815 	switch (ret) {
816 	case 0:
817 		break;
818 	case ISAL_END_INPUT:
819 		return INFLATE_END_OF_INPUT;
820 		break;
821 	case ISAL_INVALID_BLOCK:
822 		return INFLATE_INVALID_BLOCK_HEADER;
823 		break;
824 	case ISAL_INVALID_SYMBOL:
825 		return INFLATE_INVALID_SYMBOL;
826 		break;
827 	case ISAL_OUT_OVERFLOW:
828 		return INFLATE_OUT_BUFFER_OVERFLOW;
829 		break;
830 	case ISAL_INVALID_LOOKBACK:
831 		return INFLATE_INVALID_LOOK_BACK_DISTANCE;
832 		break;
833 	case INFLATE_LEFTOVER_INPUT:
834 		return INFLATE_LEFTOVER_INPUT;
835 		break;
836 	case INCORRECT_GZIP_TRAILER:
837 		gzip_trl_result = INCORRECT_GZIP_TRAILER;
838 		break;
839 	case INCORRECT_ZLIB_TRAILER:
840 		gzip_trl_result = INCORRECT_ZLIB_TRAILER;
841 		break;
842 	case ISAL_INCORRECT_CHECKSUM:
843 		if (gzip_flag == IGZIP_GZIP || gzip_flag == IGZIP_GZIP_NO_HDR
844 		    || gzip_flag == ISAL_GZIP_NO_HDR_VER)
845 			gzip_trl_result = INCORRECT_GZIP_TRAILER;
846 		else if (gzip_flag == IGZIP_ZLIB || gzip_flag == IGZIP_ZLIB_NO_HDR
847 			 || gzip_flag == ISAL_ZLIB_NO_HDR_VER)
848 			gzip_trl_result = INCORRECT_GZIP_TRAILER;
849 		break;
850 	case ISAL_UNSUPPORTED_METHOD:
851 		return UNSUPPORTED_METHOD;
852 	case INFLATE_INPUT_STREAM_INTEGRITY_ERROR:
853 		return INFLATE_INPUT_STREAM_INTEGRITY_ERROR;
854 		break;
855 	case INFLATE_OUTPUT_STREAM_INTEGRITY_ERROR:
856 		return INFLATE_OUTPUT_STREAM_INTEGRITY_ERROR;
857 		break;
858 	default:
859 		return INFLATE_GENERAL_ERROR;
860 		break;
861 	}
862 
863 	if (test_size != in_size)
864 		return INFLATE_INCORRECT_OUTPUT_SIZE;
865 
866 	if (mem_result)
867 		return RESULT_ERROR;
868 
869 	if (gzip_hdr_result == INVALID_GZIP_HEADER)
870 		return INVALID_GZIP_HEADER;
871 
872 	else if (gzip_hdr_result == INVALID_ZLIB_HEADER)
873 		return INVALID_ZLIB_HEADER;
874 
875 	if (gzip_trl_result == INCORRECT_GZIP_TRAILER)
876 		return INCORRECT_GZIP_TRAILER;
877 
878 	else if (gzip_trl_result == INCORRECT_ZLIB_TRAILER)
879 		return INCORRECT_ZLIB_TRAILER;
880 
881 	return 0;
882 }
883 
884 /* Check if that the state of the data stream is consistent */
885 int stream_valid_check(struct isal_zstream *stream, uint8_t * in_buf, uint32_t in_size,
886 		       uint8_t * out_buf, uint32_t out_size, uint32_t in_processed,
887 		       uint32_t out_processed, uint32_t data_size)
888 {
889 	uint32_t total_in, in_buffer_size, total_out, out_buffer_size;
890 
891 	total_in =
892 	    (in_size ==
893 	     0) ? in_processed : (in_processed - in_size) + (stream->next_in - in_buf);
894 	in_buffer_size = (in_size == 0) ? 0 : stream->next_in - in_buf + stream->avail_in;
895 
896 	/* Check for a consistent amount of data processed */
897 	if (total_in != stream->total_in || in_buffer_size != in_size)
898 		return COMPRESS_INPUT_STREAM_INTEGRITY_ERROR;
899 
900 	total_out =
901 	    (out_size == 0) ? out_processed : out_processed + (stream->next_out - out_buf);
902 	out_buffer_size = (out_size == 0) ? 0 : stream->next_out - out_buf + stream->avail_out;
903 
904 	/* Check for a consistent amount of data compressed */
905 	if (total_out != stream->total_out || out_buffer_size != out_size) {
906 		return COMPRESS_OUTPUT_STREAM_INTEGRITY_ERROR;
907 	}
908 
909 	return 0;
910 }
911 
912 /* Performs compression with checks to discover and verify the state of the
913  * stream
914  * stream: compress data structure which has been initialized to use
915  * in_buf and out_buf as the buffers
916  * data_size: size of all input data
917  * compressed_size: size of all available output buffers
918  * in_buf: next buffer of data to be compressed
919  * in_size: size of in_buf
920  * out_buf: next out put buffer where data is stored
921  * out_size: size of out_buf
922  * in_processed: the amount of input data which has been loaded into buffers
923  * to be compressed, this includes the data in in_buf
924  * out_processed: the amount of output data which has been compressed and stored,
925  * this does not include the data in the current out_buf
926 */
927 int isal_deflate_with_checks(struct isal_zstream *stream, uint32_t data_size,
928 			     uint32_t compressed_size, uint8_t * in_buf, uint32_t in_size,
929 			     uint32_t in_processed, uint8_t * out_buf, uint32_t out_size,
930 			     uint32_t out_processed)
931 {
932 	int ret, stream_check;
933 	struct isal_zstate *state = &stream->internal_state;
934 
935 #ifdef VERBOSE
936 	printf("Pre compression\n");
937 	printf
938 	    ("data_size       = 0x%05x, in_processed  = 0x%05x, in_size  = 0x%05x, avail_in  = 0x%05x, total_in  = 0x%05x\n",
939 	     data_size, in_processed, in_size, stream->avail_in, stream->total_in);
940 	printf
941 	    ("compressed_size = 0x%05x, out_processed = 0x%05x, out_size = 0x%05x, avail_out = 0x%05x, total_out = 0x%05x\n",
942 	     compressed_size, out_processed, out_size, stream->avail_out, stream->total_out);
943 #endif
944 
945 	ret = isal_deflate(stream);
946 
947 #ifdef VERBOSE
948 	printf("Post compression\n");
949 	printf
950 	    ("data_size       = 0x%05x, in_processed  = 0x%05x, in_size  = 0x%05x, avail_in  = 0x%05x, total_in  = 0x%05x\n",
951 	     data_size, in_processed, in_size, stream->avail_in, stream->total_in);
952 	printf
953 	    ("compressed_size = 0x%05x, out_processed = 0x%05x, out_size = 0x%05x, avail_out = 0x%05x, total_out = 0x%05x\n",
954 	     compressed_size, out_processed, out_size, stream->avail_out, stream->total_out);
955 	printf("\n\n");
956 #endif
957 
958 	/* Verify the stream is in a valid state */
959 	stream_check = stream_valid_check(stream, in_buf, in_size, out_buf, out_size,
960 					  in_processed, out_processed, data_size);
961 
962 	if (stream_check != 0)
963 		return stream_check;
964 
965 	if (ret != IGZIP_COMP_OK)
966 		return COMPRESS_GENERAL_ERROR;
967 
968 	/* Check if the compression is completed */
969 	if (state->state != ZSTATE_END)
970 		if (compressed_size - out_processed - (out_size - stream->avail_out) <= 0)
971 			return COMPRESS_OUT_BUFFER_OVERFLOW;
972 
973 	return ret;
974 
975 }
976 
977 void set_random_hufftable(struct isal_zstream *stream, int level, uint8_t * data,
978 			  uint32_t data_size)
979 {
980 	struct isal_hufftables *huff = hufftables;
981 	struct isal_huff_histogram hist;
982 	if (level == 0 || rand() % 16 == 0) {
983 		if (rand() % 8 == 0) {
984 			huff = hufftables_subset;
985 			memset(&hist, 0, sizeof(hist));
986 			isal_update_histogram(data, data_size, &hist);
987 			isal_create_hufftables_subset(huff, &hist);
988 		}
989 
990 		isal_deflate_set_hufftables(stream, huff, rand() % 4);
991 	}
992 }
993 
994 /* Compress the input data into the output buffer where the input buffer and
995  * output buffer are randomly segmented to test state information for the
996  * compression*/
997 int compress_multi_pass(uint8_t * data, uint32_t data_size, uint8_t * compressed_buf,
998 			uint32_t * compressed_size, uint32_t flush_type, uint32_t gzip_flag,
999 			uint32_t level, uint8_t * dict, uint32_t dict_len, uint32_t hist_bits)
1000 {
1001 	int ret = IGZIP_COMP_OK;
1002 	uint8_t *in_buf = NULL, *out_buf = NULL;
1003 	uint32_t in_size = 0, out_size = 0;
1004 	uint32_t in_processed = 0, out_processed = 0;
1005 	struct isal_zstream *stream;
1006 	struct isal_zstate *state;
1007 	uint32_t loop_count = 0;
1008 	uint32_t level_buf_size;
1009 	uint8_t *level_buf = NULL;
1010 	struct isal_hufftables *huff_tmp;
1011 	uint32_t reset_test_flag = 0;
1012 	uint8_t tmp_symbol;
1013 	int no_mod = 0;
1014 
1015 #ifdef VERBOSE
1016 	printf("Starting Compress Multi Pass\n");
1017 #endif
1018 
1019 	stream = malloc(sizeof(*stream));
1020 	if (stream == NULL)
1021 		return MALLOC_FAILED;
1022 	state = &stream->internal_state;
1023 
1024 	create_rand_repeat_data((uint8_t *) stream, sizeof(*stream));
1025 
1026 	isal_deflate_init(stream);
1027 
1028 	if (state->state != ZSTATE_NEW_HDR)
1029 		return COMPRESS_INCORRECT_STATE;
1030 
1031 	if (rand() % 4 == 0) {
1032 		/* Test reset */
1033 		reset_test_flag = 1;
1034 		huff_tmp = stream->hufftables;
1035 		create_rand_repeat_data((uint8_t *) stream, sizeof(*stream));
1036 
1037 		/* Restore variables not necessarily set by user */
1038 		stream->hufftables = huff_tmp;
1039 		stream->end_of_stream = 0;
1040 		stream->level = 0;
1041 		stream->level_buf = NULL;
1042 		stream->level_buf_size = 0;
1043 	}
1044 
1045 	stream->flush = flush_type;
1046 	stream->end_of_stream = 0;
1047 
1048 	/* These are set here to allow the loop to run correctly */
1049 	stream->avail_in = 0;
1050 	stream->avail_out = 0;
1051 	stream->gzip_flag = gzip_flag;
1052 	stream->level = level;
1053 	stream->hist_bits = hist_bits;
1054 
1055 	if (level >= 1) {
1056 		level_buf_size = get_rand_level_buf_size(stream->level);
1057 		level_buf = malloc(level_buf_size);
1058 		create_rand_repeat_data(level_buf, level_buf_size);
1059 		stream->level_buf = level_buf;
1060 		stream->level_buf_size = level_buf_size;
1061 	}
1062 
1063 	if (reset_test_flag)
1064 		isal_deflate_reset(stream);
1065 
1066 	if (dict != NULL)
1067 		isal_deflate_set_dict(stream, dict, dict_len);
1068 
1069 	while (1) {
1070 		loop_count++;
1071 
1072 		/* Setup in buffer for next round of compression */
1073 		if (stream->avail_in == 0) {
1074 			if (flush_type == NO_FLUSH || state->state == ZSTATE_NEW_HDR) {
1075 				/* Randomly choose size of the next out buffer */
1076 				in_size = rand() % (data_size + 1);
1077 
1078 				/* Limit size of buffer to be smaller than maximum */
1079 				if (in_size >= data_size - in_processed) {
1080 					in_size = data_size - in_processed;
1081 					stream->end_of_stream = 1;
1082 				}
1083 
1084 				if (in_size != 0) {
1085 					if (in_buf != NULL) {
1086 						free(in_buf);
1087 						in_buf = NULL;
1088 					}
1089 
1090 					in_buf = malloc(in_size);
1091 					if (in_buf == NULL) {
1092 						ret = MALLOC_FAILED;
1093 						break;
1094 					}
1095 					memcpy(in_buf, data + in_processed, in_size);
1096 					in_processed += in_size;
1097 
1098 					stream->avail_in = in_size;
1099 					stream->next_in = in_buf;
1100 				}
1101 			}
1102 		} else {
1103 			/* Randomly modify data after next in */
1104 			if (rand() % 4 == 0 && !no_mod) {
1105 
1106 				tmp_symbol = rand();
1107 #ifdef VERBOSE
1108 				printf
1109 				    ("Modifying data at index 0x%x from 0x%x to 0x%x before recalling isal_deflate\n",
1110 				     in_processed - stream->avail_in,
1111 				     data[in_processed - stream->avail_in], tmp_symbol);
1112 #endif
1113 				*stream->next_in = tmp_symbol;
1114 				data[in_processed - stream->avail_in] = tmp_symbol;
1115 			}
1116 		}
1117 
1118 		/* Setup out buffer for next round of compression */
1119 		if (stream->avail_out == 0) {
1120 			/* Save compressed data inot compressed_buf */
1121 			if (out_buf != NULL) {
1122 				memcpy(compressed_buf + out_processed, out_buf,
1123 				       out_size - stream->avail_out);
1124 				out_processed += out_size - stream->avail_out;
1125 			}
1126 
1127 			/* Randomly choose size of the next out buffer */
1128 			out_size = rand() % (*compressed_size + 1);
1129 
1130 			/* Limit size of buffer to be smaller than maximum */
1131 			if (out_size > *compressed_size - out_processed)
1132 				out_size = *compressed_size - out_processed;
1133 
1134 			if (out_size != 0) {
1135 				if (out_buf != NULL) {
1136 					free(out_buf);
1137 					out_buf = NULL;
1138 				}
1139 
1140 				out_buf = malloc(out_size);
1141 				if (out_buf == NULL) {
1142 					ret = MALLOC_FAILED;
1143 					break;
1144 				}
1145 
1146 				stream->avail_out = out_size;
1147 				stream->next_out = out_buf;
1148 			}
1149 		}
1150 
1151 		if (state->state == ZSTATE_NEW_HDR) {
1152 			set_random_hufftable(stream, level, data, data_size);
1153 			if (stream->hufftables == hufftables_subset)
1154 				no_mod = 1;
1155 			else
1156 				no_mod = 0;
1157 		}
1158 
1159 		ret =
1160 		    isal_deflate_with_checks(stream, data_size, *compressed_size, in_buf,
1161 					     in_size, in_processed, out_buf, out_size,
1162 					     out_processed);
1163 
1164 		if (ret) {
1165 			if (ret == COMPRESS_OUT_BUFFER_OVERFLOW
1166 			    || ret == COMPRESS_INCORRECT_STATE)
1167 				memcpy(compressed_buf + out_processed, out_buf, out_size);
1168 			break;
1169 		}
1170 
1171 		/* Check if the compression is completed */
1172 		if (state->state == ZSTATE_END) {
1173 			memcpy(compressed_buf + out_processed, out_buf, out_size);
1174 			*compressed_size = stream->total_out;
1175 			break;
1176 		}
1177 
1178 	}
1179 
1180 	if (stream != NULL)
1181 		free(stream);
1182 	if (level_buf != NULL)
1183 		free(level_buf);
1184 	if (in_buf != NULL)
1185 		free(in_buf);
1186 	if (out_buf != NULL)
1187 		free(out_buf);
1188 
1189 	if (ret == COMPRESS_OUT_BUFFER_OVERFLOW && flush_type == SYNC_FLUSH
1190 	    && loop_count >= MAX_LOOPS)
1191 		ret = COMPRESS_LOOP_COUNT_OVERFLOW;
1192 
1193 	return ret;
1194 
1195 }
1196 
1197 /* Compress the input data into the outbuffer in one call to isal_deflate */
1198 int compress_single_pass(uint8_t * data, uint32_t data_size, uint8_t * compressed_buf,
1199 			 uint32_t * compressed_size, uint32_t flush_type, uint32_t gzip_flag,
1200 			 uint32_t level, uint8_t * dict, uint32_t dict_len, uint32_t hist_bits)
1201 {
1202 	int ret = IGZIP_COMP_OK;
1203 	struct isal_zstream stream;
1204 	struct isal_zstate *state = &stream.internal_state;
1205 	uint32_t level_buf_size;
1206 	uint8_t *level_buf = NULL;
1207 	struct isal_hufftables *huff_tmp;
1208 	uint32_t reset_test_flag = 0;
1209 
1210 #ifdef VERBOSE
1211 	printf("Starting Compress Single Pass\n");
1212 #endif
1213 
1214 	create_rand_repeat_data((uint8_t *) & stream, sizeof(stream));
1215 
1216 	isal_deflate_init(&stream);
1217 
1218 	set_random_hufftable(&stream, level, data, data_size);
1219 
1220 	if (state->state != ZSTATE_NEW_HDR)
1221 		return COMPRESS_INCORRECT_STATE;
1222 
1223 	if (rand() % 4 == 0) {
1224 		/* Test reset */
1225 		reset_test_flag = 1;
1226 		huff_tmp = stream.hufftables;
1227 		create_rand_repeat_data((uint8_t *) & stream, sizeof(stream));
1228 
1229 		/* Restore variables not necessarily set by user */
1230 		stream.hufftables = huff_tmp;
1231 		stream.end_of_stream = 0;
1232 		stream.level = 0;
1233 		stream.level_buf = NULL;
1234 		stream.level_buf_size = 0;
1235 	}
1236 
1237 	stream.flush = flush_type;
1238 	stream.avail_in = data_size;
1239 	stream.next_in = data;
1240 	stream.avail_out = *compressed_size;
1241 	stream.next_out = compressed_buf;
1242 	stream.end_of_stream = 1;
1243 	stream.gzip_flag = gzip_flag;
1244 	stream.level = level;
1245 	stream.hist_bits = hist_bits;
1246 
1247 	if (level >= 1) {
1248 		level_buf_size = get_rand_level_buf_size(stream.level);
1249 		level_buf = malloc(level_buf_size);
1250 		create_rand_repeat_data(level_buf, level_buf_size);
1251 		stream.level_buf = level_buf;
1252 		stream.level_buf_size = level_buf_size;
1253 	}
1254 
1255 	if (reset_test_flag)
1256 		isal_deflate_reset(&stream);
1257 
1258 	if (dict != NULL)
1259 		isal_deflate_set_dict(&stream, dict, dict_len);
1260 
1261 	ret =
1262 	    isal_deflate_with_checks(&stream, data_size, *compressed_size, data, data_size,
1263 				     data_size, compressed_buf, *compressed_size, 0);
1264 
1265 	if (level_buf != NULL)
1266 		free(level_buf);
1267 
1268 	/* Check if the compression is completed */
1269 	if (state->state == ZSTATE_END)
1270 		*compressed_size = stream.total_out;
1271 	else if (flush_type == SYNC_FLUSH && stream.avail_out < 16)
1272 		ret = COMPRESS_OUT_BUFFER_OVERFLOW;
1273 
1274 	return ret;
1275 
1276 }
1277 
1278 /* Compress the input data repeatedly into the outbuffer
1279  * Compresses and verifies in place to decrease memory usage
1280  */
1281 int compress_ver_rep_buf(uint8_t * data, uint32_t data_size, uint64_t data_rep_size,
1282 			 uint8_t * compressed_buf, uint32_t compressed_size,
1283 			 uint8_t * decomp_buf, uint32_t decomp_buf_size, uint32_t flush_type,
1284 			 uint32_t gzip_flag, uint32_t level)
1285 {
1286 	int ret = IGZIP_COMP_OK;
1287 	struct isal_zstream stream;
1288 	struct inflate_state state;
1289 	uint32_t level_buf_size;
1290 	uint8_t *level_buf = NULL;
1291 	uint64_t data_remaining = data_rep_size;
1292 	uint64_t data_verified = 0;
1293 	uint32_t index;
1294 	uint32_t out_size, cmp_size;
1295 	uint32_t avail_out_start;
1296 
1297 #ifdef VERBOSE
1298 	printf("Starting Compress and Verify Repeated Buffer\n");
1299 #endif
1300 	create_rand_repeat_data((uint8_t *) & stream, sizeof(stream));
1301 
1302 	/* Setup compression stream */
1303 	isal_deflate_init(&stream);
1304 	stream.avail_in = 0;
1305 	stream.next_in = NULL;
1306 	stream.avail_out = 0;
1307 	stream.next_out = NULL;
1308 
1309 	set_random_hufftable(&stream, level, data, data_size);
1310 	stream.flush = flush_type;
1311 	stream.end_of_stream = 0;
1312 	stream.gzip_flag = gzip_flag;
1313 	stream.level = level;
1314 
1315 	if (level >= 1) {
1316 		level_buf_size = get_rand_level_buf_size(stream.level);
1317 		level_buf = malloc(level_buf_size);
1318 		create_rand_repeat_data(level_buf, level_buf_size);
1319 		stream.level_buf = level_buf;
1320 		stream.level_buf_size = level_buf_size;
1321 	}
1322 
1323 	/* Setup decompression stream */
1324 	create_rand_repeat_data((uint8_t *) & state, sizeof(state));
1325 	isal_inflate_init(&state);
1326 	state.crc_flag = gzip_flag;
1327 
1328 	while (data_remaining || stream.avail_in) {
1329 		/* Compress the input buffer */
1330 		if (stream.next_out == NULL) {
1331 			stream.avail_out = compressed_size;
1332 			stream.next_out = compressed_buf;
1333 		}
1334 
1335 		while (stream.avail_out > 0 && (data_remaining || stream.avail_in)) {
1336 			if (stream.avail_in == 0) {
1337 				stream.avail_in = data_size;
1338 				if (data_size >= data_remaining) {
1339 					stream.avail_in = data_remaining;
1340 					stream.end_of_stream = 1;
1341 				}
1342 
1343 				stream.next_in = data;
1344 				data_remaining -= stream.avail_in;
1345 			}
1346 
1347 			ret = isal_deflate(&stream);
1348 
1349 			if (ret)
1350 				return COMPRESS_GENERAL_ERROR;
1351 		}
1352 
1353 		/* Verfiy the compressed buffer */
1354 		state.next_in = compressed_buf;
1355 		state.avail_in = compressed_size;
1356 		state.next_out = NULL;
1357 		state.avail_out = 0;
1358 		create_rand_repeat_data(decomp_buf, decomp_buf_size);
1359 
1360 		while (state.avail_out == 0) {
1361 			state.next_out = decomp_buf;
1362 			state.avail_out = decomp_buf_size;
1363 
1364 			/* Force decoding to stop when avail_out rolls over */
1365 			if ((1ULL << 32) - state.total_out < decomp_buf_size)
1366 				state.avail_out = (1ULL << 32) - state.total_out;
1367 
1368 			avail_out_start = state.avail_out;
1369 
1370 			ret = isal_inflate(&state);
1371 			if (ret)
1372 				return inflate_ret_to_code(ret);
1373 
1374 			/* Check data accuracy */
1375 			index = data_verified % data_size;
1376 			out_size = avail_out_start - state.avail_out;
1377 			cmp_size =
1378 			    (out_size > data_size - index) ? data_size - index : out_size;
1379 			ret |= memcmp(decomp_buf, data + index, cmp_size);
1380 			out_size -= cmp_size;
1381 			cmp_size = (out_size > index) ? index : out_size;
1382 			ret |= memcmp(decomp_buf + data_size - index, data, cmp_size);
1383 			out_size -= cmp_size;
1384 			cmp_size = out_size;
1385 			ret |= memcmp(decomp_buf, decomp_buf + data_size, out_size);
1386 			if (ret)
1387 				return RESULT_ERROR;
1388 
1389 			data_verified += avail_out_start - state.avail_out;
1390 		}
1391 		stream.next_out = NULL;
1392 	}
1393 
1394 	if (level_buf != NULL)
1395 		free(level_buf);
1396 
1397 	return ret;
1398 
1399 }
1400 
1401 /* Statelessly compress the input buffer into the output buffer */
1402 int compress_stateless(uint8_t * data, uint32_t data_size, uint8_t * compressed_buf,
1403 		       uint32_t * compressed_size, uint32_t flush_type, uint32_t gzip_flag,
1404 		       uint32_t level, uint32_t hist_bits)
1405 {
1406 	int ret = IGZIP_COMP_OK;
1407 	struct isal_zstream stream;
1408 	uint32_t level_buf_size;
1409 	uint8_t *level_buf = NULL;
1410 	struct isal_hufftables *huff_tmp;
1411 	uint32_t reset_test_flag = 0;
1412 
1413 	create_rand_repeat_data((uint8_t *) & stream, sizeof(stream));
1414 
1415 	isal_deflate_stateless_init(&stream);
1416 
1417 	set_random_hufftable(&stream, level, data, data_size);
1418 
1419 	if (rand() % 4 == 0) {
1420 		/* Test reset */
1421 		reset_test_flag = 1;
1422 		huff_tmp = stream.hufftables;
1423 		create_rand_repeat_data((uint8_t *) & stream, sizeof(stream));
1424 
1425 		/* Restore variables not necessarily set by user */
1426 		stream.hufftables = huff_tmp;
1427 		stream.end_of_stream = 0;
1428 		stream.level = 0;
1429 		stream.level_buf = NULL;
1430 		stream.level_buf_size = 0;
1431 	}
1432 
1433 	stream.avail_in = data_size;
1434 	stream.next_in = data;
1435 	stream.flush = flush_type;
1436 	if (flush_type != NO_FLUSH)
1437 		stream.end_of_stream = 1;
1438 	stream.avail_out = *compressed_size;
1439 	stream.next_out = compressed_buf;
1440 	stream.gzip_flag = gzip_flag;
1441 	stream.level = level;
1442 	stream.hist_bits = hist_bits;
1443 
1444 	if (level == 1) {
1445 		/* This is to test case where level buf uses already existing
1446 		 * internal buffers */
1447 		level_buf_size = rand() % IBUF_SIZE;
1448 
1449 		if (level_buf_size >= ISAL_DEF_LVL1_MIN) {
1450 			level_buf = malloc(level_buf_size);
1451 			create_rand_repeat_data(level_buf, level_buf_size);
1452 			stream.level_buf = level_buf;
1453 			stream.level_buf_size = level_buf_size;
1454 		}
1455 	} else if (level > 1) {
1456 		level_buf_size = get_rand_level_buf_size(level);
1457 		level_buf = malloc(level_buf_size);
1458 		create_rand_repeat_data(level_buf, level_buf_size);
1459 		stream.level_buf = level_buf;
1460 		stream.level_buf_size = level_buf_size;
1461 	}
1462 
1463 	if (reset_test_flag)
1464 		isal_deflate_reset(&stream);
1465 
1466 	ret = isal_deflate_stateless(&stream);
1467 
1468 	if (level_buf != NULL)
1469 		free(level_buf);
1470 
1471 	/* verify the stream */
1472 	if (stream.next_in - data != stream.total_in ||
1473 	    stream.total_in + stream.avail_in != data_size)
1474 		return COMPRESS_INPUT_STREAM_INTEGRITY_ERROR;
1475 
1476 	if (stream.next_out - compressed_buf != stream.total_out ||
1477 	    stream.total_out + stream.avail_out != *compressed_size) {
1478 		return COMPRESS_OUTPUT_STREAM_INTEGRITY_ERROR;
1479 	}
1480 
1481 	if (ret != IGZIP_COMP_OK) {
1482 		if (ret == STATELESS_OVERFLOW)
1483 			return COMPRESS_OUT_BUFFER_OVERFLOW;
1484 		else if (ret == INVALID_FLUSH)
1485 			return INVALID_FLUSH_ERROR;
1486 		else {
1487 			printf("Return due to ret = %d with level = %d or %d\n", ret, level,
1488 			       stream.level);
1489 			return COMPRESS_GENERAL_ERROR;
1490 		}
1491 	}
1492 
1493 	if (!stream.end_of_stream) {
1494 		return COMPRESS_END_OF_STREAM_NOT_SET;
1495 	}
1496 
1497 	if (stream.avail_in != 0)
1498 		return COMPRESS_ALL_INPUT_FAIL;
1499 
1500 	*compressed_size = stream.total_out;
1501 
1502 	return ret;
1503 
1504 }
1505 
1506 /* Statelessly compress the input buffer into the output buffer */
1507 int compress_stateless_full_flush(uint8_t * data, uint32_t data_size, uint8_t * compressed_buf,
1508 				  uint32_t * compressed_size, uint32_t level,
1509 				  uint32_t hist_bits)
1510 {
1511 	int ret = IGZIP_COMP_OK;
1512 	uint8_t *in_buf = NULL, *level_buf = NULL, *out_buf = compressed_buf;
1513 	uint32_t in_size = 0, level_buf_size;
1514 	uint32_t in_processed = 00;
1515 	struct isal_zstream stream;
1516 	uint32_t loop_count = 0;
1517 	struct isal_hufftables *huff_tmp;
1518 	uint32_t reset_test_flag = 0;
1519 
1520 #ifdef VERBOSE
1521 	printf("Starting Stateless Compress Full Flush\n");
1522 #endif
1523 
1524 	create_rand_repeat_data((uint8_t *) & stream, sizeof(stream));
1525 
1526 	isal_deflate_stateless_init(&stream);
1527 
1528 	if (rand() % 4 == 0) {
1529 		/* Test reset */
1530 		reset_test_flag = 1;
1531 		huff_tmp = stream.hufftables;
1532 		create_rand_repeat_data((uint8_t *) & stream, sizeof(stream));
1533 
1534 		/* Restore variables not necessarily set by user */
1535 		stream.hufftables = huff_tmp;
1536 		stream.end_of_stream = 0;
1537 		stream.level = 0;
1538 		stream.level_buf = NULL;
1539 		stream.level_buf_size = 0;
1540 		stream.gzip_flag = 0;
1541 	}
1542 
1543 	stream.flush = FULL_FLUSH;
1544 	stream.end_of_stream = 0;
1545 	stream.avail_out = *compressed_size;
1546 	stream.next_out = compressed_buf;
1547 	stream.level = level;
1548 	stream.hist_bits = hist_bits;
1549 
1550 	if (level == 1) {
1551 		/* This is to test case where level_buf uses already existing
1552 		 * internal buffers */
1553 		level_buf_size = rand() % IBUF_SIZE;
1554 
1555 		if (level_buf_size >= ISAL_DEF_LVL1_MIN) {
1556 			level_buf = malloc(level_buf_size);
1557 			create_rand_repeat_data(level_buf, level_buf_size);
1558 			stream.level_buf = level_buf;
1559 			stream.level_buf_size = level_buf_size;
1560 		}
1561 	} else if (level > 1) {
1562 		level_buf_size = get_rand_level_buf_size(level);
1563 		level_buf = malloc(level_buf_size);
1564 		create_rand_repeat_data(level_buf, level_buf_size);
1565 		stream.level_buf = level_buf;
1566 		stream.level_buf_size = level_buf_size;
1567 	}
1568 
1569 	if (reset_test_flag)
1570 		isal_deflate_reset(&stream);
1571 
1572 	while (1) {
1573 		loop_count++;
1574 
1575 		/* Randomly choose size of the next out buffer */
1576 		in_size = rand() % (data_size + 1);
1577 
1578 		/* Limit size of buffer to be smaller than maximum */
1579 		if (in_size >= data_size - in_processed) {
1580 			in_size = data_size - in_processed;
1581 			stream.end_of_stream = 1;
1582 		}
1583 
1584 		stream.avail_in = in_size;
1585 
1586 		if (in_size != 0) {
1587 			if (in_buf != NULL) {
1588 				free(in_buf);
1589 				in_buf = NULL;
1590 			}
1591 
1592 			in_buf = malloc(in_size);
1593 			if (in_buf == NULL) {
1594 				ret = MALLOC_FAILED;
1595 				break;
1596 			}
1597 			memcpy(in_buf, data + in_processed, in_size);
1598 			in_processed += in_size;
1599 
1600 			stream.next_in = in_buf;
1601 		}
1602 
1603 		out_buf = stream.next_out;
1604 
1605 		if (stream.internal_state.state == ZSTATE_NEW_HDR)
1606 			set_random_hufftable(&stream, level, data, data_size);
1607 
1608 		ret = isal_deflate_stateless(&stream);
1609 
1610 		assert(stream.internal_state.bitbuf.m_bit_count == 0);
1611 
1612 		assert(compressed_buf == stream.next_out - stream.total_out);
1613 		if (ret)
1614 			break;
1615 
1616 		/* Verify that blocks are independent */
1617 		ret =
1618 		    inflate_check(out_buf, stream.next_out - out_buf, in_buf, in_size, 0, NULL,
1619 				  0, hist_bits);
1620 
1621 		if (ret == INFLATE_INVALID_LOOK_BACK_DISTANCE) {
1622 			break;
1623 		} else
1624 			ret = 0;
1625 
1626 		/* Check if the compression is completed */
1627 		if (in_processed == data_size) {
1628 			*compressed_size = stream.total_out;
1629 			break;
1630 		}
1631 
1632 	}
1633 
1634 	if (level_buf != NULL)
1635 		free(level_buf);
1636 
1637 	if (in_buf != NULL)
1638 		free(in_buf);
1639 
1640 	if (ret == STATELESS_OVERFLOW && loop_count >= MAX_LOOPS)
1641 		ret = COMPRESS_LOOP_COUNT_OVERFLOW;
1642 
1643 	return ret;
1644 
1645 }
1646 
1647 /* Compress the input data into the output buffer where the input buffer and
1648  * is randomly segmented to test for independence of blocks in full flush
1649  * compression*/
1650 int compress_full_flush(uint8_t * data, uint32_t data_size, uint8_t * compressed_buf,
1651 			uint32_t * compressed_size, uint32_t gzip_flag, uint32_t level)
1652 {
1653 	int ret = IGZIP_COMP_OK;
1654 	uint8_t *in_buf = NULL, *out_buf = compressed_buf, *level_buf = NULL;
1655 	uint32_t in_size = 0, level_buf_size;
1656 	uint32_t in_processed = 00;
1657 	struct isal_zstream stream;
1658 	struct isal_zstate *state = &stream.internal_state;
1659 	uint32_t loop_count = 0;
1660 	struct isal_hufftables *huff_tmp;
1661 	uint32_t reset_test_flag = 0;
1662 
1663 #ifdef VERBOSE
1664 	printf("Starting Compress Full Flush\n");
1665 #endif
1666 
1667 	create_rand_repeat_data((uint8_t *) & stream, sizeof(stream));
1668 
1669 	isal_deflate_init(&stream);
1670 
1671 	if (state->state != ZSTATE_NEW_HDR)
1672 		return COMPRESS_INCORRECT_STATE;
1673 
1674 	if (rand() % 4 == 0) {
1675 		/* Test reset */
1676 		reset_test_flag = 1;
1677 		huff_tmp = stream.hufftables;
1678 		create_rand_repeat_data((uint8_t *) & stream, sizeof(stream));
1679 
1680 		/* Restore variables not necessarily set by user */
1681 		stream.hufftables = huff_tmp;
1682 		stream.end_of_stream = 0;
1683 		stream.level = 0;
1684 		stream.level_buf = NULL;
1685 		stream.level_buf_size = 0;
1686 		stream.hist_bits = 0;
1687 	}
1688 
1689 	stream.flush = FULL_FLUSH;
1690 	stream.end_of_stream = 0;
1691 	stream.avail_out = *compressed_size;
1692 	stream.next_out = compressed_buf;
1693 	stream.total_out = 0;
1694 	stream.gzip_flag = gzip_flag;
1695 	stream.level = level;
1696 
1697 	if (level >= 1) {
1698 		level_buf_size = get_rand_level_buf_size(stream.level);
1699 		if (level_buf_size >= ISAL_DEF_LVL1_MIN) {
1700 			level_buf = malloc(level_buf_size);
1701 			create_rand_repeat_data(level_buf, level_buf_size);
1702 			stream.level_buf = level_buf;
1703 			stream.level_buf_size = level_buf_size;
1704 		}
1705 	}
1706 
1707 	if (reset_test_flag)
1708 		isal_deflate_reset(&stream);
1709 
1710 	while (1) {
1711 		loop_count++;
1712 
1713 		/* Setup in buffer for next round of compression */
1714 		if (state->state == ZSTATE_NEW_HDR) {
1715 			/* Randomly choose size of the next out buffer */
1716 			in_size = rand() % (data_size + 1);
1717 
1718 			/* Limit size of buffer to be smaller than maximum */
1719 			if (in_size >= data_size - in_processed) {
1720 				in_size = data_size - in_processed;
1721 				stream.end_of_stream = 1;
1722 			}
1723 
1724 			stream.avail_in = in_size;
1725 
1726 			if (in_size != 0) {
1727 				if (in_buf != NULL) {
1728 					free(in_buf);
1729 					in_buf = NULL;
1730 				}
1731 
1732 				in_buf = malloc(in_size);
1733 				if (in_buf == NULL) {
1734 					ret = MALLOC_FAILED;
1735 					break;
1736 				}
1737 				memcpy(in_buf, data + in_processed, in_size);
1738 				in_processed += in_size;
1739 
1740 				stream.next_in = in_buf;
1741 			}
1742 
1743 			out_buf = stream.next_out;
1744 		}
1745 
1746 		if (state->state == ZSTATE_NEW_HDR)
1747 			set_random_hufftable(&stream, level, data, data_size);
1748 
1749 		ret = isal_deflate(&stream);
1750 
1751 		if (ret)
1752 			break;
1753 
1754 		/* Verify that blocks are independent */
1755 		if (state->state == ZSTATE_NEW_HDR || state->state == ZSTATE_END) {
1756 			ret =
1757 			    inflate_check(out_buf, stream.next_out - out_buf, in_buf, in_size,
1758 					  0, NULL, 0, 0);
1759 
1760 			if (ret == INFLATE_INVALID_LOOK_BACK_DISTANCE)
1761 				break;
1762 			else
1763 				ret = 0;
1764 		}
1765 
1766 		/* Check if the compression is completed */
1767 		if (state->state == ZSTATE_END) {
1768 			*compressed_size = stream.total_out;
1769 			break;
1770 		}
1771 
1772 	}
1773 
1774 	if (level_buf != NULL)
1775 		free(level_buf);
1776 
1777 	if (in_buf != NULL)
1778 		free(in_buf);
1779 
1780 	if (ret == COMPRESS_OUT_BUFFER_OVERFLOW && loop_count >= MAX_LOOPS)
1781 		ret = COMPRESS_LOOP_COUNT_OVERFLOW;
1782 
1783 	return ret;
1784 
1785 }
1786 
1787 /*Compress the input buffer into the output buffer, but switch the flush type in
1788  * the middle of the compression to test what happens*/
1789 int compress_swap_flush(uint8_t * data, uint32_t data_size, uint8_t * compressed_buf,
1790 			uint32_t * compressed_size, uint32_t flush_type, int level,
1791 			uint32_t gzip_flag)
1792 {
1793 	int ret = IGZIP_COMP_OK;
1794 	struct isal_zstream stream;
1795 	struct isal_zstate *state = &stream.internal_state;
1796 	uint32_t partial_size;
1797 	struct isal_hufftables *huff_tmp;
1798 	uint32_t reset_test_flag = 0;
1799 	uint32_t level_buf_size;
1800 	uint8_t *level_buf = NULL;
1801 
1802 #ifdef VERBOSE
1803 	printf("Starting Compress Swap Flush\n");
1804 #endif
1805 
1806 	isal_deflate_init(&stream);
1807 
1808 	set_random_hufftable(&stream, 0, data, data_size);
1809 
1810 	if (state->state != ZSTATE_NEW_HDR)
1811 		return COMPRESS_INCORRECT_STATE;
1812 
1813 	if (rand() % 4 == 0) {
1814 		/* Test reset */
1815 		reset_test_flag = 1;
1816 		huff_tmp = stream.hufftables;
1817 		create_rand_repeat_data((uint8_t *) & stream, sizeof(stream));
1818 
1819 		/* Restore variables not necessarily set by user */
1820 		stream.hufftables = huff_tmp;
1821 		stream.end_of_stream = 0;
1822 		stream.level = 0;
1823 		stream.level_buf = NULL;
1824 		stream.level_buf_size = 0;
1825 	}
1826 
1827 	partial_size = rand() % (data_size + 1);
1828 
1829 	stream.flush = flush_type;
1830 	stream.avail_in = partial_size;
1831 	stream.next_in = data;
1832 	stream.avail_out = *compressed_size;
1833 	stream.next_out = compressed_buf;
1834 	stream.end_of_stream = 0;
1835 	stream.gzip_flag = gzip_flag;
1836 	if (level) {
1837 		stream.level = level;
1838 		level_buf_size = get_rand_level_buf_size(stream.level);
1839 		level_buf = malloc(level_buf_size);
1840 		create_rand_repeat_data(level_buf, level_buf_size);
1841 		stream.level_buf = level_buf;
1842 		stream.level_buf_size = level_buf_size;
1843 	}
1844 
1845 	if (reset_test_flag)
1846 		isal_deflate_reset(&stream);
1847 
1848 	ret =
1849 	    isal_deflate_with_checks(&stream, data_size, *compressed_size, data, partial_size,
1850 				     partial_size, compressed_buf, *compressed_size, 0);
1851 
1852 	if (ret)
1853 		return ret;
1854 
1855 	if (state->state == ZSTATE_NEW_HDR)
1856 		set_random_hufftable(&stream, 0, data, data_size);
1857 
1858 	flush_type = rand() % 3;
1859 
1860 	stream.flush = flush_type;
1861 	stream.avail_in = data_size - partial_size;
1862 	stream.next_in = data + partial_size;
1863 	stream.end_of_stream = 1;
1864 
1865 	ret =
1866 	    isal_deflate_with_checks(&stream, data_size, *compressed_size, data + partial_size,
1867 				     data_size - partial_size, data_size, compressed_buf,
1868 				     *compressed_size, 0);
1869 
1870 	if (ret == COMPRESS_GENERAL_ERROR)
1871 		return INVALID_FLUSH_ERROR;
1872 
1873 	*compressed_size = stream.total_out;
1874 
1875 	if (stream.level_buf != NULL)
1876 		free(stream.level_buf);
1877 
1878 	return ret;
1879 }
1880 
1881 /* Test deflate_stateless */
1882 int test_compress_stateless(uint8_t * in_data, uint32_t in_size, uint32_t flush_type)
1883 {
1884 	int ret = IGZIP_COMP_OK;
1885 	uint32_t z_size, overflow, gzip_flag, level, hist_bits;
1886 	uint8_t *z_buf = NULL;
1887 	uint8_t *in_buf = NULL;
1888 
1889 	gzip_flag = rand() % 5;
1890 	hist_bits = rand() % 16;
1891 	level = get_rand_level();
1892 
1893 	if (in_size != 0) {
1894 		in_buf = malloc(in_size);
1895 
1896 		if (in_buf == NULL)
1897 			return MALLOC_FAILED;
1898 
1899 		memcpy(in_buf, in_data, in_size);
1900 	}
1901 
1902 	/* Test non-overflow case where a type 0 block is not written */
1903 	z_size = 2 * in_size + hdr_bytes;
1904 	if (gzip_flag == IGZIP_GZIP)
1905 		z_size += gzip_extra_bytes;
1906 	else if (gzip_flag == IGZIP_GZIP_NO_HDR)
1907 		z_size += gzip_trl_bytes;
1908 	else if (gzip_flag == IGZIP_ZLIB)
1909 		z_size += zlib_extra_bytes;
1910 	else if (gzip_flag == IGZIP_ZLIB_NO_HDR)
1911 		z_size += zlib_trl_bytes;
1912 
1913 	z_buf = malloc(z_size);
1914 
1915 	if (z_buf == NULL)
1916 		return MALLOC_FAILED;
1917 
1918 	create_rand_repeat_data(z_buf, z_size);
1919 
1920 	/* If flush type is invalid */
1921 	if (flush_type != NO_FLUSH && flush_type != FULL_FLUSH) {
1922 		ret =
1923 		    compress_stateless(in_buf, in_size, z_buf, &z_size, flush_type, gzip_flag,
1924 				       level, hist_bits);
1925 
1926 		if (ret != INVALID_FLUSH_ERROR)
1927 			print_error(ret);
1928 		else
1929 			ret = 0;
1930 
1931 		if (z_buf != NULL)
1932 			free(z_buf);
1933 
1934 		if (in_buf != NULL)
1935 			free(in_buf);
1936 
1937 		return ret;
1938 	}
1939 
1940 	/* Else test valid flush type */
1941 	ret = compress_stateless(in_buf, in_size, z_buf, &z_size, flush_type, gzip_flag, level,
1942 				 hist_bits);
1943 
1944 	if (!ret)
1945 		ret =
1946 		    inflate_check(z_buf, z_size, in_buf, in_size, gzip_flag, NULL, 0,
1947 				  hist_bits);
1948 
1949 #ifdef VERBOSE
1950 	if (ret) {
1951 		printf
1952 		    ("Compressed array at level %d with gzip flag %d, flush type %d, and window bits %d: ",
1953 		     level, gzip_flag, flush_type, hist_bits);
1954 		print_uint8_t(z_buf, z_size);
1955 		printf("\n");
1956 		printf("Data: ");
1957 		print_uint8_t(in_buf, in_size);
1958 	}
1959 #endif
1960 	if (z_buf != NULL) {
1961 		free(z_buf);
1962 		z_buf = NULL;
1963 	}
1964 
1965 	print_error(ret);
1966 	if (ret)
1967 		return ret;
1968 
1969 	/*Test non-overflow case where a type 0 block is possible to be written */
1970 	z_size = TYPE0_HDR_SIZE * ((in_size + TYPE0_MAX_SIZE - 1) / TYPE0_MAX_SIZE) + in_size;
1971 
1972 	if (gzip_flag == IGZIP_GZIP)
1973 		z_size += gzip_extra_bytes;
1974 	else if (gzip_flag == IGZIP_GZIP_NO_HDR)
1975 		z_size += gzip_trl_bytes;
1976 	else if (gzip_flag == IGZIP_ZLIB)
1977 		z_size += zlib_extra_bytes;
1978 	else if (gzip_flag == IGZIP_ZLIB_NO_HDR)
1979 		z_size += zlib_trl_bytes;
1980 
1981 	if (z_size <= gzip_extra_bytes)
1982 		z_size += TYPE0_HDR_SIZE;
1983 
1984 	if (z_size < 8)
1985 		z_size = 8;
1986 
1987 	z_buf = malloc(z_size);
1988 
1989 	if (z_buf == NULL)
1990 		return MALLOC_FAILED;
1991 
1992 	create_rand_repeat_data(z_buf, z_size);
1993 
1994 	ret = compress_stateless(in_buf, in_size, z_buf, &z_size, flush_type, gzip_flag, level,
1995 				 hist_bits);
1996 	if (!ret)
1997 		ret =
1998 		    inflate_check(z_buf, z_size, in_buf, in_size, gzip_flag, NULL, 0,
1999 				  hist_bits);
2000 #ifdef VERBOSE
2001 	if (ret) {
2002 		printf
2003 		    ("Compressed array at level %d with gzip flag %d, flush type %d, and hist_bits %d: ",
2004 		     level, gzip_flag, flush_type, hist_bits);
2005 		print_uint8_t(z_buf, z_size);
2006 		printf("\n");
2007 		printf("Data: ");
2008 		print_uint8_t(in_buf, in_size);
2009 	}
2010 #endif
2011 
2012 	if (!ret) {
2013 		free(z_buf);
2014 		z_buf = NULL;
2015 
2016 		/* Test random overflow case */
2017 		z_size = rand() % z_size;
2018 
2019 		if (z_size > in_size)
2020 			z_size = rand() & in_size;
2021 
2022 		if (z_size > 0) {
2023 			z_buf = malloc(z_size);
2024 
2025 			if (z_buf == NULL)
2026 				return MALLOC_FAILED;
2027 		}
2028 
2029 		overflow = compress_stateless(in_buf, in_size, z_buf, &z_size, flush_type,
2030 					      gzip_flag, level, hist_bits);
2031 
2032 		if (overflow != COMPRESS_OUT_BUFFER_OVERFLOW) {
2033 			if (overflow == 0)
2034 				ret =
2035 				    inflate_check(z_buf, z_size, in_buf, in_size, gzip_flag,
2036 						  NULL, 0, hist_bits);
2037 
2038 			if (overflow != 0 || ret != 0) {
2039 #ifdef VERBOSE
2040 				printf("overflow error = %d\n", overflow);
2041 				print_error(overflow);
2042 				printf("inflate ret = %d\n", ret);
2043 				print_error(overflow);
2044 
2045 				printf
2046 				    ("Compressed array at level %d with gzip flag %d, flush type %d, and hist_bits %d: ",
2047 				     level, gzip_flag, flush_type, hist_bits);
2048 
2049 				print_uint8_t(z_buf, z_size);
2050 				printf("\n");
2051 				printf("Data: ");
2052 				print_uint8_t(in_buf, in_size);
2053 #endif
2054 				printf("Failed on compress single pass overflow\n");
2055 				print_error(ret);
2056 				ret = OVERFLOW_TEST_ERROR;
2057 			}
2058 		}
2059 	}
2060 
2061 	print_error(ret);
2062 	if (ret) {
2063 		if (z_buf != NULL) {
2064 			free(z_buf);
2065 			z_buf = NULL;
2066 		}
2067 		if (in_buf != NULL)
2068 			free(in_buf);
2069 		return ret;
2070 	}
2071 
2072 	if (flush_type == FULL_FLUSH) {
2073 		if (z_buf != NULL)
2074 			free(z_buf);
2075 
2076 		z_size = 2 * in_size + MAX_LOOPS * (hdr_bytes + 5);
2077 
2078 		z_buf = malloc(z_size);
2079 
2080 		if (z_buf == NULL)
2081 			return MALLOC_FAILED;
2082 
2083 		create_rand_repeat_data(z_buf, z_size);
2084 
2085 		/* Else test valid flush type */
2086 		ret = compress_stateless_full_flush(in_buf, in_size, z_buf, &z_size,
2087 						    level, hist_bits);
2088 
2089 		if (!ret)
2090 			ret =
2091 			    inflate_check(z_buf, z_size, in_buf, in_size, 0, NULL, 0,
2092 					  hist_bits);
2093 		else if (ret == COMPRESS_LOOP_COUNT_OVERFLOW)
2094 			ret = 0;
2095 
2096 		print_error(ret);
2097 #ifdef VERBOSE
2098 		if (ret) {
2099 			printf
2100 			    ("Compressed array at level %d with gzip flag %d, flush type %d, and hist_bits %d: ",
2101 			     level, gzip_flag, FULL_FLUSH, hist_bits);
2102 			print_uint8_t(z_buf, z_size);
2103 			printf("\n");
2104 			printf("Data: ");
2105 			print_uint8_t(in_buf, in_size);
2106 		}
2107 #endif
2108 	}
2109 	if (z_buf != NULL)
2110 		free(z_buf);
2111 
2112 	if (in_buf != NULL)
2113 		free(in_buf);
2114 
2115 	return ret;
2116 }
2117 
2118 /* Test deflate */
2119 int test_compress(uint8_t * in_buf, uint32_t in_size, uint32_t flush_type)
2120 {
2121 	int ret = IGZIP_COMP_OK, fin_ret = IGZIP_COMP_OK;
2122 	uint32_t overflow = 0, gzip_flag, level, hist_bits;
2123 	uint32_t z_size = 0, z_size_max = 0, z_compressed_size, dict_len = 0;
2124 	uint8_t *z_buf = NULL, *dict = NULL;
2125 
2126 	/* Test a non overflow case */
2127 	if (flush_type == NO_FLUSH)
2128 		z_size_max = 2 * in_size + hdr_bytes + 2;
2129 	else if (flush_type == SYNC_FLUSH || flush_type == FULL_FLUSH)
2130 		z_size_max = 2 * in_size + MAX_LOOPS * (hdr_bytes + 5);
2131 	else {
2132 		printf("Invalid Flush Parameter\n");
2133 		return COMPRESS_GENERAL_ERROR;
2134 	}
2135 
2136 	gzip_flag = rand() % 5;
2137 	hist_bits = rand() % 16;
2138 	level = get_rand_level();
2139 
2140 	z_size = z_size_max;
2141 
2142 	if (gzip_flag == IGZIP_GZIP)
2143 		z_size += gzip_extra_bytes;
2144 	else if (gzip_flag == IGZIP_GZIP_NO_HDR)
2145 		z_size += gzip_trl_bytes;
2146 	else if (gzip_flag == IGZIP_ZLIB)
2147 		z_size += zlib_extra_bytes;
2148 	else if (gzip_flag == IGZIP_ZLIB_NO_HDR)
2149 		z_size += zlib_trl_bytes;
2150 
2151 	z_buf = malloc(z_size);
2152 	if (z_buf == NULL) {
2153 		print_error(MALLOC_FAILED);
2154 		return MALLOC_FAILED;
2155 	}
2156 	create_rand_repeat_data(z_buf, z_size);
2157 
2158 	if (rand() % 8 == 0) {
2159 		dict_len = (rand() % IGZIP_HIST_SIZE) + 1;
2160 		dict = malloc(dict_len);
2161 		if (dict == NULL) {
2162 			print_error(MALLOC_FAILED);
2163 			return MALLOC_FAILED;
2164 		}
2165 		create_rand_dict(dict, dict_len, z_buf, z_size);
2166 	}
2167 
2168 	ret = compress_single_pass(in_buf, in_size, z_buf, &z_size, flush_type,
2169 				   gzip_flag, level, dict, dict_len, hist_bits);
2170 
2171 	if (!ret)
2172 		ret =
2173 		    inflate_check(z_buf, z_size, in_buf, in_size, gzip_flag, dict, dict_len,
2174 				  hist_bits);
2175 
2176 	if (ret) {
2177 #ifdef VERBOSE
2178 		printf
2179 		    ("Compressed array at level %d with gzip flag %d, flush type %d, and hist_bits %d: ",
2180 		     level, gzip_flag, flush_type, hist_bits);
2181 		print_uint8_t(z_buf, z_size);
2182 		printf("\n");
2183 		if (dict != NULL) {
2184 			printf("Using Dictionary: ");
2185 			print_uint8_t(dict, dict_len);
2186 			printf("\n");
2187 		}
2188 		printf("Data: ");
2189 		print_uint8_t(in_buf, in_size);
2190 #endif
2191 		printf("Failed on compress single pass\n");
2192 		print_error(ret);
2193 	}
2194 
2195 	if (dict != NULL) {
2196 		free(dict);
2197 		dict = NULL;
2198 		dict_len = 0;
2199 	}
2200 
2201 	fin_ret |= ret;
2202 	if (ret)
2203 		goto test_compress_cleanup;
2204 
2205 	z_compressed_size = z_size;
2206 	z_size = z_size_max;
2207 	create_rand_repeat_data(z_buf, z_size_max);
2208 
2209 	if (rand() % 8 == 0) {
2210 		dict_len = (rand() % IGZIP_HIST_SIZE) + 1;
2211 		dict = malloc(dict_len);
2212 		if (dict == NULL) {
2213 			print_error(MALLOC_FAILED);
2214 			return MALLOC_FAILED;
2215 		}
2216 		create_rand_dict(dict, dict_len, z_buf, z_size);
2217 	}
2218 
2219 	ret =
2220 	    compress_multi_pass(in_buf, in_size, z_buf, &z_size, flush_type, gzip_flag, level,
2221 				dict, dict_len, hist_bits);
2222 
2223 	if (!ret)
2224 		ret =
2225 		    inflate_check(z_buf, z_size, in_buf, in_size, gzip_flag, dict, dict_len,
2226 				  hist_bits);
2227 
2228 	if (ret) {
2229 #ifdef VERBOSE
2230 		printf
2231 		    ("Compressed array at level %d with gzip flag %d, flush type %d and hist_bits %d: ",
2232 		     level, gzip_flag, flush_type, hist_bits);
2233 		print_uint8_t(z_buf, z_size);
2234 		printf("\n");
2235 		if (dict != NULL) {
2236 			printf("Using Dictionary: ");
2237 			print_uint8_t(dict, dict_len);
2238 			printf("\n");
2239 		}
2240 		printf("Data: ");
2241 		print_uint8_t(in_buf, in_size);
2242 #endif
2243 		printf("Failed on compress multi pass\n");
2244 		print_error(ret);
2245 	}
2246 
2247 	if (dict != NULL) {
2248 		free(dict);
2249 		dict = NULL;
2250 		dict_len = 0;
2251 	}
2252 
2253 	fin_ret |= ret;
2254 	if (ret)
2255 		goto test_compress_cleanup;
2256 
2257 	ret = 0;
2258 
2259 	/* Test random overflow case */
2260 	if (flush_type == SYNC_FLUSH && z_compressed_size > in_size)
2261 		z_compressed_size = in_size + 1;
2262 
2263 	z_size = rand() % z_compressed_size;
2264 	create_rand_repeat_data(z_buf, z_size);
2265 
2266 	overflow = compress_single_pass(in_buf, in_size, z_buf, &z_size, flush_type,
2267 					gzip_flag, level, dict, dict_len, hist_bits);
2268 
2269 	if (overflow != COMPRESS_OUT_BUFFER_OVERFLOW) {
2270 		if (overflow == 0)
2271 			ret =
2272 			    inflate_check(z_buf, z_size, in_buf, in_size, gzip_flag, dict,
2273 					  dict_len, hist_bits);
2274 
2275 		/* Rarely single pass overflow will compresses data
2276 		 * better than the initial run. This is to stop that
2277 		 * case from erroring. */
2278 		if (overflow != 0 || ret != 0) {
2279 #ifdef VERBOSE
2280 			printf("overflow error = %d\n", overflow);
2281 			print_error(overflow);
2282 			printf("inflate ret = %d\n", ret);
2283 			print_error(ret);
2284 
2285 			printf
2286 			    ("Compressed array at level %d with gzip flag %d, flush type %d, and hist_bits %d: ",
2287 			     level, gzip_flag, flush_type, hist_bits);
2288 			print_uint8_t(z_buf, z_size);
2289 			printf("\n");
2290 			printf("Data: ");
2291 			print_uint8_t(in_buf, in_size);
2292 #endif
2293 			printf("Failed on compress single pass overflow\n");
2294 			print_error(ret);
2295 			ret = OVERFLOW_TEST_ERROR;
2296 		}
2297 	}
2298 
2299 	fin_ret |= ret;
2300 	if (ret)
2301 		goto test_compress_cleanup;
2302 
2303 	if (flush_type == NO_FLUSH) {
2304 		create_rand_repeat_data(z_buf, z_size);
2305 
2306 		overflow =
2307 		    compress_multi_pass(in_buf, in_size, z_buf, &z_size, flush_type,
2308 					gzip_flag, level, dict, dict_len, hist_bits);
2309 
2310 		if (overflow != COMPRESS_OUT_BUFFER_OVERFLOW) {
2311 			if (overflow == 0)
2312 				ret =
2313 				    inflate_check(z_buf, z_size, in_buf, in_size, gzip_flag,
2314 						  dict, dict_len, hist_bits);
2315 
2316 			/* Rarely multi pass overflow will compresses data
2317 			 * better than the initial run. This is to stop that
2318 			 * case from erroring */
2319 			if (overflow != 0 || ret != 0) {
2320 #ifdef VERBOSE
2321 				printf("overflow error = %d\n", overflow);
2322 				print_error(overflow);
2323 				printf("inflate ret = %d\n", ret);
2324 				print_error(ret);
2325 				printf
2326 				    ("Compressed array at level %d with gzip flag %d, flush type %d, and hist_bits %d: ",
2327 				     level, gzip_flag, flush_type, hist_bits);
2328 				print_uint8_t(z_buf, z_size);
2329 				printf("\n");
2330 				printf("Data: ");
2331 				print_uint8_t(in_buf, in_size);
2332 #endif
2333 				printf("Failed on compress multi pass overflow\n");
2334 				print_error(ret);
2335 				ret = OVERFLOW_TEST_ERROR;
2336 			}
2337 		}
2338 		fin_ret |= ret;
2339 	}
2340 
2341       test_compress_cleanup:
2342 	free(z_buf);
2343 
2344 	return fin_ret;
2345 }
2346 
2347 /* Test swapping flush types in the middle of compression */
2348 int test_flush(uint8_t * in_buf, uint32_t in_size)
2349 {
2350 	int fin_ret = IGZIP_COMP_OK, ret;
2351 	uint32_t z_size, flush_type = 0, gzip_flag, level;
2352 	uint8_t *z_buf = NULL;
2353 
2354 	gzip_flag = rand() % 5;
2355 	level = get_rand_level();
2356 
2357 	z_size = 2 * in_size + 2 * hdr_bytes + 8;
2358 	if (gzip_flag == IGZIP_GZIP)
2359 		z_size += gzip_extra_bytes;
2360 	else if (gzip_flag == IGZIP_GZIP_NO_HDR)
2361 		z_size += gzip_trl_bytes;
2362 	else if (gzip_flag == IGZIP_ZLIB)
2363 		z_size += zlib_extra_bytes;
2364 	else if (gzip_flag == IGZIP_ZLIB_NO_HDR)
2365 		z_size += zlib_trl_bytes;
2366 
2367 	z_buf = malloc(z_size);
2368 
2369 	if (z_buf == NULL)
2370 		return MALLOC_FAILED;
2371 
2372 	create_rand_repeat_data(z_buf, z_size);
2373 
2374 	while (flush_type < 3)
2375 		flush_type = rand() & 0xFFFF;
2376 
2377 	/* Test invalid flush */
2378 	ret = compress_single_pass(in_buf, in_size, z_buf, &z_size, flush_type,
2379 				   gzip_flag, level, NULL, 0, 0);
2380 
2381 	if (ret == COMPRESS_GENERAL_ERROR)
2382 		ret = 0;
2383 	else {
2384 		printf("Failed when passing invalid flush parameter\n");
2385 		ret = INVALID_FLUSH_ERROR;
2386 	}
2387 
2388 	fin_ret |= ret;
2389 	print_error(ret);
2390 
2391 	create_rand_repeat_data(z_buf, z_size);
2392 
2393 	/* Test swapping flush type */
2394 	ret =
2395 	    compress_swap_flush(in_buf, in_size, z_buf, &z_size, rand() % 3, level, gzip_flag);
2396 
2397 	if (!ret)
2398 		ret = inflate_check(z_buf, z_size, in_buf, in_size, gzip_flag, NULL, 0, 0);
2399 
2400 	if (ret) {
2401 #ifdef VERBOSE
2402 		printf("Compressed array at level %d with gzip flag %d: ", level, gzip_flag);
2403 		print_uint8_t(z_buf, z_size);
2404 		printf("\n");
2405 		printf("Data: ");
2406 		print_uint8_t(in_buf, in_size);
2407 #endif
2408 		printf("Failed on swapping flush type\n");
2409 		print_error(ret);
2410 	}
2411 
2412 	fin_ret |= ret;
2413 	print_error(ret);
2414 
2415 	return fin_ret;
2416 }
2417 
2418 /* Test there are no length distance pairs across full flushes */
2419 int test_full_flush(uint8_t * in_buf, uint32_t in_size)
2420 {
2421 	int ret = IGZIP_COMP_OK;
2422 	uint32_t z_size, gzip_flag, level;
2423 	uint8_t *z_buf = NULL;
2424 
2425 	gzip_flag = rand() % 5;
2426 	level = get_rand_level();
2427 	z_size = 2 * in_size + MAX_LOOPS * (hdr_bytes + 5);
2428 
2429 	if (gzip_flag == IGZIP_GZIP)
2430 		z_size += gzip_extra_bytes;
2431 	else if (gzip_flag == IGZIP_GZIP_NO_HDR)
2432 		z_size += gzip_trl_bytes;
2433 	else if (gzip_flag == IGZIP_ZLIB)
2434 		z_size += zlib_extra_bytes;
2435 	else if (gzip_flag == IGZIP_ZLIB_NO_HDR)
2436 		z_size += zlib_trl_bytes;
2437 
2438 	z_buf = malloc(z_size);
2439 	if (z_buf == NULL) {
2440 		print_error(MALLOC_FAILED);
2441 		return MALLOC_FAILED;
2442 	}
2443 
2444 	create_rand_repeat_data(z_buf, z_size);
2445 
2446 	ret = compress_full_flush(in_buf, in_size, z_buf, &z_size, gzip_flag, level);
2447 
2448 	if (!ret)
2449 		ret = inflate_check(z_buf, z_size, in_buf, in_size, gzip_flag, NULL, 0, 0);
2450 
2451 	if (ret) {
2452 #ifdef VERBOSE
2453 		printf
2454 		    ("Compressed array at level %d with gzip flag %d and flush type %d: ",
2455 		     level, gzip_flag, FULL_FLUSH);
2456 		print_uint8_t(z_buf, z_size);
2457 		printf("\n");
2458 		printf("Data: ");
2459 		print_uint8_t(in_buf, in_size);
2460 #endif
2461 		printf("Failed on compress multi pass\n");
2462 		print_error(ret);
2463 	}
2464 
2465 	free(z_buf);
2466 
2467 	return ret;
2468 }
2469 
2470 int test_inflate(struct vect_result *in_vector)
2471 {
2472 	int ret = IGZIP_COMP_OK;
2473 	uint8_t *compress_buf = in_vector->vector, *out_buf = NULL;
2474 	uint64_t compress_len = in_vector->vector_length;
2475 	uint32_t out_size = 0;
2476 
2477 	out_size = 10 * in_vector->vector_length;
2478 	out_buf = malloc(out_size);
2479 	if (out_buf == NULL)
2480 		return MALLOC_FAILED;
2481 
2482 	ret = inflate_stateless_pass(compress_buf, compress_len, out_buf, &out_size, 0);
2483 
2484 	if (ret == INFLATE_LEFTOVER_INPUT)
2485 		ret = ISAL_DECOMP_OK;
2486 
2487 	if (ret != in_vector->expected_error)
2488 		printf("Inflate return value incorrect, %d != %d\n", ret,
2489 		       in_vector->expected_error);
2490 	else
2491 		ret = IGZIP_COMP_OK;
2492 
2493 	if (!ret) {
2494 		ret = inflate_multi_pass(compress_buf, compress_len, out_buf, &out_size,
2495 					 0, NULL, 0, 0);
2496 
2497 		if (ret == INFLATE_LEFTOVER_INPUT)
2498 			ret = ISAL_DECOMP_OK;
2499 
2500 		if (ret != in_vector->expected_error)
2501 			printf("Inflate return value incorrect, %d != %d\n", ret,
2502 			       in_vector->expected_error);
2503 		else
2504 			ret = IGZIP_COMP_OK;
2505 	}
2506 
2507 	return ret;
2508 
2509 }
2510 
2511 int test_large(uint8_t * in_buf, uint32_t in_size, uint64_t large_size)
2512 {
2513 
2514 	int ret = IGZIP_COMP_OK;
2515 	uint32_t gzip_flag, level;
2516 	uint32_t z_size = 0, z_size_max = 0, tmp_buf_size;
2517 	uint8_t *z_buf = NULL, *tmp_buf = NULL;
2518 	int flush_type = NO_FLUSH;
2519 
2520 	/* Test a non overflow case */
2521 	z_size_max = MAX_LARGE_COMP_BUF_SIZE;
2522 
2523 	gzip_flag = rand() % 5;
2524 	level = get_rand_level();
2525 
2526 	z_size = z_size_max;
2527 	z_buf = malloc(z_size);
2528 	if (z_buf == NULL) {
2529 		print_error(MALLOC_FAILED);
2530 		return MALLOC_FAILED;
2531 	}
2532 	create_rand_repeat_data(z_buf, z_size);
2533 
2534 	tmp_buf_size = IBUF_SIZE;
2535 	tmp_buf = malloc(tmp_buf_size);
2536 	if (tmp_buf == NULL) {
2537 		print_error(MALLOC_FAILED);
2538 		return MALLOC_FAILED;
2539 	}
2540 
2541 	ret =
2542 	    compress_ver_rep_buf(in_buf, in_size, large_size, z_buf, z_size, tmp_buf,
2543 				 tmp_buf_size, flush_type, gzip_flag, level);
2544 
2545 	if (ret)
2546 		print_error(ret);
2547 
2548 	if (z_buf != NULL) {
2549 		free(z_buf);
2550 		z_buf = NULL;
2551 	}
2552 
2553 	if (tmp_buf != NULL) {
2554 		free(tmp_buf);
2555 		tmp_buf = NULL;
2556 	}
2557 
2558 	return ret;
2559 }
2560 
2561 /* Run multiple compression tests on data stored in a file */
2562 int test_compress_file(char *file_name)
2563 {
2564 	int ret = IGZIP_COMP_OK;
2565 	uint64_t in_size;
2566 	uint8_t *in_buf = NULL;
2567 	FILE *in_file = NULL;
2568 
2569 	in_file = fopen(file_name, "rb");
2570 	if (!in_file) {
2571 		printf("Failed to open file %s\n", file_name);
2572 		return FILE_READ_FAILED;
2573 	}
2574 
2575 	in_size = get_filesize(in_file);
2576 	if (in_size > MAX_FILE_SIZE)
2577 		in_size = MAX_FILE_SIZE;
2578 
2579 	if (in_size != 0) {
2580 		in_buf = malloc(in_size);
2581 		if (in_buf == NULL) {
2582 			printf("Failed to allocate in_buf for test_compress_file\n");
2583 			return MALLOC_FAILED;
2584 		}
2585 		fread(in_buf, 1, in_size, in_file);
2586 	}
2587 
2588 	ret |= test_compress_stateless(in_buf, in_size, NO_FLUSH);
2589 	if (!ret)
2590 		ret |= test_compress_stateless(in_buf, in_size, SYNC_FLUSH);
2591 	if (!ret)
2592 		ret |= test_compress_stateless(in_buf, in_size, FULL_FLUSH);
2593 	if (!ret)
2594 		ret |= test_compress(in_buf, in_size, NO_FLUSH);
2595 	if (!ret)
2596 		ret |= test_compress(in_buf, in_size, SYNC_FLUSH);
2597 	if (!ret)
2598 		ret |= test_compress(in_buf, in_size, FULL_FLUSH);
2599 	if (!ret)
2600 		ret |= test_flush(in_buf, in_size);
2601 
2602 	if (ret)
2603 		printf("Failed on file %s\n", file_name);
2604 
2605 	if (in_buf != NULL)
2606 		free(in_buf);
2607 
2608 	return ret;
2609 }
2610 
2611 int create_custom_hufftables(struct isal_hufftables *hufftables_custom, int argc, char *argv[])
2612 {
2613 	long int file_length;
2614 	uint8_t *stream = NULL;
2615 	struct isal_huff_histogram histogram;
2616 	FILE *file;
2617 
2618 	memset(&histogram, 0, sizeof(histogram));
2619 
2620 	while (argc > 1) {
2621 		printf("Processing %s\n", argv[argc - 1]);
2622 		file = fopen(argv[argc - 1], "r");
2623 		if (file == NULL) {
2624 			printf("Error opening file\n");
2625 			return 1;
2626 		}
2627 		fseek(file, 0, SEEK_END);
2628 		file_length = ftell(file);
2629 		fseek(file, 0, SEEK_SET);
2630 		file_length -= ftell(file);
2631 
2632 		if (file_length > 0) {
2633 			stream = malloc(file_length);
2634 			if (stream == NULL) {
2635 				printf("Failed to allocate memory to read in file\n");
2636 				fclose(file);
2637 				return 1;
2638 			}
2639 		}
2640 
2641 		fread(stream, 1, file_length, file);
2642 
2643 		if (ferror(file)) {
2644 			printf("Error occurred when reading file\n");
2645 			fclose(file);
2646 			free(stream);
2647 			stream = NULL;
2648 			return 1;
2649 		}
2650 
2651 		/* Create a histogram of frequency of symbols found in stream to
2652 		 * generate the huffman tree.*/
2653 		isal_update_histogram(stream, file_length, &histogram);
2654 
2655 		fclose(file);
2656 		if (stream != NULL) {
2657 			free(stream);
2658 			stream = NULL;
2659 		}
2660 		argc--;
2661 	}
2662 
2663 	return isal_create_hufftables(hufftables_custom, &histogram);
2664 
2665 }
2666 
2667 int main(int argc, char *argv[])
2668 {
2669 	int i = 0, j = 0, ret = 0, fin_ret = 0;
2670 	uint32_t in_size = 0, offset = 0;
2671 	uint8_t *in_buf;
2672 	struct isal_hufftables hufftables_custom, hufftables_sub;
2673 	uint64_t iterations, large_buf_size;
2674 
2675 #ifndef VERBOSE
2676 	setbuf(stdout, NULL);
2677 #endif
2678 
2679 	printf("Window Size: %d K\n", IGZIP_HIST_SIZE / 1024);
2680 	printf("Test Seed  : %d\n", TEST_SEED);
2681 	printf("Randoms    : %d\n", RANDOMS);
2682 	srand(TEST_SEED);
2683 
2684 	hufftables_subset = &hufftables_sub;
2685 	if (argc > 1) {
2686 		ret = create_custom_hufftables(&hufftables_custom, argc, argv);
2687 		if (ret == 0)
2688 			hufftables = &hufftables_custom;
2689 		else {
2690 			printf("Failed to generate custom hufftable");
2691 			return -1;
2692 		}
2693 	}
2694 
2695 	in_buf = malloc(IBUF_SIZE);
2696 	memset(in_buf, 0, IBUF_SIZE);
2697 
2698 	if (in_buf == NULL) {
2699 		fprintf(stderr, "Can't allocate in_buf memory\n");
2700 		return -1;
2701 	}
2702 
2703 	if (argc > 1) {
2704 		printf("igzip_rand_test files:                  ");
2705 
2706 		for (i = 1; i < argc; i++) {
2707 			ret |= test_compress_file(argv[i]);
2708 			if (ret)
2709 				return ret;
2710 		}
2711 
2712 		printf("................");
2713 		printf("%s\n", ret ? "Fail" : "Pass");
2714 		fin_ret |= ret;
2715 	}
2716 
2717 	printf("igzip_rand_test stateless:              ");
2718 
2719 	ret = test_compress_stateless((uint8_t *) str1, sizeof(str1), NO_FLUSH);
2720 	if (ret)
2721 		return ret;
2722 
2723 	ret |= test_compress_stateless((uint8_t *) str2, sizeof(str2), NO_FLUSH);
2724 	if (ret)
2725 		return ret;
2726 
2727 	for (i = 0; i < RANDOMS; i++) {
2728 		in_size = get_rand_data_length();
2729 		offset = rand() % (IBUF_SIZE + 1 - in_size);
2730 		in_buf += offset;
2731 
2732 		create_rand_repeat_data(in_buf, in_size);
2733 
2734 		ret |= test_compress_stateless(in_buf, in_size, NO_FLUSH);
2735 
2736 		in_buf -= offset;
2737 
2738 		if (i % (RANDOMS / 16) == 0)
2739 			printf(".");
2740 
2741 		if (ret)
2742 			return ret;
2743 	}
2744 
2745 	for (i = 0; i < RANDOMS / 16; i++) {
2746 		create_rand_repeat_data(in_buf, PAGE_SIZE);
2747 		ret |= test_compress_stateless(in_buf, PAGE_SIZE, NO_FLUSH);	// good for efence
2748 		if (ret)
2749 			return ret;
2750 	}
2751 
2752 	fin_ret |= ret;
2753 
2754 	ret = test_compress_stateless((uint8_t *) str1, sizeof(str1), SYNC_FLUSH);
2755 	if (ret)
2756 		return ret;
2757 
2758 	ret |= test_compress_stateless((uint8_t *) str2, sizeof(str2), SYNC_FLUSH);
2759 	if (ret)
2760 		return ret;
2761 
2762 	for (i = 0; i < 16; i++) {
2763 		in_size = get_rand_data_length();
2764 		offset = rand() % (IBUF_SIZE + 1 - in_size);
2765 		in_buf += offset;
2766 
2767 		create_rand_repeat_data(in_buf, in_size);
2768 
2769 		ret |= test_compress_stateless(in_buf, in_size, SYNC_FLUSH);
2770 
2771 		in_buf -= offset;
2772 
2773 		if (ret)
2774 			return ret;
2775 	}
2776 
2777 	fin_ret |= ret;
2778 
2779 	printf("%s\n", ret ? "Fail" : "Pass");
2780 
2781 	printf("igzip_rand_test stateless FULL_FLUSH:   ");
2782 
2783 	ret = test_compress_stateless((uint8_t *) str1, sizeof(str1), FULL_FLUSH);
2784 	if (ret)
2785 		return ret;
2786 
2787 	ret |= test_compress_stateless((uint8_t *) str2, sizeof(str2), FULL_FLUSH);
2788 	if (ret)
2789 		return ret;
2790 
2791 	for (i = 0; i < RANDOMS; i++) {
2792 		in_size = get_rand_data_length();
2793 		offset = rand() % (IBUF_SIZE + 1 - in_size);
2794 		in_buf += offset;
2795 
2796 		create_rand_repeat_data(in_buf, in_size);
2797 
2798 		ret |= test_compress_stateless(in_buf, in_size, FULL_FLUSH);
2799 
2800 		in_buf -= offset;
2801 
2802 		if (i % (RANDOMS / 16) == 0)
2803 			printf(".");
2804 
2805 		if (ret)
2806 			return ret;
2807 	}
2808 
2809 	for (i = 0; i < RANDOMS / 16; i++) {
2810 		create_rand_repeat_data(in_buf, PAGE_SIZE);
2811 		ret |= test_compress_stateless(in_buf, PAGE_SIZE, FULL_FLUSH);	// good for efence
2812 		if (ret)
2813 			return ret;
2814 	}
2815 	fin_ret |= ret;
2816 
2817 	printf("%s\n", ret ? "Fail" : "Pass");
2818 
2819 	printf("igzip_rand_test stateful  NO_FLUSH:     ");
2820 
2821 	memcpy(in_buf, str1, sizeof(str1));
2822 	ret = test_compress(in_buf, sizeof(str1), NO_FLUSH);
2823 	if (ret)
2824 		return ret;
2825 
2826 	memcpy(in_buf, str2, sizeof(str2));
2827 	ret |= test_compress(in_buf, sizeof(str2), NO_FLUSH);
2828 	if (ret)
2829 		return ret;
2830 
2831 	for (i = 0; i < RANDOMS; i++) {
2832 		in_size = get_rand_data_length();
2833 		offset = rand() % (IBUF_SIZE + 1 - in_size);
2834 		in_buf += offset;
2835 
2836 		create_rand_repeat_data(in_buf, in_size);
2837 
2838 		ret |= test_compress(in_buf, in_size, NO_FLUSH);
2839 
2840 		in_buf -= offset;
2841 
2842 		if (i % (RANDOMS / 16) == 0)
2843 			printf(".");
2844 		if (ret)
2845 			return ret;
2846 	}
2847 
2848 	fin_ret |= ret;
2849 
2850 	printf("%s\n", ret ? "Fail" : "Pass");
2851 
2852 	printf("igzip_rand_test stateful  SYNC_FLUSH:   ");
2853 
2854 	memcpy(in_buf, str1, sizeof(str1));
2855 	ret = test_compress(in_buf, sizeof(str1), SYNC_FLUSH);
2856 	if (ret)
2857 		return ret;
2858 
2859 	memcpy(in_buf, str2, sizeof(str2));
2860 	ret |= test_compress(in_buf, sizeof(str2), SYNC_FLUSH);
2861 	if (ret)
2862 		return ret;
2863 
2864 	for (i = 0; i < RANDOMS; i++) {
2865 		in_size = get_rand_data_length();
2866 		offset = rand() % (IBUF_SIZE + 1 - in_size);
2867 		in_buf += offset;
2868 
2869 		create_rand_repeat_data(in_buf, in_size);
2870 
2871 		ret |= test_compress(in_buf, in_size, SYNC_FLUSH);
2872 
2873 		in_buf -= offset;
2874 
2875 		if (i % (RANDOMS / 16) == 0)
2876 			printf(".");
2877 		if (ret)
2878 			return ret;
2879 	}
2880 
2881 	fin_ret |= ret;
2882 
2883 	printf("%s\n", ret ? "Fail" : "Pass");
2884 
2885 	printf("igzip_rand_test stateful  FULL_FLUSH:   ");
2886 
2887 	memcpy(in_buf, str1, sizeof(str1));
2888 	ret = test_compress(in_buf, sizeof(str1), FULL_FLUSH);
2889 	if (ret)
2890 		return ret;
2891 
2892 	memcpy(in_buf, str2, sizeof(str2));
2893 	ret |= test_compress(in_buf, sizeof(str2), FULL_FLUSH);
2894 	if (ret)
2895 		return ret;
2896 
2897 	for (i = 0; i < RANDOMS; i++) {
2898 		in_size = get_rand_data_length();
2899 		offset = rand() % (IBUF_SIZE + 1 - in_size);
2900 		in_buf += offset;
2901 
2902 		create_rand_repeat_data(in_buf, in_size);
2903 
2904 		ret |= test_compress(in_buf, in_size, FULL_FLUSH);
2905 
2906 		in_buf -= offset;
2907 
2908 		if (i % (RANDOMS / 16) == 0)
2909 			printf(".");
2910 		if (ret)
2911 			return ret;
2912 	}
2913 
2914 	for (i = 0; i < RANDOMS / 8; i++) {
2915 		in_size = get_rand_data_length();
2916 		offset = rand() % (IBUF_SIZE + 1 - in_size);
2917 		in_buf += offset;
2918 
2919 		create_rand_repeat_data(in_buf, in_size);
2920 
2921 		ret |= test_full_flush(in_buf, in_size);
2922 
2923 		in_buf -= offset;
2924 
2925 		if (ret)
2926 			return ret;
2927 	}
2928 
2929 	fin_ret |= ret;
2930 
2931 	printf("%s\n", ret ? "Fail" : "Pass");
2932 
2933 	printf("igzip_rand_test stateful  Change Flush: ");
2934 
2935 	ret = test_flush((uint8_t *) str1, sizeof(str1));
2936 	if (ret)
2937 		return ret;
2938 
2939 	ret |= test_flush((uint8_t *) str2, sizeof(str2));
2940 	if (ret)
2941 		return ret;
2942 
2943 	for (i = 0; i < RANDOMS / 4; i++) {
2944 		in_size = get_rand_data_length();
2945 		offset = rand() % (IBUF_SIZE + 1 - in_size);
2946 		in_buf += offset;
2947 
2948 		create_rand_repeat_data(in_buf, in_size);
2949 
2950 		ret |= test_flush(in_buf, in_size);
2951 
2952 		in_buf -= offset;
2953 
2954 		if (i % ((RANDOMS / 4) / 16) == 0)
2955 			printf(".");
2956 		if (ret)
2957 			return ret;
2958 	}
2959 
2960 	fin_ret |= ret;
2961 
2962 	printf("%s\n", ret ? "Fail" : "Pass");
2963 
2964 	printf("igzip_rand_test large input             ");
2965 
2966 	iterations = RANDOMS / 256 + 1;
2967 	for (i = 0; i < iterations; i++) {
2968 		in_size = rand() % (32 * 1024) + 16 * 1024;
2969 		offset = rand() % (IBUF_SIZE + 1 - in_size);
2970 		in_buf += offset;
2971 
2972 		large_buf_size = 1;
2973 		large_buf_size <<= 32;
2974 		large_buf_size += rand() % (1024 * 1024) + 1;
2975 		create_rand_repeat_data(in_buf, in_size);
2976 
2977 		ret |= test_large(in_buf, in_size, large_buf_size);
2978 
2979 		if (ret)
2980 			return ret;
2981 
2982 		in_buf -= offset;
2983 
2984 		if (iterations < 16) {
2985 			for (j = 0; j < 16 / iterations; j++)
2986 				printf(".");
2987 		} else if (i % (iterations / 16) == 0)
2988 			printf(".");
2989 
2990 	}
2991 
2992 	if (iterations < 16) {
2993 		for (j = (16 / iterations) * iterations; j < 16; j++)
2994 			printf(".");
2995 	}
2996 
2997 	printf("%s\n", ret ? "Fail" : "Pass");
2998 
2999 	printf("igzip_rand_test inflate   Std Vectors:  ");
3000 
3001 	for (i = 0; i < sizeof(std_vect_array) / sizeof(struct vect_result); i++) {
3002 		ret = test_inflate(&std_vect_array[i]);
3003 		if (ret)
3004 			return ret;
3005 	}
3006 	printf("................");
3007 	printf("%s\n", ret ? "Fail" : "Pass");
3008 
3009 	printf("igzip rand test finished: %s\n",
3010 	       fin_ret ? "Some tests failed" : "All tests passed");
3011 
3012 	return fin_ret != IGZIP_COMP_OK;
3013 }
3014