]> git.proxmox.com Git - ceph.git/blob - ceph/src/isa-l/igzip/igzip_rand_test.c
f3d3ff4d1b3e241955c3289dd9e7cd1302a9e93c
[ceph.git] / ceph / src / isa-l / igzip / igzip_rand_test.c
1 /**********************************************************************
2 Copyright(c) 2011-2016 Intel Corporation All rights reserved.
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7 * Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above copyright
10 notice, this list of conditions and the following disclaimer in
11 the documentation and/or other materials provided with the
12 distribution.
13 * Neither the name of Intel Corporation nor the names of its
14 contributors may be used to endorse or promote products derived
15 from this software without specific prior written permission.
16
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 **********************************************************************/
29
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include "igzip_lib.h"
34 #include "igzip_inflate_ref.h"
35 #include "crc_inflate.h"
36 #include <math.h>
37
38 #ifndef RANDOMS
39 # define RANDOMS 400
40 #endif
41 #ifndef TEST_SEED
42 # define TEST_SEED 0x1234
43 #endif
44
45 #define IBUF_SIZE (1024*1024)
46
47 #ifndef IGZIP_USE_GZIP_FORMAT
48 # define DEFLATE 1
49 #endif
50
51 #define PAGE_SIZE 4*1024
52
53 #define str1 "Short test string"
54 #define str2 "one two three four five six seven eight nine ten eleven twelve " \
55 "thirteen fourteen fifteen sixteen"
56
57 #define TYPE0_HDR_SIZE 5 /* Size of a type 0 blocks header in bytes */
58 #define TYPE0_MAX_SIZE 65535 /* Max length of a type 0 block in bytes (excludes the header) */
59
60 #define MAX_LOOPS 20
61 /* Defines for the possible error conditions */
62 enum IGZIP_TEST_ERROR_CODES {
63 IGZIP_COMP_OK,
64
65 MALLOC_FAILED,
66 FILE_READ_FAILED,
67
68 COMPRESS_INCORRECT_STATE,
69 COMPRESS_INPUT_STREAM_INTEGRITY_ERROR,
70 COMPRESS_OUTPUT_STREAM_INTEGRITY_ERROR,
71 COMPRESS_END_OF_STREAM_NOT_SET,
72 COMPRESS_ALL_INPUT_FAIL,
73 COMPRESS_OUT_BUFFER_OVERFLOW,
74 COMPRESS_LOOP_COUNT_OVERFLOW,
75 COMPRESS_GENERAL_ERROR,
76
77 INFLATE_END_OF_INPUT,
78 INFLATE_INVALID_BLOCK_HEADER,
79 INFLATE_INVALID_SYMBOL,
80 INFLATE_OUT_BUFFER_OVERFLOW,
81 INFLATE_INVALID_NON_COMPRESSED_BLOCK_LENGTH,
82 INFLATE_LEFTOVER_INPUT,
83 INFLATE_INCORRECT_OUTPUT_SIZE,
84 INFLATE_INVALID_LOOK_BACK_DISTANCE,
85 INVALID_GZIP_HEADER,
86 INCORRECT_GZIP_TRAILER,
87 INFLATE_GENERAL_ERROR,
88
89 INVALID_FLUSH_ERROR,
90
91 OVERFLOW_TEST_ERROR,
92 RESULT_ERROR
93 };
94
95 const int hdr_bytes = 300;
96
97 #ifndef DEFLATE
98 const uint8_t gzip_hdr[10] = {
99 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
100 0x00, 0xff
101 };
102
103 const uint32_t gzip_hdr_bytes = 10;
104 const uint32_t gzip_trl_bytes = 8;
105
106 const int trl_bytes = 8;
107 const int gzip_extra_bytes = 18;
108
109 #else
110 const int trl_bytes = 0;
111 const int gzip_extra_bytes = 0;
112
113 #endif
114
115 struct isal_hufftables *hufftables = NULL;
116
117 #define HISTORY_SIZE 32*1024
118 #define MIN_LENGTH 3
119 #define MIN_DIST 1
120
121 /* Create random compressible data. This is achieved by randomly choosing a
122 * random character, or to repeat previous data in the stream for a random
123 * length and look back distance. The probability of a random character or a
124 * repeat being chosen is semi-randomly chosen by setting max_repeat_data to be
125 * differing values */
126 void create_rand_repeat_data(uint8_t * data, int size)
127 {
128 uint32_t next_data;
129 uint8_t *data_start = data;
130 uint32_t length, distance;
131 uint32_t max_repeat_data = 256;
132 uint32_t power = rand() % 32;
133 /* An array of the powers of 2 (except the final element which is 0) */
134 const uint32_t power_of_2_array[] = {
135 0x00000001, 0x00000002, 0x00000004, 0x00000008,
136 0x00000010, 0x00000020, 0x00000040, 0x00000080,
137 0x00000100, 0x00000200, 0x00000400, 0x00000800,
138 0x00001000, 0x00002000, 0x00004000, 0x00008000,
139 0x00010000, 0x00020000, 0x00040000, 0x00080000,
140 0x00100000, 0x00200000, 0x00400000, 0x00800000,
141 0x01000000, 0x02000000, 0x04000000, 0x08000000,
142 0x10000000, 0x20000000, 0x40000000, 0x00000000
143 };
144
145 max_repeat_data += power_of_2_array[power];
146
147 if (size-- > 0)
148 *data++ = rand();
149
150 while (size > 0) {
151 next_data = rand() % max_repeat_data;
152 if (next_data < 256) {
153 *data++ = next_data;
154 size--;
155 } else if (size < 3) {
156 *data++ = rand() % 256;
157 size--;
158 } else {
159 length = (rand() % 256) + MIN_LENGTH;
160 if (length > size)
161 length = (rand() % (size - 2)) + MIN_LENGTH;
162
163 distance = (rand() % HISTORY_SIZE) + MIN_DIST;
164 if (distance > data - data_start)
165 distance = (rand() % (data - data_start)) + MIN_DIST;
166
167 size -= length;
168 if (distance <= length) {
169 while (length-- > 0) {
170 *data = *(data - distance);
171 data++;
172 }
173 } else
174 memcpy(data, data - distance, length);
175 }
176 }
177 }
178
179 void print_error(int error_code)
180 {
181 switch (error_code) {
182 case IGZIP_COMP_OK:
183 break;
184 case MALLOC_FAILED:
185 printf("error: failed to allocate memory\n");
186 break;
187 case FILE_READ_FAILED:
188 printf("error: failed to read in file\n");
189 break;
190 case COMPRESS_INCORRECT_STATE:
191 printf("error: incorrect stream internal state\n");
192 break;
193 case COMPRESS_INPUT_STREAM_INTEGRITY_ERROR:
194 printf("error: inconsistent stream input buffer\n");
195 break;
196 case COMPRESS_OUTPUT_STREAM_INTEGRITY_ERROR:
197 printf("error: inconsistent stream output buffer\n");
198 break;
199 case COMPRESS_END_OF_STREAM_NOT_SET:
200 printf("error: end of stream not set\n");
201 break;
202 case COMPRESS_ALL_INPUT_FAIL:
203 printf("error: not all input data compressed\n");
204 break;
205 case COMPRESS_OUT_BUFFER_OVERFLOW:
206 printf("error: output buffer overflow while compressing data\n");
207 break;
208 case COMPRESS_GENERAL_ERROR:
209 printf("error: compression failed\n");
210 break;
211 case INFLATE_END_OF_INPUT:
212 printf("error: did not decompress all input\n");
213 break;
214 case INFLATE_INVALID_BLOCK_HEADER:
215 printf("error: invalid header\n");
216 break;
217 case INFLATE_INVALID_SYMBOL:
218 printf("error: invalid symbol found when decompressing input\n");
219 break;
220 case INFLATE_OUT_BUFFER_OVERFLOW:
221 printf("error: output buffer overflow while decompressing data\n");
222 break;
223 case INFLATE_INVALID_NON_COMPRESSED_BLOCK_LENGTH:
224 printf("error: invalid length bits in non-compressed block\n");
225 break;
226 case INFLATE_GENERAL_ERROR:
227 printf("error: decompression failed\n");
228 break;
229 case INFLATE_LEFTOVER_INPUT:
230 printf("error: the trailer of igzip output contains junk\n");
231 break;
232 case INFLATE_INCORRECT_OUTPUT_SIZE:
233 printf("error: incorrect amount of data was decompressed\n");
234 break;
235 case INFLATE_INVALID_LOOK_BACK_DISTANCE:
236 printf("error: invalid look back distance found while decompressing\n");
237 break;
238 case INVALID_GZIP_HEADER:
239 printf("error: incorrect gzip header found when inflating data\n");
240 break;
241 case INCORRECT_GZIP_TRAILER:
242 printf("error: incorrect gzip trailer found when inflating data\n");
243 break;
244 case INVALID_FLUSH_ERROR:
245 printf("error: invalid flush did not cause compression to error\n");
246 break;
247 case RESULT_ERROR:
248 printf("error: decompressed data is not the same as the compressed data\n");
249 break;
250 case OVERFLOW_TEST_ERROR:
251 printf("error: overflow undetected\n");
252 break;
253 default:
254 printf("error: unknown error code\n");
255 }
256 }
257
258 void print_uint8_t(uint8_t * array, uint64_t length)
259 {
260 const int line_size = 16;
261 int i;
262
263 printf("Length = %lu", length);
264 for (i = 0; i < length; i++) {
265 if ((i % line_size) == 0)
266 printf("\n0x%08x\t", i);
267 else
268 printf(" ");
269 printf("0x%02x,", array[i]);
270 }
271 printf("\n");
272 }
273
274 #ifndef DEFLATE
275 uint32_t check_gzip_header(uint8_t * z_buf)
276 {
277 /* These values are defined in RFC 1952 page 4 */
278 const uint8_t ID1 = 0x1f, ID2 = 0x8b, CM = 0x08, FLG = 0;
279 uint32_t ret = 0;
280 int i;
281 /* Verify that the gzip header is the one used in hufftables_c.c */
282 for (i = 0; i < gzip_hdr_bytes; i++)
283 if (z_buf[i] != gzip_hdr[i])
284 ret = INVALID_GZIP_HEADER;
285
286 /* Verify that the gzip header is a valid gzip header */
287 if (*z_buf++ != ID1)
288 ret = INVALID_GZIP_HEADER;
289
290 if (*z_buf++ != ID2)
291 ret = INVALID_GZIP_HEADER;
292
293 /* Verfiy compression method is Deflate */
294 if (*z_buf++ != CM)
295 ret = INVALID_GZIP_HEADER;
296
297 /* The following comparison is specific to how gzip headers are written in igzip */
298 /* Verify no extra flags are set */
299 if (*z_buf != FLG)
300 ret = INVALID_GZIP_HEADER;
301
302 /* The last 6 bytes in the gzip header do not contain any information
303 * important to decomrpessing the data */
304
305 return ret;
306 }
307
308 uint32_t check_gzip_trl(struct inflate_state * gstream)
309 {
310 uint8_t *index = NULL;
311 uint32_t crc, ret = 0;
312
313 index = gstream->out_buffer.next_out - gstream->out_buffer.total_out;
314 crc = find_crc(index, gstream->out_buffer.total_out);
315
316 if (gstream->out_buffer.total_out != *(uint32_t *) (gstream->in_buffer.next_in + 4) ||
317 crc != *(uint32_t *) gstream->in_buffer.next_in)
318 ret = INCORRECT_GZIP_TRAILER;
319
320 return ret;
321 }
322 #endif
323
324 /* Inflate the compressed data and check that the decompressed data agrees with the input data */
325 int inflate_check(uint8_t * z_buf, int z_size, uint8_t * in_buf, int in_size)
326 {
327 /* Test inflate with reference inflate */
328
329 int ret = 0;
330 struct inflate_state gstream;
331 uint32_t test_size = in_size;
332 uint8_t *test_buf = NULL;
333 int mem_result = 0;
334
335 if (in_size > 0) {
336 assert(in_buf != NULL);
337 test_buf = malloc(test_size);
338
339 if (test_buf == NULL)
340 return MALLOC_FAILED;
341 }
342 if (test_buf != NULL)
343 memset(test_buf, 0xff, test_size);
344
345 #ifndef DEFLATE
346 int gzip_hdr_result, gzip_trl_result;
347
348 gzip_hdr_result = check_gzip_header(z_buf);
349 z_buf += gzip_hdr_bytes;
350 z_size -= gzip_hdr_bytes;
351 #endif
352
353 igzip_inflate_init(&gstream, z_buf, z_size, test_buf, test_size);
354 ret = igzip_inflate(&gstream);
355
356 if (test_buf != NULL)
357 mem_result = memcmp(in_buf, test_buf, in_size);
358
359 #ifdef VERBOSE
360 int i;
361 if (mem_result)
362 for (i = 0; i < in_size; i++) {
363 if (in_buf[i] != test_buf[i]) {
364 printf("First incorrect data at 0x%x of 0x%x, 0x%x != 0x%x\n",
365 i, in_size, in_buf[i], test_buf[i]);
366 break;
367 }
368 }
369 #endif
370
371 #ifndef DEFLATE
372 gzip_trl_result = check_gzip_trl(&gstream);
373 gstream.in_buffer.avail_in -= gzip_trl_bytes;
374 gstream.in_buffer.next_in += gzip_trl_bytes;
375 #endif
376
377 if (test_buf != NULL)
378 free(test_buf);
379
380 switch (ret) {
381 case 0:
382 break;
383 case END_OF_INPUT:
384 return INFLATE_END_OF_INPUT;
385 break;
386 case INVALID_BLOCK_HEADER:
387 return INFLATE_INVALID_BLOCK_HEADER;
388 break;
389 case INVALID_SYMBOL:
390 return INFLATE_INVALID_SYMBOL;
391 break;
392 case OUT_BUFFER_OVERFLOW:
393 return INFLATE_OUT_BUFFER_OVERFLOW;
394 break;
395 case INVALID_NON_COMPRESSED_BLOCK_LENGTH:
396 return INFLATE_INVALID_NON_COMPRESSED_BLOCK_LENGTH;
397 break;
398 case INVALID_LOOK_BACK_DISTANCE:
399 return INFLATE_INVALID_LOOK_BACK_DISTANCE;
400 break;
401 default:
402 return INFLATE_GENERAL_ERROR;
403 break;
404 }
405
406 if (gstream.in_buffer.avail_in != 0)
407 return INFLATE_LEFTOVER_INPUT;
408
409 if (gstream.out_buffer.total_out != in_size)
410 return INFLATE_INCORRECT_OUTPUT_SIZE;
411
412 if (mem_result)
413 return RESULT_ERROR;
414
415 #ifndef DEFLATE
416 if (gzip_hdr_result)
417 return INVALID_GZIP_HEADER;
418
419 if (gzip_trl_result)
420 return INCORRECT_GZIP_TRAILER;
421 #endif
422
423 return 0;
424 }
425
426 /* Check if that the state of the data stream is consistent */
427 int stream_valid_check(struct isal_zstream *stream, uint8_t * in_buf, uint32_t in_size,
428 uint8_t * out_buf, uint32_t out_size, uint32_t in_processed,
429 uint32_t out_processed, uint32_t data_size)
430 {
431 uint32_t total_in, in_buffer_size, total_out, out_buffer_size;
432
433 total_in =
434 (in_size ==
435 0) ? in_processed : (in_processed - in_size) + (stream->next_in - in_buf);
436 in_buffer_size = (in_size == 0) ? 0 : stream->next_in - in_buf + stream->avail_in;
437
438 /* Check for a consistent amount of data processed */
439 if (total_in != stream->total_in || in_buffer_size != in_size)
440 return COMPRESS_INPUT_STREAM_INTEGRITY_ERROR;
441
442 total_out =
443 (out_size == 0) ? out_processed : out_processed + (stream->next_out - out_buf);
444 out_buffer_size = (out_size == 0) ? 0 : stream->next_out - out_buf + stream->avail_out;
445
446 /* Check for a consistent amount of data compressed */
447 if (total_out != stream->total_out || out_buffer_size != out_size) {
448 return COMPRESS_OUTPUT_STREAM_INTEGRITY_ERROR;
449 }
450
451 return 0;
452 }
453
454 /* Performs compression with checks to discover and verify the state of the
455 * stream
456 * stream: compress data structure which has been initialized to use
457 * in_buf and out_buf as the buffers
458 * data_size: size of all input data
459 * compressed_size: size of all available output buffers
460 * in_buf: next buffer of data to be compressed
461 * in_size: size of in_buf
462 * out_buf: next out put buffer where data is stored
463 * out_size: size of out_buf
464 * in_processed: the amount of input data which has been loaded into buffers
465 * to be compressed, this includes the data in in_buf
466 * out_processed: the amount of output data which has been compressed and stored,
467 * this does not include the data in the current out_buf
468 */
469 int isal_deflate_with_checks(struct isal_zstream *stream, uint32_t data_size,
470 uint32_t compressed_size, uint8_t * in_buf, uint32_t in_size,
471 uint32_t in_processed, uint8_t * out_buf, uint32_t out_size,
472 uint32_t out_processed)
473 {
474 int ret, stream_check;
475 struct isal_zstate *state = &stream->internal_state;
476
477 #ifdef VERBOSE
478 printf("Pre compression\n");
479 printf
480 ("data_size = 0x%05x, in_processed = 0x%05x, in_size = 0x%05x, avail_in = 0x%05x, total_in = 0x%05x\n",
481 data_size, in_processed, in_size, stream->avail_in, stream->total_in);
482 printf
483 ("compressed_size = 0x%05x, out_processed = 0x%05x, out_size = 0x%05x, avail_out = 0x%05x, total_out = 0x%05x\n",
484 compressed_size, out_processed, out_size, stream->avail_out, stream->total_out);
485 #endif
486
487 ret = isal_deflate(stream);
488
489 #ifdef VERBOSE
490 printf("Post compression\n");
491 printf
492 ("data_size = 0x%05x, in_processed = 0x%05x, in_size = 0x%05x, avail_in = 0x%05x, total_in = 0x%05x\n",
493 data_size, in_processed, in_size, stream->avail_in, stream->total_in);
494 printf
495 ("compressed_size = 0x%05x, out_processed = 0x%05x, out_size = 0x%05x, avail_out = 0x%05x, total_out = 0x%05x\n",
496 compressed_size, out_processed, out_size, stream->avail_out, stream->total_out);
497 printf("\n\n");
498 #endif
499
500 /* Verify the stream is in a valid state */
501 stream_check = stream_valid_check(stream, in_buf, in_size, out_buf, out_size,
502 in_processed, out_processed, data_size);
503
504 if (stream_check != 0)
505 return stream_check;
506
507 if (ret != IGZIP_COMP_OK)
508 return COMPRESS_GENERAL_ERROR;
509
510 /* Check if the compression is completed */
511 if (state->state != ZSTATE_END)
512 if (compressed_size - out_processed - (out_size - stream->avail_out) <= 0)
513 return COMPRESS_OUT_BUFFER_OVERFLOW;
514
515 return ret;
516
517 }
518
519 /* Compress the input data into the output buffer where the input buffer and
520 * output buffer are randomly segmented to test state information for the
521 * compression*/
522 int compress_multi_pass(uint8_t * data, uint32_t data_size, uint8_t * compressed_buf,
523 uint32_t * compressed_size, uint32_t flush_type)
524 {
525 int ret = IGZIP_COMP_OK;
526 uint8_t *in_buf = NULL, *out_buf = NULL;
527 uint32_t in_size = 0, out_size = 0;
528 uint32_t in_processed = 0, out_processed = 0;
529 struct isal_zstream stream;
530 struct isal_zstate *state = &stream.internal_state;
531 uint32_t loop_count = 0;
532
533 #ifdef VERBOSE
534 printf("Starting Compress Multi Pass\n");
535 #endif
536
537 create_rand_repeat_data((uint8_t *) & stream, sizeof(stream));
538
539 isal_deflate_init(&stream);
540
541 if (hufftables != NULL)
542 stream.hufftables = hufftables;
543
544 if (state->state != ZSTATE_NEW_HDR)
545 return COMPRESS_INCORRECT_STATE;
546
547 stream.flush = flush_type;
548 stream.end_of_stream = 0;
549
550 /* These are set here to allow the loop to run correctly */
551 stream.avail_in = 0;
552 stream.avail_out = 0;
553
554 while (1) {
555 loop_count++;
556
557 /* Setup in buffer for next round of compression */
558 if (stream.avail_in == 0) {
559 if (flush_type == NO_FLUSH || state->state == ZSTATE_NEW_HDR) {
560 /* Randomly choose size of the next out buffer */
561 in_size = rand() % (data_size + 1);
562
563 /* Limit size of buffer to be smaller than maximum */
564 if (in_size >= data_size - in_processed) {
565 in_size = data_size - in_processed;
566 stream.end_of_stream = 1;
567 }
568
569 if (in_size != 0) {
570 if (in_buf != NULL) {
571 free(in_buf);
572 in_buf = NULL;
573 }
574
575 in_buf = malloc(in_size);
576 if (in_buf == NULL) {
577 ret = MALLOC_FAILED;
578 break;
579 }
580 memcpy(in_buf, data + in_processed, in_size);
581 in_processed += in_size;
582
583 stream.avail_in = in_size;
584 stream.next_in = in_buf;
585 }
586 }
587 }
588
589 /* Setup out buffer for next round of compression */
590 if (stream.avail_out == 0) {
591 /* Save compressed data inot compressed_buf */
592 if (out_buf != NULL) {
593 memcpy(compressed_buf + out_processed, out_buf,
594 out_size - stream.avail_out);
595 out_processed += out_size - stream.avail_out;
596 }
597
598 /* Randomly choose size of the next out buffer */
599 out_size = rand() % (*compressed_size + 1);
600
601 /* Limit size of buffer to be smaller than maximum */
602 if (out_size > *compressed_size - out_processed)
603 out_size = *compressed_size - out_processed;
604
605 if (out_size != 0) {
606 if (out_buf != NULL) {
607 free(out_buf);
608 out_buf = NULL;
609 }
610
611 out_buf = malloc(out_size);
612 if (out_buf == NULL) {
613 ret = MALLOC_FAILED;
614 break;
615 }
616
617 stream.avail_out = out_size;
618 stream.next_out = out_buf;
619 }
620 }
621
622 ret =
623 isal_deflate_with_checks(&stream, data_size, *compressed_size, in_buf,
624 in_size, in_processed, out_buf, out_size,
625 out_processed);
626
627 if (ret) {
628 if (ret == COMPRESS_OUT_BUFFER_OVERFLOW
629 || ret == COMPRESS_INCORRECT_STATE)
630 memcpy(compressed_buf + out_processed, out_buf, out_size);
631 break;
632 }
633
634 /* Check if the compression is completed */
635 if (state->state == ZSTATE_END) {
636 memcpy(compressed_buf + out_processed, out_buf, out_size);
637 *compressed_size = stream.total_out;
638 break;
639 }
640
641 }
642
643 if (in_buf != NULL)
644 free(in_buf);
645 if (out_buf != NULL)
646 free(out_buf);
647
648 if (ret == COMPRESS_OUT_BUFFER_OVERFLOW && flush_type == SYNC_FLUSH
649 && loop_count >= MAX_LOOPS)
650 ret = COMPRESS_LOOP_COUNT_OVERFLOW;
651
652 return ret;
653
654 }
655
656 /* Compress the input data into the outbuffer in one call to isal_deflate */
657 int compress_single_pass(uint8_t * data, uint32_t data_size, uint8_t * compressed_buf,
658 uint32_t * compressed_size, uint32_t flush_type)
659 {
660 int ret = IGZIP_COMP_OK;
661 struct isal_zstream stream;
662 struct isal_zstate *state = &stream.internal_state;
663
664 #ifdef VERBOSE
665 printf("Starting Compress Single Pass\n");
666 #endif
667
668 create_rand_repeat_data((uint8_t *) & stream, sizeof(stream));
669
670 isal_deflate_init(&stream);
671
672 if (hufftables != NULL)
673 stream.hufftables = hufftables;
674
675 if (state->state != ZSTATE_NEW_HDR)
676 return COMPRESS_INCORRECT_STATE;
677
678 stream.flush = flush_type;
679 stream.avail_in = data_size;
680 stream.next_in = data;
681 stream.avail_out = *compressed_size;
682 stream.next_out = compressed_buf;
683 stream.end_of_stream = 1;
684
685 ret =
686 isal_deflate_with_checks(&stream, data_size, *compressed_size, data, data_size,
687 data_size, compressed_buf, *compressed_size, 0);
688
689 /* Check if the compression is completed */
690 if (state->state == ZSTATE_END)
691 *compressed_size = stream.total_out;
692 else if (flush_type == SYNC_FLUSH && stream.avail_out < 16)
693 ret = COMPRESS_OUT_BUFFER_OVERFLOW;
694
695 return ret;
696
697 }
698
699 /* Statelessly compress the input buffer into the output buffer */
700 int compress_stateless(uint8_t * data, uint32_t data_size, uint8_t * compressed_buf,
701 uint32_t * compressed_size)
702 {
703 int ret = IGZIP_COMP_OK;
704 struct isal_zstream stream;
705
706 create_rand_repeat_data((uint8_t *) & stream, sizeof(stream));
707
708 isal_deflate_init(&stream);
709
710 if (hufftables != NULL)
711 stream.hufftables = hufftables;
712
713 stream.avail_in = data_size;
714 stream.end_of_stream = 1;
715 stream.next_in = data;
716 stream.flush = NO_FLUSH;
717
718 stream.avail_out = *compressed_size;
719 stream.next_out = compressed_buf;
720
721 ret = isal_deflate_stateless(&stream);
722
723 /* verify the stream */
724 if (stream.next_in - data != stream.total_in ||
725 stream.total_in + stream.avail_in != data_size)
726 return COMPRESS_INPUT_STREAM_INTEGRITY_ERROR;
727
728 if (stream.next_out - compressed_buf != stream.total_out ||
729 stream.total_out + stream.avail_out != *compressed_size)
730 return COMPRESS_OUTPUT_STREAM_INTEGRITY_ERROR;
731
732 if (ret != IGZIP_COMP_OK) {
733 if (ret == STATELESS_OVERFLOW)
734 return COMPRESS_OUT_BUFFER_OVERFLOW;
735 else
736 return COMPRESS_GENERAL_ERROR;
737 }
738
739 if (!stream.end_of_stream) {
740 return COMPRESS_END_OF_STREAM_NOT_SET;
741 }
742
743 if (stream.avail_in != 0)
744 return COMPRESS_ALL_INPUT_FAIL;
745
746 *compressed_size = stream.total_out;
747
748 return ret;
749
750 }
751
752 /* Compress the input data into the output buffer where the input buffer and
753 * is randomly segmented to test for independence of blocks in full flush
754 * compression*/
755 int compress_full_flush(uint8_t * data, uint32_t data_size, uint8_t * compressed_buf,
756 uint32_t * compressed_size)
757 {
758 int ret = IGZIP_COMP_OK;
759 uint8_t *in_buf = NULL, *out_buf = compressed_buf;
760 uint32_t in_size = 0;
761 uint32_t in_processed = 00;
762 struct isal_zstream stream;
763 struct isal_zstate *state = &stream.internal_state;
764 uint32_t loop_count = 0;
765
766 #ifdef VERBOSE
767 printf("Starting Compress Full Flush\n");
768 #endif
769
770 create_rand_repeat_data((uint8_t *) & stream, sizeof(stream));
771
772 isal_deflate_init(&stream);
773
774 if (hufftables != NULL)
775 stream.hufftables = hufftables;
776
777 if (state->state != ZSTATE_NEW_HDR)
778 return COMPRESS_INCORRECT_STATE;
779
780 stream.flush = FULL_FLUSH;
781 stream.end_of_stream = 0;
782 stream.avail_out = *compressed_size;
783 stream.next_out = compressed_buf;
784 stream.total_out = 0;
785
786 while (1) {
787 loop_count++;
788
789 /* Setup in buffer for next round of compression */
790 if (state->state == ZSTATE_NEW_HDR) {
791 /* Randomly choose size of the next out buffer */
792 in_size = rand() % (data_size + 1);
793
794 /* Limit size of buffer to be smaller than maximum */
795 if (in_size >= data_size - in_processed) {
796 in_size = data_size - in_processed;
797 stream.end_of_stream = 1;
798 }
799
800 stream.avail_in = in_size;
801
802 if (in_size != 0) {
803 if (in_buf != NULL) {
804 free(in_buf);
805 in_buf = NULL;
806 }
807
808 in_buf = malloc(in_size);
809 if (in_buf == NULL) {
810 ret = MALLOC_FAILED;
811 break;
812 }
813 memcpy(in_buf, data + in_processed, in_size);
814 in_processed += in_size;
815
816 stream.next_in = in_buf;
817 }
818
819 out_buf = stream.next_out;
820 }
821
822 ret = isal_deflate(&stream);
823
824 if (ret)
825 break;
826
827 /* Verify that blocks are independent */
828 if (state->state == ZSTATE_NEW_HDR || state->state == ZSTATE_END) {
829 ret =
830 inflate_check(out_buf, stream.next_out - out_buf, in_buf, in_size);
831
832 if (ret == INFLATE_INVALID_LOOK_BACK_DISTANCE)
833 break;
834 else
835 ret = 0;
836 }
837
838 /* Check if the compression is completed */
839 if (state->state == ZSTATE_END) {
840 *compressed_size = stream.total_out;
841 break;
842 }
843
844 }
845
846 if (in_buf != NULL)
847 free(in_buf);
848
849 if (ret == COMPRESS_OUT_BUFFER_OVERFLOW && loop_count >= MAX_LOOPS)
850 ret = COMPRESS_LOOP_COUNT_OVERFLOW;
851
852 return ret;
853
854 }
855
856 /*Compress the input buffer into the output buffer, but switch the flush type in
857 * the middle of the compression to test what happens*/
858 int compress_swap_flush(uint8_t * data, uint32_t data_size, uint8_t * compressed_buf,
859 uint32_t * compressed_size, uint32_t flush_type)
860 {
861 int ret = IGZIP_COMP_OK;
862 struct isal_zstream stream;
863 struct isal_zstate *state = &stream.internal_state;
864 uint32_t partial_size;
865
866 #ifdef VERBOSE
867 printf("Starting Compress Swap Flush\n");
868 #endif
869
870 isal_deflate_init(&stream);
871
872 if (hufftables != NULL)
873 stream.hufftables = hufftables;
874
875 if (state->state != ZSTATE_NEW_HDR)
876 return COMPRESS_INCORRECT_STATE;
877
878 partial_size = rand() % (data_size + 1);
879
880 stream.flush = flush_type;
881 stream.avail_in = partial_size;
882 stream.next_in = data;
883 stream.avail_out = *compressed_size;
884 stream.next_out = compressed_buf;
885 stream.end_of_stream = 0;
886
887 ret =
888 isal_deflate_with_checks(&stream, data_size, *compressed_size, data, partial_size,
889 partial_size, compressed_buf, *compressed_size, 0);
890
891 if (ret)
892 return ret;
893
894 flush_type = rand() % 3;
895
896 stream.flush = flush_type;
897 stream.avail_in = data_size - partial_size;
898 stream.next_in = data + partial_size;
899 stream.end_of_stream = 1;
900
901 ret =
902 isal_deflate_with_checks(&stream, data_size, *compressed_size, data + partial_size,
903 data_size - partial_size, data_size, compressed_buf,
904 *compressed_size, 0);
905
906 if (ret == COMPRESS_GENERAL_ERROR)
907 return INVALID_FLUSH_ERROR;
908
909 *compressed_size = stream.total_out;
910
911 return ret;
912 }
913
914 /* Test deflate_stateless */
915 int test_compress_stateless(uint8_t * in_data, uint32_t in_size)
916 {
917 int ret = IGZIP_COMP_OK;
918 uint32_t z_size, overflow;
919 uint8_t *z_buf = NULL;
920 uint8_t *in_buf = NULL;
921
922 if (in_size != 0) {
923 in_buf = malloc(in_size);
924
925 if (in_buf == NULL)
926 return MALLOC_FAILED;
927
928 memcpy(in_buf, in_data, in_size);
929 }
930
931 /* Test non-overflow case where a type 0 block is not written */
932 z_size = 2 * in_size + hdr_bytes + trl_bytes;
933
934 z_buf = malloc(z_size);
935
936 if (z_buf == NULL)
937 return MALLOC_FAILED;
938
939 create_rand_repeat_data(z_buf, z_size);
940
941 ret = compress_stateless(in_buf, in_size, z_buf, &z_size);
942
943 if (!ret)
944 ret = inflate_check(z_buf, z_size, in_buf, in_size);
945
946 #ifdef VERBOSE
947 if (ret) {
948 printf("Compressed array: ");
949 print_uint8_t(z_buf, z_size);
950 printf("\n");
951 printf("Data: ");
952 print_uint8_t(in_buf, in_size);
953 }
954 #endif
955 if (z_buf != NULL) {
956 free(z_buf);
957 z_buf = NULL;
958 }
959 print_error(ret);
960 if (ret)
961 return ret;
962
963 /*Test non-overflow case where a type 0 block is possible to be written */
964 z_size =
965 TYPE0_HDR_SIZE * ((in_size + TYPE0_MAX_SIZE - 1) / TYPE0_MAX_SIZE) + in_size +
966 gzip_extra_bytes;
967
968 if (z_size == gzip_extra_bytes)
969 z_size += TYPE0_HDR_SIZE;
970
971 if (z_size < 8)
972 z_size = 8;
973
974 z_buf = malloc(z_size);
975
976 if (z_buf == NULL)
977 return MALLOC_FAILED;
978
979 create_rand_repeat_data(z_buf, z_size);
980
981 ret = compress_stateless(in_buf, in_size, z_buf, &z_size);
982 if (!ret)
983 ret = inflate_check(z_buf, z_size, in_buf, in_size);
984 #ifdef VERBOSE
985 if (ret) {
986 printf("Compressed array: ");
987 print_uint8_t(z_buf, z_size);
988 printf("\n");
989 printf("Data: ");
990 print_uint8_t(in_buf, in_size);
991 }
992 #endif
993
994 if (!ret) {
995 free(z_buf);
996 z_buf = NULL;
997
998 /* Test random overflow case */
999 z_size = rand() % z_size;
1000
1001 if (z_size > in_size)
1002 z_size = rand() & in_size;
1003
1004 if (z_size > 0) {
1005 z_buf = malloc(z_size);
1006
1007 if (z_buf == NULL)
1008 return MALLOC_FAILED;
1009 }
1010
1011 overflow = compress_stateless(in_buf, in_size, z_buf, &z_size);
1012
1013 if (overflow != COMPRESS_OUT_BUFFER_OVERFLOW) {
1014 #ifdef VERBOSE
1015 printf("overflow error = %d\n", overflow);
1016 print_error(overflow);
1017 if (overflow == 0) {
1018 overflow = inflate_check(z_buf, z_size, in_buf, in_size);
1019 printf("inflate ret = %d\n", overflow);
1020 print_error(overflow);
1021 }
1022 printf("Compressed array: ");
1023 print_uint8_t(z_buf, z_size);
1024 printf("\n");
1025 printf("Data: ");
1026 print_uint8_t(in_buf, in_size);
1027 #endif
1028 ret = OVERFLOW_TEST_ERROR;
1029 }
1030 }
1031
1032 print_error(ret);
1033
1034 if (z_buf != NULL)
1035 free(z_buf);
1036
1037 if (in_buf != NULL)
1038 free(in_buf);
1039
1040 return ret;
1041 }
1042
1043 /* Test deflate */
1044 int test_compress(uint8_t * in_buf, uint32_t in_size, uint32_t flush_type)
1045 {
1046 int ret = IGZIP_COMP_OK, fin_ret = IGZIP_COMP_OK;
1047 uint32_t overflow = 0;
1048 uint32_t z_size, z_size_max, z_compressed_size;
1049 uint8_t *z_buf = NULL;
1050
1051 /* Test a non overflow case */
1052 if (flush_type == NO_FLUSH)
1053 z_size_max = 2 * in_size + hdr_bytes + trl_bytes + 2;
1054 else if (flush_type == SYNC_FLUSH || flush_type == FULL_FLUSH)
1055 z_size_max = 2 * in_size + MAX_LOOPS * (hdr_bytes + trl_bytes + 5);
1056 else {
1057 printf("Invalid Flush Parameter\n");
1058 return COMPRESS_GENERAL_ERROR;
1059 }
1060
1061 z_size = z_size_max;
1062
1063 z_buf = malloc(z_size);
1064 if (z_buf == NULL) {
1065 print_error(MALLOC_FAILED);
1066 return MALLOC_FAILED;
1067 }
1068 create_rand_repeat_data(z_buf, z_size_max);
1069
1070 ret = compress_single_pass(in_buf, in_size, z_buf, &z_size, flush_type);
1071
1072 if (!ret)
1073 ret = inflate_check(z_buf, z_size, in_buf, in_size);
1074
1075 if (ret) {
1076 #ifdef VERBOSE
1077 printf("Compressed array: ");
1078 print_uint8_t(z_buf, z_size);
1079 printf("\n");
1080 printf("Data: ");
1081 print_uint8_t(in_buf, in_size);
1082 #endif
1083 printf("Failed on compress single pass\n");
1084 print_error(ret);
1085 }
1086
1087 fin_ret |= ret;
1088
1089 z_compressed_size = z_size;
1090 z_size = z_size_max;
1091 create_rand_repeat_data(z_buf, z_size_max);
1092
1093 ret = compress_multi_pass(in_buf, in_size, z_buf, &z_size, flush_type);
1094
1095 if (!ret)
1096 ret = inflate_check(z_buf, z_size, in_buf, in_size);
1097
1098 if (ret) {
1099 #ifdef VERBOSE
1100 printf("Compressed array: ");
1101 print_uint8_t(z_buf, z_size);
1102 printf("\n");
1103 printf("Data: ");
1104 print_uint8_t(in_buf, in_size);
1105 #endif
1106 printf("Failed on compress multi pass\n");
1107 print_error(ret);
1108 }
1109
1110 fin_ret |= ret;
1111
1112 ret = 0;
1113
1114 /* Test random overflow case */
1115 if (flush_type == SYNC_FLUSH && z_compressed_size > in_size)
1116 z_compressed_size = in_size + 1;
1117
1118 z_size = rand() % z_compressed_size;
1119 create_rand_repeat_data(z_buf, z_size_max);
1120
1121 overflow = compress_single_pass(in_buf, in_size, z_buf, &z_size, flush_type);
1122
1123 if (overflow != COMPRESS_OUT_BUFFER_OVERFLOW) {
1124 if (overflow == 0)
1125 ret = inflate_check(z_buf, z_size, in_buf, in_size);
1126
1127 /* Rarely single pass overflow will compresses data
1128 * better than the initial run. This is to stop that
1129 * case from erroring. */
1130 if (overflow != 0 || ret != 0) {
1131 #ifdef VERBOSE
1132 printf("overflow error = %d\n", overflow);
1133 print_error(overflow);
1134 printf("inflate ret = %d\n", ret);
1135 print_error(overflow);
1136
1137 printf("Compressed array: ");
1138 print_uint8_t(z_buf, z_size);
1139 printf("\n");
1140 printf("Data: ");
1141 print_uint8_t(in_buf, in_size);
1142 #endif
1143 printf("Failed on compress multi pass overflow\n");
1144 print_error(ret);
1145 ret = OVERFLOW_TEST_ERROR;
1146 }
1147 }
1148
1149 fin_ret |= ret;
1150
1151 if (flush_type == NO_FLUSH) {
1152 create_rand_repeat_data(z_buf, z_size_max);
1153
1154 overflow = compress_multi_pass(in_buf, in_size, z_buf, &z_size, flush_type);
1155
1156 if (overflow != COMPRESS_OUT_BUFFER_OVERFLOW) {
1157 if (overflow == 0)
1158 ret = inflate_check(z_buf, z_size, in_buf, in_size);
1159
1160 /* Rarely multi pass overflow will compresses data
1161 * better than the initial run. This is to stop that
1162 * case from erroring */
1163 if (overflow != 0 || ret != 0) {
1164 #ifdef VERBOSE
1165 printf("overflow error = %d\n", overflow);
1166 print_error(overflow);
1167 printf("inflate ret = %d\n", ret);
1168 print_error(overflow);
1169
1170 printf("Compressed array: ");
1171 print_uint8_t(z_buf, z_size);
1172 printf("\n");
1173 printf("Data: ");
1174 print_uint8_t(in_buf, in_size);
1175 #endif
1176 printf("Failed on compress multi pass overflow\n");
1177 print_error(ret);
1178 ret = OVERFLOW_TEST_ERROR;
1179 }
1180 }
1181 fin_ret |= ret;
1182 }
1183
1184 free(z_buf);
1185
1186 return fin_ret;
1187 }
1188
1189 /* Test swapping flush types in the middle of compression */
1190 int test_flush(uint8_t * in_buf, uint32_t in_size)
1191 {
1192 int fin_ret = IGZIP_COMP_OK, ret;
1193 uint32_t z_size, flush_type = 0;
1194 uint8_t *z_buf = NULL;
1195
1196 z_size = 2 * in_size + 2 * (hdr_bytes + trl_bytes) + 8;
1197
1198 z_buf = malloc(z_size);
1199
1200 if (z_buf == NULL)
1201 return MALLOC_FAILED;
1202
1203 create_rand_repeat_data(z_buf, z_size);
1204
1205 while (flush_type < 3)
1206 flush_type = rand();
1207
1208 /* Test invalid flush */
1209 ret = compress_single_pass(in_buf, in_size, z_buf, &z_size, flush_type);
1210
1211 if (ret == COMPRESS_GENERAL_ERROR)
1212 ret = 0;
1213 else {
1214 printf("Failed when passing invalid flush parameter\n");
1215 ret = INVALID_FLUSH_ERROR;
1216 }
1217
1218 fin_ret |= ret;
1219 print_error(ret);
1220
1221 create_rand_repeat_data(z_buf, z_size);
1222
1223 /* Test swapping flush type */
1224 ret = compress_swap_flush(in_buf, in_size, z_buf, &z_size, rand() % 3);
1225
1226 if (!ret)
1227 ret = inflate_check(z_buf, z_size, in_buf, in_size);
1228
1229 if (ret) {
1230 #ifdef VERBOSE
1231 printf("Compressed array: ");
1232 print_uint8_t(z_buf, z_size);
1233 printf("\n");
1234 printf("Data: ");
1235 print_uint8_t(in_buf, in_size);
1236 #endif
1237 printf("Failed on swapping flush type\n");
1238 print_error(ret);
1239 }
1240
1241 fin_ret |= ret;
1242 print_error(ret);
1243
1244 return fin_ret;
1245 }
1246
1247 /* Test there are no length distance pairs across full flushes */
1248 int test_full_flush(uint8_t * in_buf, uint32_t in_size)
1249 {
1250 int ret = IGZIP_COMP_OK;
1251 uint32_t z_size;
1252 uint8_t *z_buf = NULL;
1253
1254 z_size = 2 * in_size + MAX_LOOPS * (hdr_bytes + trl_bytes + 5);
1255
1256 z_buf = malloc(z_size);
1257 if (z_buf == NULL) {
1258 print_error(MALLOC_FAILED);
1259 return MALLOC_FAILED;
1260 }
1261
1262 create_rand_repeat_data(z_buf, z_size);
1263
1264 ret = compress_full_flush(in_buf, in_size, z_buf, &z_size);
1265
1266 if (!ret)
1267 ret = inflate_check(z_buf, z_size, in_buf, in_size);
1268
1269 if (ret) {
1270 #ifdef VERBOSE
1271 printf("Compressed array: ");
1272 print_uint8_t(z_buf, z_size);
1273 printf("\n");
1274 printf("Data: ");
1275 print_uint8_t(in_buf, in_size);
1276 #endif
1277 printf("Failed on compress multi pass\n");
1278 print_error(ret);
1279 }
1280
1281 free(z_buf);
1282
1283 return ret;
1284 }
1285
1286 int get_filesize(FILE * f)
1287 {
1288 int curr, end;
1289
1290 curr = ftell(f); /* Save current position */
1291 fseek(f, 0L, SEEK_END);
1292 end = ftell(f);
1293 fseek(f, curr, SEEK_SET); /* Restore position */
1294 return end;
1295 }
1296
1297 /* Run multiple compression tests on data stored in a file */
1298 int test_compress_file(char *file_name)
1299 {
1300 int ret = IGZIP_COMP_OK;
1301 uint32_t in_size;
1302 uint8_t *in_buf = NULL;
1303 FILE *in_file = NULL;
1304
1305 in_file = fopen(file_name, "rb");
1306 if (!in_file)
1307 return FILE_READ_FAILED;
1308
1309 in_size = get_filesize(in_file);
1310 if (in_size != 0) {
1311 in_buf = malloc(in_size);
1312 if (in_buf == NULL)
1313 return MALLOC_FAILED;
1314 fread(in_buf, 1, in_size, in_file);
1315 }
1316
1317 ret |= test_compress_stateless(in_buf, in_size);
1318 ret |= test_compress(in_buf, in_size, NO_FLUSH);
1319 ret |= test_compress(in_buf, in_size, SYNC_FLUSH);
1320 ret |= test_compress(in_buf, in_size, FULL_FLUSH);
1321 ret |= test_flush(in_buf, in_size);
1322
1323 if (ret)
1324 printf("Failed on file %s\n", file_name);
1325
1326 if (in_buf != NULL)
1327 free(in_buf);
1328
1329 return ret;
1330 }
1331
1332 int create_custom_hufftables(struct isal_hufftables *hufftables_custom, int argc, char *argv[])
1333 {
1334 long int file_length;
1335 uint8_t *stream = NULL;
1336 struct isal_huff_histogram histogram;
1337 FILE *file;
1338
1339 memset(&histogram, 0, sizeof(histogram));
1340
1341 while (argc > 1) {
1342 printf("Processing %s\n", argv[argc - 1]);
1343 file = fopen(argv[argc - 1], "r");
1344 if (file == NULL) {
1345 printf("Error opening file\n");
1346 return 1;
1347 }
1348 fseek(file, 0, SEEK_END);
1349 file_length = ftell(file);
1350 fseek(file, 0, SEEK_SET);
1351 file_length -= ftell(file);
1352
1353 if (file_length > 0) {
1354 stream = malloc(file_length);
1355 if (stream == NULL) {
1356 printf("Failed to allocate memory to read in file\n");
1357 fclose(file);
1358 return 1;
1359 }
1360 }
1361
1362 fread(stream, 1, file_length, file);
1363
1364 if (ferror(file)) {
1365 printf("Error occurred when reading file");
1366 fclose(file);
1367 free(stream);
1368 return 1;
1369 }
1370
1371 /* Create a histogram of frequency of symbols found in stream to
1372 * generate the huffman tree.*/
1373 isal_update_histogram(stream, file_length, &histogram);
1374
1375 fclose(file);
1376 free(stream);
1377 argc--;
1378 }
1379
1380 return isal_create_hufftables(hufftables_custom, &histogram);
1381
1382 }
1383
1384 int main(int argc, char *argv[])
1385 {
1386 int i = 0, ret = 0, fin_ret = 0;
1387 uint32_t in_size = 0, offset = 0;
1388 uint8_t *in_buf;
1389 struct isal_hufftables hufftables_custom;
1390
1391 #ifndef VERBOSE
1392 setbuf(stdout, NULL);
1393 #endif
1394
1395 printf("Window Size: %d K\n", HIST_SIZE);
1396 printf("Test Seed : %d\n", TEST_SEED);
1397 printf("Randoms : %d\n", RANDOMS);
1398 srand(TEST_SEED);
1399
1400 if (argc > 1) {
1401 ret = create_custom_hufftables(&hufftables_custom, argc, argv);
1402 if (ret == 0)
1403 hufftables = &hufftables_custom;
1404 else {
1405 printf("Failed to generate custom hufftable");
1406 return -1;
1407 }
1408 }
1409
1410 in_buf = malloc(IBUF_SIZE);
1411 memset(in_buf, 0, IBUF_SIZE);
1412
1413 if (in_buf == NULL) {
1414 fprintf(stderr, "Can't allocate in_buf memory\n");
1415 return -1;
1416 }
1417
1418 if (argc > 1) {
1419 printf("igzip_rand_test files: ");
1420
1421 for (i = 1; i < argc; i++) {
1422 ret |= test_compress_file(argv[i]);
1423 if (ret)
1424 return ret;
1425 }
1426
1427 printf("................");
1428 printf("%s\n", ret ? "Fail" : "Pass");
1429 fin_ret |= ret;
1430 }
1431
1432 printf("igzip_rand_test stateless: ");
1433
1434 ret = test_compress_stateless((uint8_t *) str1, sizeof(str1));
1435 if (ret)
1436 return ret;
1437
1438 ret |= test_compress_stateless((uint8_t *) str2, sizeof(str2));
1439 if (ret)
1440 return ret;
1441
1442 for (i = 0; i < RANDOMS; i++) {
1443 in_size = rand() % (IBUF_SIZE + 1);
1444 offset = rand() % (IBUF_SIZE + 1 - in_size);
1445 in_buf += offset;
1446
1447 create_rand_repeat_data(in_buf, in_size);
1448
1449 ret |= test_compress_stateless(in_buf, in_size);
1450
1451 in_buf -= offset;
1452
1453 if (i % (RANDOMS / 16) == 0)
1454 printf(".");
1455
1456 if (ret)
1457 return ret;
1458 }
1459
1460 for (i = 0; i < RANDOMS / 16; i++) {
1461 create_rand_repeat_data(in_buf, PAGE_SIZE);
1462 ret |= test_compress_stateless(in_buf, PAGE_SIZE); // good for efence
1463 }
1464
1465 fin_ret |= ret;
1466
1467 printf("%s\n", ret ? "Fail" : "Pass");
1468
1469 printf("igzip_rand_test NO_FLUSH: ");
1470
1471 ret = test_compress((uint8_t *) str1, sizeof(str1), NO_FLUSH);
1472 if (ret)
1473 return ret;
1474
1475 ret |= test_compress((uint8_t *) str2, sizeof(str2), NO_FLUSH);
1476 if (ret)
1477 return ret;
1478
1479 for (i = 0; i < RANDOMS; i++) {
1480 in_size = rand() % (IBUF_SIZE + 1);
1481 offset = rand() % (IBUF_SIZE + 1 - in_size);
1482 in_buf += offset;
1483
1484 create_rand_repeat_data(in_buf, in_size);
1485
1486 ret |= test_compress(in_buf, in_size, NO_FLUSH);
1487
1488 in_buf -= offset;
1489
1490 if (i % (RANDOMS / 16) == 0)
1491 printf(".");
1492 if (ret)
1493 return ret;
1494 }
1495
1496 fin_ret |= ret;
1497
1498 printf("%s\n", ret ? "Fail" : "Pass");
1499
1500 printf("igzip_rand_test SYNC_FLUSH: ");
1501
1502 ret = test_compress((uint8_t *) str1, sizeof(str1), SYNC_FLUSH);
1503 if (ret)
1504 return ret;
1505
1506 ret |= test_compress((uint8_t *) str2, sizeof(str2), SYNC_FLUSH);
1507 if (ret)
1508 return ret;
1509
1510 for (i = 0; i < RANDOMS; i++) {
1511 in_size = rand() % (IBUF_SIZE + 1);
1512 offset = rand() % (IBUF_SIZE + 1 - in_size);
1513 in_buf += offset;
1514
1515 create_rand_repeat_data(in_buf, in_size);
1516
1517 ret |= test_compress(in_buf, in_size, SYNC_FLUSH);
1518
1519 in_buf -= offset;
1520
1521 if (i % (RANDOMS / 16) == 0)
1522 printf(".");
1523 if (ret)
1524 return ret;
1525 }
1526
1527 fin_ret |= ret;
1528
1529 printf("%s\n", ret ? "Fail" : "Pass");
1530
1531 printf("igzip_rand_test FULL_FLUSH: ");
1532
1533 ret = test_compress((uint8_t *) str1, sizeof(str1), FULL_FLUSH);
1534 if (ret)
1535 return ret;
1536
1537 ret |= test_compress((uint8_t *) str2, sizeof(str2), FULL_FLUSH);
1538 if (ret)
1539 return ret;
1540
1541 for (i = 0; i < RANDOMS; i++) {
1542 in_size = rand() % (IBUF_SIZE + 1);
1543 offset = rand() % (IBUF_SIZE + 1 - in_size);
1544 in_buf += offset;
1545
1546 create_rand_repeat_data(in_buf, in_size);
1547
1548 ret |= test_compress(in_buf, in_size, FULL_FLUSH);
1549
1550 in_buf -= offset;
1551
1552 if (i % (RANDOMS / 16) == 0)
1553 printf(".");
1554 if (ret)
1555 return ret;
1556 }
1557
1558 #ifdef DEFLATE
1559 for (i = 0; i < RANDOMS / 8; i++) {
1560 in_size = rand() % (IBUF_SIZE + 1);
1561 offset = rand() % (IBUF_SIZE + 1 - in_size);
1562 in_buf += offset;
1563
1564 create_rand_repeat_data(in_buf, in_size);
1565
1566 ret |= test_full_flush(in_buf, in_size);
1567
1568 in_buf -= offset;
1569
1570 if (ret)
1571 return ret;
1572 }
1573 #endif
1574
1575 fin_ret |= ret;
1576
1577 printf("%s\n", ret ? "Fail" : "Pass");
1578
1579 printf("igzip_rand_test Change Flush: ");
1580
1581 ret = test_flush((uint8_t *) str1, sizeof(str1));
1582 if (ret)
1583 return ret;
1584
1585 ret |= test_flush((uint8_t *) str2, sizeof(str2));
1586 if (ret)
1587 return ret;
1588
1589 for (i = 0; i < RANDOMS / 4; i++) {
1590 in_size = rand() % (IBUF_SIZE + 1);
1591 offset = rand() % (IBUF_SIZE + 1 - in_size);
1592 in_buf += offset;
1593
1594 create_rand_repeat_data(in_buf, in_size);
1595
1596 ret |= test_flush(in_buf, in_size);
1597
1598 in_buf -= offset;
1599
1600 if (i % ((RANDOMS / 4) / 16) == 0)
1601 printf(".");
1602 if (ret)
1603 return ret;
1604 }
1605
1606 fin_ret |= ret;
1607
1608 printf("%s\n", ret ? "Fail" : "Pass");
1609
1610 printf("igzip rand test finished: %s\n",
1611 fin_ret ? "Some tests failed" : "All tests passed");
1612
1613 return fin_ret != IGZIP_COMP_OK;
1614 }