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