1 /**********************************************************************
2 Copyright(c) 2011-2016 Intel Corporation All rights reserved.
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
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
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.
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 **********************************************************************/
34 #include "igzip_lib.h"
35 #include "crc_inflate.h"
36 #include "inflate_std_vects.h"
43 # define TEST_SEED 0x1234
46 #define IBUF_SIZE (1024*1024)
48 #define PAGE_SIZE 4*1024
50 #define str1 "Short test string"
51 #define str2 "one two three four five six seven eight nine ten eleven twelve " \
52 "thirteen fourteen fifteen sixteen"
54 #define TYPE0_HDR_SIZE 5 /* Size of a type 0 blocks header in bytes */
55 #define TYPE0_MAX_SIZE 65535 /* Max length of a type 0 block in bytes (excludes the header) */
58 /* Defines for the possible error conditions */
59 enum IGZIP_TEST_ERROR_CODES
{
65 COMPRESS_INCORRECT_STATE
,
66 COMPRESS_INPUT_STREAM_INTEGRITY_ERROR
,
67 COMPRESS_OUTPUT_STREAM_INTEGRITY_ERROR
,
68 COMPRESS_END_OF_STREAM_NOT_SET
,
69 COMPRESS_ALL_INPUT_FAIL
,
70 COMPRESS_OUT_BUFFER_OVERFLOW
,
71 COMPRESS_LOOP_COUNT_OVERFLOW
,
72 COMPRESS_GENERAL_ERROR
,
75 INFLATE_INVALID_BLOCK_HEADER
,
76 INFLATE_INVALID_SYMBOL
,
77 INFLATE_OUT_BUFFER_OVERFLOW
,
78 INFLATE_LEFTOVER_INPUT
,
79 INFLATE_INCORRECT_OUTPUT_SIZE
,
80 INFLATE_INVALID_LOOK_BACK_DISTANCE
,
82 INCORRECT_GZIP_TRAILER
,
83 INFLATE_GENERAL_ERROR
,
91 static const int hdr_bytes
= 300;
93 static const uint8_t gzip_hdr
[10] = {
94 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
98 static const uint32_t gzip_hdr_bytes
= 10;
99 /* static const uint32_t gzip_trl_bytes = 8; */
101 static const int gzip_extra_bytes
= 18; /* gzip_hdr_bytes + gzip_trl_bytes */
103 int inflate_type
= 0;
105 struct isal_hufftables
*hufftables
= NULL
;
107 #define HISTORY_SIZE 32*1024
111 /* Create random compressible data. This is achieved by randomly choosing a
112 * random character, or to repeat previous data in the stream for a random
113 * length and look back distance. The probability of a random character or a
114 * repeat being chosen is semi-randomly chosen by setting max_repeat_data to be
115 * differing values */
116 void create_rand_repeat_data(uint8_t * data
, int size
)
119 uint8_t *data_start
= data
;
120 uint32_t length
, distance
;
121 uint32_t max_repeat_data
= 256;
122 uint32_t power
= rand() % 32;
123 /* An array of the powers of 2 (except the final element which is 0) */
124 const uint32_t power_of_2_array
[] = {
125 0x00000001, 0x00000002, 0x00000004, 0x00000008,
126 0x00000010, 0x00000020, 0x00000040, 0x00000080,
127 0x00000100, 0x00000200, 0x00000400, 0x00000800,
128 0x00001000, 0x00002000, 0x00004000, 0x00008000,
129 0x00010000, 0x00020000, 0x00040000, 0x00080000,
130 0x00100000, 0x00200000, 0x00400000, 0x00800000,
131 0x01000000, 0x02000000, 0x04000000, 0x08000000,
132 0x10000000, 0x20000000, 0x40000000, 0x00000000
135 max_repeat_data
+= power_of_2_array
[power
];
141 next_data
= rand() % max_repeat_data
;
142 if (next_data
< 256) {
145 } else if (size
< 3) {
146 *data
++ = rand() % 256;
149 length
= (rand() % 256) + MIN_LENGTH
;
151 length
= (rand() % (size
- 2)) + MIN_LENGTH
;
153 distance
= (rand() % HISTORY_SIZE
) + MIN_DIST
;
154 if (distance
> data
- data_start
)
155 distance
= (rand() % (data
- data_start
)) + MIN_DIST
;
158 if (distance
<= length
) {
159 while (length
-- > 0) {
160 *data
= *(data
- distance
);
164 memcpy(data
, data
- distance
, length
);
169 void print_error(int error_code
)
171 switch (error_code
) {
175 printf("error: failed to allocate memory\n");
177 case FILE_READ_FAILED
:
178 printf("error: failed to read in file\n");
180 case COMPRESS_INCORRECT_STATE
:
181 printf("error: incorrect stream internal state\n");
183 case COMPRESS_INPUT_STREAM_INTEGRITY_ERROR
:
184 printf("error: inconsistent stream input buffer\n");
186 case COMPRESS_OUTPUT_STREAM_INTEGRITY_ERROR
:
187 printf("error: inconsistent stream output buffer\n");
189 case COMPRESS_END_OF_STREAM_NOT_SET
:
190 printf("error: end of stream not set\n");
192 case COMPRESS_ALL_INPUT_FAIL
:
193 printf("error: not all input data compressed\n");
195 case COMPRESS_OUT_BUFFER_OVERFLOW
:
196 printf("error: output buffer overflow while compressing data\n");
198 case COMPRESS_GENERAL_ERROR
:
199 printf("error: compression failed\n");
201 case INFLATE_END_OF_INPUT
:
202 printf("error: did not decompress all input\n");
204 case INFLATE_INVALID_BLOCK_HEADER
:
205 printf("error: invalid header\n");
207 case INFLATE_INVALID_SYMBOL
:
208 printf("error: invalid symbol found when decompressing input\n");
210 case INFLATE_OUT_BUFFER_OVERFLOW
:
211 printf("error: output buffer overflow while decompressing data\n");
213 case INFLATE_GENERAL_ERROR
:
214 printf("error: decompression failed\n");
216 case INFLATE_LEFTOVER_INPUT
:
217 printf("error: the trailer of igzip output contains junk\n");
219 case INFLATE_INCORRECT_OUTPUT_SIZE
:
220 printf("error: incorrect amount of data was decompressed\n");
222 case INFLATE_INVALID_LOOK_BACK_DISTANCE
:
223 printf("error: invalid look back distance found while decompressing\n");
225 case INVALID_GZIP_HEADER
:
226 printf("error: incorrect gzip header found when inflating data\n");
228 case INCORRECT_GZIP_TRAILER
:
229 printf("error: incorrect gzip trailer found when inflating data\n");
231 case INVALID_FLUSH_ERROR
:
232 printf("error: invalid flush did not cause compression to error\n");
235 printf("error: decompressed data is not the same as the compressed data\n");
237 case OVERFLOW_TEST_ERROR
:
238 printf("error: overflow undetected\n");
241 printf("error: unknown error code\n");
245 void print_uint8_t(uint8_t * array
, uint64_t length
)
247 const int line_size
= 16;
250 printf("Length = %lu", length
);
251 for (i
= 0; i
< length
; i
++) {
252 if ((i
% line_size
) == 0)
253 printf("\n0x%08x\t", i
);
256 printf("0x%02x,", array
[i
]);
261 uint32_t check_gzip_header(uint8_t * z_buf
)
263 /* These values are defined in RFC 1952 page 4 */
264 const uint8_t ID1
= 0x1f, ID2
= 0x8b, CM
= 0x08, FLG
= 0;
267 /* Verify that the gzip header is the one used in hufftables_c.c */
268 for (i
= 0; i
< gzip_hdr_bytes
; i
++)
269 if (z_buf
[i
] != gzip_hdr
[i
])
270 ret
= INVALID_GZIP_HEADER
;
272 /* Verify that the gzip header is a valid gzip header */
274 ret
= INVALID_GZIP_HEADER
;
277 ret
= INVALID_GZIP_HEADER
;
279 /* Verfiy compression method is Deflate */
281 ret
= INVALID_GZIP_HEADER
;
283 /* The following comparison is specific to how gzip headers are written in igzip */
284 /* Verify no extra flags are set */
286 ret
= INVALID_GZIP_HEADER
;
288 /* The last 6 bytes in the gzip header do not contain any information
289 * important to decomrpessing the data */
294 uint32_t check_gzip_trl(uint64_t gzip_trl
, uint32_t inflate_crc
, uint8_t * uncompress_buf
,
295 uint32_t uncompress_len
)
297 uint64_t trl
, ret
= 0;
300 crc
= find_crc(uncompress_buf
, uncompress_len
);
301 trl
= ((uint64_t) uncompress_len
<< 32) | crc
;
303 if (crc
!= inflate_crc
|| trl
!= gzip_trl
)
304 ret
= INCORRECT_GZIP_TRAILER
;
309 int inflate_stateless_pass(uint8_t * compress_buf
, uint64_t compress_len
,
310 uint8_t * uncompress_buf
, uint32_t * uncompress_len
,
313 struct inflate_state state
;
316 state
.next_in
= compress_buf
;
317 state
.avail_in
= compress_len
;
318 state
.next_out
= uncompress_buf
;
319 state
.avail_out
= *uncompress_len
;
320 state
.crc_flag
= gzip_flag
;
322 ret
= isal_inflate_stateless(&state
);
324 *uncompress_len
= state
.total_out
;
329 check_gzip_trl(*(uint64_t *) state
.next_in
, state
.crc
,
330 uncompress_buf
, *uncompress_len
);
334 if (ret
== 0 && state
.avail_in
!= 0)
335 ret
= INFLATE_LEFTOVER_INPUT
;
340 int inflate_multi_pass(uint8_t * compress_buf
, uint64_t compress_len
,
341 uint8_t * uncompress_buf
, uint32_t * uncompress_len
, uint32_t gzip_flag
)
343 struct inflate_state
*state
= NULL
;
345 uint8_t *comp_tmp
= NULL
, *uncomp_tmp
= NULL
;
346 uint32_t comp_tmp_size
= 0, uncomp_tmp_size
= 0;
347 uint32_t comp_processed
= 0, uncomp_processed
= 0;
348 int32_t read_in_old
= 0;
350 state
= malloc(sizeof(struct inflate_state
));
352 printf("Failed to allocate memory\n");
356 isal_inflate_init(state
);
358 state
->next_in
= NULL
;
359 state
->next_out
= NULL
;
361 state
->avail_out
= 0;
362 state
->crc_flag
= gzip_flag
;
368 if (state
->avail_in
== 0) {
369 comp_tmp_size
= rand() % (compress_len
+ 1);
371 if (comp_tmp_size
>= compress_len
- comp_processed
)
372 comp_tmp_size
= compress_len
- comp_processed
;
374 if (comp_tmp_size
!= 0) {
375 if (comp_tmp
!= NULL
) {
380 comp_tmp
= malloc(comp_tmp_size
);
382 if (comp_tmp
== NULL
) {
383 printf("Failed to allocate memory\n");
384 return MALLOC_FAILED
;
387 memcpy(comp_tmp
, compress_buf
+ comp_processed
, comp_tmp_size
);
388 comp_processed
+= comp_tmp_size
;
390 state
->next_in
= comp_tmp
;
391 state
->avail_in
= comp_tmp_size
;
395 if (state
->avail_out
== 0) {
396 /* Save uncompressed data into uncompress_buf */
397 if (uncomp_tmp
!= NULL
) {
398 memcpy(uncompress_buf
+ uncomp_processed
, uncomp_tmp
,
400 uncomp_processed
+= uncomp_tmp_size
;
403 uncomp_tmp_size
= rand() % (*uncompress_len
+ 1);
405 /* Limit size of buffer to be smaller than maximum */
406 if (uncomp_tmp_size
> *uncompress_len
- uncomp_processed
)
407 uncomp_tmp_size
= *uncompress_len
- uncomp_processed
;
409 if (uncomp_tmp_size
!= 0) {
411 if (uncomp_tmp
!= NULL
) {
417 uncomp_tmp
= malloc(uncomp_tmp_size
);
418 if (uncomp_tmp
== NULL
) {
419 printf("Failed to allocate memory\n");
420 return MALLOC_FAILED
;
423 state
->avail_out
= uncomp_tmp_size
;
424 state
->next_out
= uncomp_tmp
;
428 ret
= isal_inflate(state
);
430 if (state
->block_state
== ISAL_BLOCK_FINISH
|| ret
!= 0) {
431 memcpy(uncompress_buf
+ uncomp_processed
, uncomp_tmp
, uncomp_tmp_size
);
432 *uncompress_len
= state
->total_out
;
436 if (*uncompress_len
- uncomp_processed
== 0 && state
->avail_out
== 0
437 && state
->tmp_out_valid
- state
->tmp_out_processed
> 0) {
438 ret
= ISAL_OUT_OVERFLOW
;
442 if (compress_len
- comp_processed
== 0 && state
->avail_in
== 0
443 && (state
->block_state
!= ISAL_BLOCK_INPUT_DONE
)
444 && state
->tmp_out_valid
- state
->tmp_out_processed
== 0) {
445 if (state
->read_in_length
== read_in_old
) {
446 ret
= ISAL_END_INPUT
;
449 read_in_old
= state
->read_in_length
;
456 check_gzip_trl(*(uint64_t *) & compress_buf
[compress_len
],
457 state
->crc
, uncompress_buf
, *uncompress_len
);
459 if (ret
== 0 && state
->avail_in
!= 0)
460 ret
= INFLATE_LEFTOVER_INPUT
;
462 if (comp_tmp
!= NULL
) {
467 if (uncomp_tmp
!= NULL
) {
476 /* Inflate the compressed data and check that the decompressed data agrees with the input data */
477 int inflate_check(uint8_t * z_buf
, int z_size
, uint8_t * in_buf
, int in_size
,
480 /* Test inflate with reference inflate */
483 uint32_t test_size
= in_size
;
484 uint8_t *test_buf
= NULL
;
486 int gzip_hdr_result
= 0, gzip_trl_result
= 0;
489 assert(in_buf
!= NULL
);
490 test_buf
= malloc(test_size
);
491 if (test_buf
== NULL
)
492 return MALLOC_FAILED
;
495 if (test_buf
!= NULL
)
496 memset(test_buf
, 0xff, test_size
);
498 if (gzip_flag
== IGZIP_GZIP
) {
499 gzip_hdr_result
= check_gzip_header(z_buf
);
500 z_buf
+= gzip_hdr_bytes
;
501 z_size
-= gzip_hdr_bytes
;
504 if (inflate_type
== 0) {
505 ret
= inflate_stateless_pass(z_buf
, z_size
, test_buf
, &test_size
, gzip_flag
);
508 ret
= inflate_multi_pass(z_buf
, z_size
, test_buf
, &test_size
, gzip_flag
);
512 if (test_buf
!= NULL
)
513 mem_result
= memcmp(in_buf
, test_buf
, in_size
);
518 for (i
= 0; i
< in_size
; i
++) {
519 if (in_buf
[i
] != test_buf
[i
]) {
521 ("First incorrect data at 0x%x of 0x%x, 0x%x != 0x%x\n",
522 i
, in_size
, in_buf
[i
], test_buf
[i
]);
528 if (test_buf
!= NULL
)
534 return INFLATE_END_OF_INPUT
;
536 case ISAL_INVALID_BLOCK
:
537 return INFLATE_INVALID_BLOCK_HEADER
;
539 case ISAL_INVALID_SYMBOL
:
540 return INFLATE_INVALID_SYMBOL
;
542 case ISAL_OUT_OVERFLOW
:
543 return INFLATE_OUT_BUFFER_OVERFLOW
;
545 case ISAL_INVALID_LOOKBACK
:
546 return INFLATE_INVALID_LOOK_BACK_DISTANCE
;
548 case INFLATE_LEFTOVER_INPUT
:
549 return INFLATE_LEFTOVER_INPUT
;
551 case INCORRECT_GZIP_TRAILER
:
552 gzip_trl_result
= INCORRECT_GZIP_TRAILER
;
556 return INFLATE_GENERAL_ERROR
;
560 if (test_size
!= in_size
)
561 return INFLATE_INCORRECT_OUTPUT_SIZE
;
568 return INVALID_GZIP_HEADER
;
571 return INCORRECT_GZIP_TRAILER
;
577 /* Check if that the state of the data stream is consistent */
578 int stream_valid_check(struct isal_zstream
*stream
, uint8_t * in_buf
, uint32_t in_size
,
579 uint8_t * out_buf
, uint32_t out_size
, uint32_t in_processed
,
580 uint32_t out_processed
, uint32_t data_size
)
582 uint32_t total_in
, in_buffer_size
, total_out
, out_buffer_size
;
586 0) ? in_processed
: (in_processed
- in_size
) + (stream
->next_in
- in_buf
);
587 in_buffer_size
= (in_size
== 0) ? 0 : stream
->next_in
- in_buf
+ stream
->avail_in
;
589 /* Check for a consistent amount of data processed */
590 if (total_in
!= stream
->total_in
|| in_buffer_size
!= in_size
)
591 return COMPRESS_INPUT_STREAM_INTEGRITY_ERROR
;
594 (out_size
== 0) ? out_processed
: out_processed
+ (stream
->next_out
- out_buf
);
595 out_buffer_size
= (out_size
== 0) ? 0 : stream
->next_out
- out_buf
+ stream
->avail_out
;
597 /* Check for a consistent amount of data compressed */
598 if (total_out
!= stream
->total_out
|| out_buffer_size
!= out_size
) {
599 return COMPRESS_OUTPUT_STREAM_INTEGRITY_ERROR
;
605 /* Performs compression with checks to discover and verify the state of the
607 * stream: compress data structure which has been initialized to use
608 * in_buf and out_buf as the buffers
609 * data_size: size of all input data
610 * compressed_size: size of all available output buffers
611 * in_buf: next buffer of data to be compressed
612 * in_size: size of in_buf
613 * out_buf: next out put buffer where data is stored
614 * out_size: size of out_buf
615 * in_processed: the amount of input data which has been loaded into buffers
616 * to be compressed, this includes the data in in_buf
617 * out_processed: the amount of output data which has been compressed and stored,
618 * this does not include the data in the current out_buf
620 int isal_deflate_with_checks(struct isal_zstream
*stream
, uint32_t data_size
,
621 uint32_t compressed_size
, uint8_t * in_buf
, uint32_t in_size
,
622 uint32_t in_processed
, uint8_t * out_buf
, uint32_t out_size
,
623 uint32_t out_processed
)
625 int ret
, stream_check
;
626 struct isal_zstate
*state
= &stream
->internal_state
;
629 printf("Pre compression\n");
631 ("data_size = 0x%05x, in_processed = 0x%05x, in_size = 0x%05x, avail_in = 0x%05x, total_in = 0x%05x\n",
632 data_size
, in_processed
, in_size
, stream
->avail_in
, stream
->total_in
);
634 ("compressed_size = 0x%05x, out_processed = 0x%05x, out_size = 0x%05x, avail_out = 0x%05x, total_out = 0x%05x\n",
635 compressed_size
, out_processed
, out_size
, stream
->avail_out
, stream
->total_out
);
638 ret
= isal_deflate(stream
);
641 printf("Post compression\n");
643 ("data_size = 0x%05x, in_processed = 0x%05x, in_size = 0x%05x, avail_in = 0x%05x, total_in = 0x%05x\n",
644 data_size
, in_processed
, in_size
, stream
->avail_in
, stream
->total_in
);
646 ("compressed_size = 0x%05x, out_processed = 0x%05x, out_size = 0x%05x, avail_out = 0x%05x, total_out = 0x%05x\n",
647 compressed_size
, out_processed
, out_size
, stream
->avail_out
, stream
->total_out
);
651 /* Verify the stream is in a valid state */
652 stream_check
= stream_valid_check(stream
, in_buf
, in_size
, out_buf
, out_size
,
653 in_processed
, out_processed
, data_size
);
655 if (stream_check
!= 0)
658 if (ret
!= IGZIP_COMP_OK
)
659 return COMPRESS_GENERAL_ERROR
;
661 /* Check if the compression is completed */
662 if (state
->state
!= ZSTATE_END
)
663 if (compressed_size
- out_processed
- (out_size
- stream
->avail_out
) <= 0)
664 return COMPRESS_OUT_BUFFER_OVERFLOW
;
670 void set_random_hufftable(struct isal_zstream
*stream
)
672 isal_deflate_set_hufftables(stream
, hufftables
, rand() % 4);
675 /* Compress the input data into the output buffer where the input buffer and
676 * output buffer are randomly segmented to test state information for the
678 int compress_multi_pass(uint8_t * data
, uint32_t data_size
, uint8_t * compressed_buf
,
679 uint32_t * compressed_size
, uint32_t flush_type
, uint32_t gzip_flag
,
682 int ret
= IGZIP_COMP_OK
;
683 uint8_t *in_buf
= NULL
, *out_buf
= NULL
;
684 uint32_t in_size
= 0, out_size
= 0;
685 uint32_t in_processed
= 0, out_processed
= 0;
686 struct isal_zstream stream
;
687 struct isal_zstate
*state
= &stream
.internal_state
;
688 uint32_t loop_count
= 0;
689 uint32_t level_buf_size
;
690 uint8_t *level_buf
= NULL
;
693 printf("Starting Compress Multi Pass\n");
696 create_rand_repeat_data((uint8_t *) & stream
, sizeof(stream
));
698 isal_deflate_init(&stream
);
700 if (state
->state
!= ZSTATE_NEW_HDR
)
701 return COMPRESS_INCORRECT_STATE
;
703 stream
.flush
= flush_type
;
704 stream
.end_of_stream
= 0;
706 /* These are set here to allow the loop to run correctly */
708 stream
.avail_out
= 0;
709 stream
.gzip_flag
= gzip_flag
;
710 stream
.level
= level
;
713 level_buf_size
= rand() % IBUF_SIZE
+ ISAL_DEF_LVL1_MIN
;
714 level_buf
= malloc(level_buf_size
);
715 create_rand_repeat_data(level_buf
, level_buf_size
);
716 stream
.level_buf
= level_buf
;
717 stream
.level_buf_size
= level_buf_size
;
723 /* Setup in buffer for next round of compression */
724 if (stream
.avail_in
== 0) {
725 if (flush_type
== NO_FLUSH
|| state
->state
== ZSTATE_NEW_HDR
) {
726 /* Randomly choose size of the next out buffer */
727 in_size
= rand() % (data_size
+ 1);
729 /* Limit size of buffer to be smaller than maximum */
730 if (in_size
>= data_size
- in_processed
) {
731 in_size
= data_size
- in_processed
;
732 stream
.end_of_stream
= 1;
736 if (in_buf
!= NULL
) {
741 in_buf
= malloc(in_size
);
742 if (in_buf
== NULL
) {
746 memcpy(in_buf
, data
+ in_processed
, in_size
);
747 in_processed
+= in_size
;
749 stream
.avail_in
= in_size
;
750 stream
.next_in
= in_buf
;
755 /* Setup out buffer for next round of compression */
756 if (stream
.avail_out
== 0) {
757 /* Save compressed data inot compressed_buf */
758 if (out_buf
!= NULL
) {
759 memcpy(compressed_buf
+ out_processed
, out_buf
,
760 out_size
- stream
.avail_out
);
761 out_processed
+= out_size
- stream
.avail_out
;
764 /* Randomly choose size of the next out buffer */
765 out_size
= rand() % (*compressed_size
+ 1);
767 /* Limit size of buffer to be smaller than maximum */
768 if (out_size
> *compressed_size
- out_processed
)
769 out_size
= *compressed_size
- out_processed
;
772 if (out_buf
!= NULL
) {
777 out_buf
= malloc(out_size
);
778 if (out_buf
== NULL
) {
783 stream
.avail_out
= out_size
;
784 stream
.next_out
= out_buf
;
788 if (state
->state
== ZSTATE_NEW_HDR
)
789 set_random_hufftable(&stream
);
792 isal_deflate_with_checks(&stream
, data_size
, *compressed_size
, in_buf
,
793 in_size
, in_processed
, out_buf
, out_size
,
797 if (ret
== COMPRESS_OUT_BUFFER_OVERFLOW
798 || ret
== COMPRESS_INCORRECT_STATE
)
799 memcpy(compressed_buf
+ out_processed
, out_buf
, out_size
);
803 /* Check if the compression is completed */
804 if (state
->state
== ZSTATE_END
) {
805 memcpy(compressed_buf
+ out_processed
, out_buf
, out_size
);
806 *compressed_size
= stream
.total_out
;
812 if (level_buf
!= NULL
)
819 if (ret
== COMPRESS_OUT_BUFFER_OVERFLOW
&& flush_type
== SYNC_FLUSH
820 && loop_count
>= MAX_LOOPS
)
821 ret
= COMPRESS_LOOP_COUNT_OVERFLOW
;
827 /* Compress the input data into the outbuffer in one call to isal_deflate */
828 int compress_single_pass(uint8_t * data
, uint32_t data_size
, uint8_t * compressed_buf
,
829 uint32_t * compressed_size
, uint32_t flush_type
, uint32_t gzip_flag
,
832 int ret
= IGZIP_COMP_OK
;
833 struct isal_zstream stream
;
834 struct isal_zstate
*state
= &stream
.internal_state
;
835 uint32_t level_buf_size
;
836 uint8_t *level_buf
= NULL
;
839 printf("Starting Compress Single Pass\n");
842 create_rand_repeat_data((uint8_t *) & stream
, sizeof(stream
));
844 isal_deflate_init(&stream
);
846 set_random_hufftable(&stream
);
848 if (state
->state
!= ZSTATE_NEW_HDR
)
849 return COMPRESS_INCORRECT_STATE
;
851 stream
.flush
= flush_type
;
852 stream
.avail_in
= data_size
;
853 stream
.next_in
= data
;
854 stream
.avail_out
= *compressed_size
;
855 stream
.next_out
= compressed_buf
;
856 stream
.end_of_stream
= 1;
857 stream
.gzip_flag
= gzip_flag
;
858 stream
.level
= level
;
861 level_buf_size
= rand() % IBUF_SIZE
+ ISAL_DEF_LVL1_MIN
;
862 level_buf
= malloc(level_buf_size
);
863 create_rand_repeat_data(level_buf
, level_buf_size
);
864 stream
.level_buf
= level_buf
;
865 stream
.level_buf_size
= level_buf_size
;
869 isal_deflate_with_checks(&stream
, data_size
, *compressed_size
, data
, data_size
,
870 data_size
, compressed_buf
, *compressed_size
, 0);
872 if (level_buf
!= NULL
)
875 /* Check if the compression is completed */
876 if (state
->state
== ZSTATE_END
)
877 *compressed_size
= stream
.total_out
;
878 else if (flush_type
== SYNC_FLUSH
&& stream
.avail_out
< 16)
879 ret
= COMPRESS_OUT_BUFFER_OVERFLOW
;
885 /* Statelessly compress the input buffer into the output buffer */
886 int compress_stateless(uint8_t * data
, uint32_t data_size
, uint8_t * compressed_buf
,
887 uint32_t * compressed_size
, uint32_t flush_type
, uint32_t gzip_flag
,
890 int ret
= IGZIP_COMP_OK
;
891 struct isal_zstream stream
;
892 uint32_t level_buf_size
;
893 uint8_t *level_buf
= NULL
;
895 create_rand_repeat_data((uint8_t *) & stream
, sizeof(stream
));
897 isal_deflate_stateless_init(&stream
);
899 set_random_hufftable(&stream
);
901 stream
.avail_in
= data_size
;
902 stream
.next_in
= data
;
903 stream
.flush
= flush_type
;
904 if (flush_type
!= NO_FLUSH
)
905 stream
.end_of_stream
= 1;
906 stream
.avail_out
= *compressed_size
;
907 stream
.next_out
= compressed_buf
;
908 stream
.gzip_flag
= gzip_flag
;
909 stream
.level
= level
;
912 level_buf_size
= rand() % IBUF_SIZE
;
913 if (level_buf_size
>= ISAL_DEF_LVL1_MIN
) {
914 level_buf
= malloc(level_buf_size
);
915 create_rand_repeat_data(level_buf
, level_buf_size
);
916 stream
.level_buf
= level_buf
;
917 stream
.level_buf_size
= level_buf_size
;
921 ret
= isal_deflate_stateless(&stream
);
923 if (level_buf
!= NULL
)
926 /* verify the stream */
927 if (stream
.next_in
- data
!= stream
.total_in
||
928 stream
.total_in
+ stream
.avail_in
!= data_size
)
929 return COMPRESS_INPUT_STREAM_INTEGRITY_ERROR
;
931 if (stream
.next_out
- compressed_buf
!= stream
.total_out
||
932 stream
.total_out
+ stream
.avail_out
!= *compressed_size
) {
933 return COMPRESS_OUTPUT_STREAM_INTEGRITY_ERROR
;
936 if (ret
!= IGZIP_COMP_OK
) {
937 if (ret
== STATELESS_OVERFLOW
)
938 return COMPRESS_OUT_BUFFER_OVERFLOW
;
939 else if (ret
== INVALID_FLUSH
)
940 return INVALID_FLUSH_ERROR
;
942 return COMPRESS_GENERAL_ERROR
;
945 if (!stream
.end_of_stream
) {
946 return COMPRESS_END_OF_STREAM_NOT_SET
;
949 if (stream
.avail_in
!= 0)
950 return COMPRESS_ALL_INPUT_FAIL
;
952 *compressed_size
= stream
.total_out
;
958 /* Statelessly compress the input buffer into the output buffer */
959 int compress_stateless_full_flush(uint8_t * data
, uint32_t data_size
, uint8_t * compressed_buf
,
960 uint32_t * compressed_size
, uint32_t level
)
962 int ret
= IGZIP_COMP_OK
;
963 uint8_t *in_buf
= NULL
, *level_buf
= NULL
, *out_buf
= compressed_buf
;
964 uint32_t in_size
= 0, level_buf_size
;
965 uint32_t in_processed
= 00;
966 struct isal_zstream stream
;
967 uint32_t loop_count
= 0;
970 printf("Starting Stateless Compress Full Flush\n");
973 create_rand_repeat_data((uint8_t *) & stream
, sizeof(stream
));
975 isal_deflate_stateless_init(&stream
);
977 stream
.flush
= FULL_FLUSH
;
978 stream
.end_of_stream
= 0;
979 stream
.avail_out
= *compressed_size
;
980 stream
.next_out
= compressed_buf
;
981 stream
.level
= level
;
984 level_buf_size
= rand() % IBUF_SIZE
;
985 if (level_buf_size
>= ISAL_DEF_LVL1_MIN
) {
986 level_buf
= malloc(level_buf_size
);
987 create_rand_repeat_data(level_buf
, level_buf_size
);
988 stream
.level_buf
= level_buf
;
989 stream
.level_buf_size
= level_buf_size
;
996 /* Randomly choose size of the next out buffer */
997 in_size
= rand() % (data_size
+ 1);
999 /* Limit size of buffer to be smaller than maximum */
1000 if (in_size
>= data_size
- in_processed
) {
1001 in_size
= data_size
- in_processed
;
1002 stream
.end_of_stream
= 1;
1005 stream
.avail_in
= in_size
;
1008 if (in_buf
!= NULL
) {
1013 in_buf
= malloc(in_size
);
1014 if (in_buf
== NULL
) {
1015 ret
= MALLOC_FAILED
;
1018 memcpy(in_buf
, data
+ in_processed
, in_size
);
1019 in_processed
+= in_size
;
1021 stream
.next_in
= in_buf
;
1024 out_buf
= stream
.next_out
;
1026 if (stream
.internal_state
.state
== ZSTATE_NEW_HDR
)
1027 set_random_hufftable(&stream
);
1029 ret
= isal_deflate_stateless(&stream
);
1030 assert(stream
.internal_state
.bitbuf
.m_bit_count
== 0);
1032 assert(compressed_buf
== stream
.next_out
- stream
.total_out
);
1036 /* Verify that blocks are independent */
1037 ret
= inflate_check(out_buf
, stream
.next_out
- out_buf
, in_buf
, in_size
, 0);
1039 if (ret
== INFLATE_INVALID_LOOK_BACK_DISTANCE
) {
1044 /* Check if the compression is completed */
1045 if (in_processed
== data_size
) {
1046 *compressed_size
= stream
.total_out
;
1052 if (level_buf
!= NULL
)
1058 if (ret
== STATELESS_OVERFLOW
&& loop_count
>= MAX_LOOPS
)
1059 ret
= COMPRESS_LOOP_COUNT_OVERFLOW
;
1065 /* Compress the input data into the output buffer where the input buffer and
1066 * is randomly segmented to test for independence of blocks in full flush
1068 int compress_full_flush(uint8_t * data
, uint32_t data_size
, uint8_t * compressed_buf
,
1069 uint32_t * compressed_size
, uint32_t gzip_flag
, uint32_t level
)
1071 int ret
= IGZIP_COMP_OK
;
1072 uint8_t *in_buf
= NULL
, *out_buf
= compressed_buf
, *level_buf
= NULL
;
1073 uint32_t in_size
= 0, level_buf_size
;
1074 uint32_t in_processed
= 00;
1075 struct isal_zstream stream
;
1076 struct isal_zstate
*state
= &stream
.internal_state
;
1077 uint32_t loop_count
= 0;
1080 printf("Starting Compress Full Flush\n");
1083 create_rand_repeat_data((uint8_t *) & stream
, sizeof(stream
));
1085 isal_deflate_init(&stream
);
1087 if (state
->state
!= ZSTATE_NEW_HDR
)
1088 return COMPRESS_INCORRECT_STATE
;
1090 stream
.flush
= FULL_FLUSH
;
1091 stream
.end_of_stream
= 0;
1092 stream
.avail_out
= *compressed_size
;
1093 stream
.next_out
= compressed_buf
;
1094 stream
.total_out
= 0;
1095 stream
.gzip_flag
= gzip_flag
;
1096 stream
.level
= level
;
1099 level_buf_size
= rand() % IBUF_SIZE
+ ISAL_DEF_LVL1_MIN
;
1100 if (level_buf_size
>= ISAL_DEF_LVL1_MIN
) {
1101 level_buf
= malloc(level_buf_size
);
1102 create_rand_repeat_data(level_buf
, level_buf_size
);
1103 stream
.level_buf
= level_buf
;
1104 stream
.level_buf_size
= level_buf_size
;
1111 /* Setup in buffer for next round of compression */
1112 if (state
->state
== ZSTATE_NEW_HDR
) {
1113 /* Randomly choose size of the next out buffer */
1114 in_size
= rand() % (data_size
+ 1);
1116 /* Limit size of buffer to be smaller than maximum */
1117 if (in_size
>= data_size
- in_processed
) {
1118 in_size
= data_size
- in_processed
;
1119 stream
.end_of_stream
= 1;
1122 stream
.avail_in
= in_size
;
1125 if (in_buf
!= NULL
) {
1130 in_buf
= malloc(in_size
);
1131 if (in_buf
== NULL
) {
1132 ret
= MALLOC_FAILED
;
1135 memcpy(in_buf
, data
+ in_processed
, in_size
);
1136 in_processed
+= in_size
;
1138 stream
.next_in
= in_buf
;
1141 out_buf
= stream
.next_out
;
1144 if (state
->state
== ZSTATE_NEW_HDR
)
1145 set_random_hufftable(&stream
);
1147 ret
= isal_deflate(&stream
);
1152 /* Verify that blocks are independent */
1153 if (state
->state
== ZSTATE_NEW_HDR
|| state
->state
== ZSTATE_END
) {
1155 inflate_check(out_buf
, stream
.next_out
- out_buf
, in_buf
, in_size
,
1158 if (ret
== INFLATE_INVALID_LOOK_BACK_DISTANCE
)
1164 /* Check if the compression is completed */
1165 if (state
->state
== ZSTATE_END
) {
1166 *compressed_size
= stream
.total_out
;
1172 if (level_buf
!= NULL
)
1178 if (ret
== COMPRESS_OUT_BUFFER_OVERFLOW
&& loop_count
>= MAX_LOOPS
)
1179 ret
= COMPRESS_LOOP_COUNT_OVERFLOW
;
1185 /*Compress the input buffer into the output buffer, but switch the flush type in
1186 * the middle of the compression to test what happens*/
1187 int compress_swap_flush(uint8_t * data
, uint32_t data_size
, uint8_t * compressed_buf
,
1188 uint32_t * compressed_size
, uint32_t flush_type
, uint32_t gzip_flag
)
1190 int ret
= IGZIP_COMP_OK
;
1191 struct isal_zstream stream
;
1192 struct isal_zstate
*state
= &stream
.internal_state
;
1193 uint32_t partial_size
;
1196 printf("Starting Compress Swap Flush\n");
1199 isal_deflate_init(&stream
);
1201 set_random_hufftable(&stream
);
1203 if (state
->state
!= ZSTATE_NEW_HDR
)
1204 return COMPRESS_INCORRECT_STATE
;
1206 partial_size
= rand() % (data_size
+ 1);
1208 stream
.flush
= flush_type
;
1209 stream
.avail_in
= partial_size
;
1210 stream
.next_in
= data
;
1211 stream
.avail_out
= *compressed_size
;
1212 stream
.next_out
= compressed_buf
;
1213 stream
.end_of_stream
= 0;
1214 stream
.gzip_flag
= gzip_flag
;
1217 isal_deflate_with_checks(&stream
, data_size
, *compressed_size
, data
, partial_size
,
1218 partial_size
, compressed_buf
, *compressed_size
, 0);
1223 if (state
->state
== ZSTATE_NEW_HDR
)
1224 set_random_hufftable(&stream
);
1226 flush_type
= rand() % 3;
1228 stream
.flush
= flush_type
;
1229 stream
.avail_in
= data_size
- partial_size
;
1230 stream
.next_in
= data
+ partial_size
;
1231 stream
.end_of_stream
= 1;
1234 isal_deflate_with_checks(&stream
, data_size
, *compressed_size
, data
+ partial_size
,
1235 data_size
- partial_size
, data_size
, compressed_buf
,
1236 *compressed_size
, 0);
1238 if (ret
== COMPRESS_GENERAL_ERROR
)
1239 return INVALID_FLUSH_ERROR
;
1241 *compressed_size
= stream
.total_out
;
1246 /* Test deflate_stateless */
1247 int test_compress_stateless(uint8_t * in_data
, uint32_t in_size
, uint32_t flush_type
)
1249 int ret
= IGZIP_COMP_OK
;
1250 uint32_t z_size
, overflow
, gzip_flag
, level
;
1251 uint8_t *z_buf
= NULL
;
1252 uint8_t *in_buf
= NULL
;
1254 gzip_flag
= rand() % 3;
1258 in_buf
= malloc(in_size
);
1261 return MALLOC_FAILED
;
1263 memcpy(in_buf
, in_data
, in_size
);
1266 /* Test non-overflow case where a type 0 block is not written */
1267 z_size
= 2 * in_size
+ hdr_bytes
;
1269 z_size
+= gzip_extra_bytes
;
1271 z_buf
= malloc(z_size
);
1274 return MALLOC_FAILED
;
1276 create_rand_repeat_data(z_buf
, z_size
);
1278 /* If flush type is invalid */
1279 if (flush_type
!= NO_FLUSH
&& flush_type
!= FULL_FLUSH
) {
1281 compress_stateless(in_buf
, in_size
, z_buf
, &z_size
, flush_type
, gzip_flag
,
1284 if (ret
!= INVALID_FLUSH_ERROR
)
1298 /* Else test valid flush type */
1300 compress_stateless(in_buf
, in_size
, z_buf
, &z_size
, flush_type
, gzip_flag
, level
);
1303 ret
= inflate_check(z_buf
, z_size
, in_buf
, in_size
, gzip_flag
);
1307 printf("Compressed array at level %d with gzip flag %d: ", level
, gzip_flag
);
1308 print_uint8_t(z_buf
, z_size
);
1311 print_uint8_t(in_buf
, in_size
);
1314 if (z_buf
!= NULL
) {
1323 /*Test non-overflow case where a type 0 block is possible to be written */
1324 z_size
= TYPE0_HDR_SIZE
* ((in_size
+ TYPE0_MAX_SIZE
- 1) / TYPE0_MAX_SIZE
) + in_size
;
1326 z_size
+= gzip_extra_bytes
;
1328 if (z_size
== gzip_extra_bytes
)
1329 z_size
+= TYPE0_HDR_SIZE
;
1334 z_buf
= malloc(z_size
);
1337 return MALLOC_FAILED
;
1339 create_rand_repeat_data(z_buf
, z_size
);
1342 compress_stateless(in_buf
, in_size
, z_buf
, &z_size
, flush_type
, gzip_flag
, level
);
1344 ret
= inflate_check(z_buf
, z_size
, in_buf
, in_size
, gzip_flag
);
1347 printf("Compressed array at level %d with gzip flag %d: ", level
, gzip_flag
);
1348 print_uint8_t(z_buf
, z_size
);
1351 print_uint8_t(in_buf
, in_size
);
1359 /* Test random overflow case */
1360 z_size
= rand() % z_size
;
1362 if (z_size
> in_size
)
1363 z_size
= rand() & in_size
;
1366 z_buf
= malloc(z_size
);
1369 return MALLOC_FAILED
;
1373 compress_stateless(in_buf
, in_size
, z_buf
, &z_size
, flush_type
, gzip_flag
,
1376 if (overflow
!= COMPRESS_OUT_BUFFER_OVERFLOW
) {
1378 printf("overflow error = %d\n", overflow
);
1379 print_error(overflow
);
1380 if (overflow
== 0) {
1382 inflate_check(z_buf
, z_size
, in_buf
, in_size
, gzip_flag
);
1383 printf("inflate ret = %d\n", overflow
);
1384 print_error(overflow
);
1386 printf("Compressed array at level %d with gzip flag %d: ", level
,
1388 print_uint8_t(z_buf
, z_size
);
1391 print_uint8_t(in_buf
, in_size
);
1398 if (z_buf
!= NULL
) {
1407 if (flush_type
== FULL_FLUSH
) {
1411 z_size
= 2 * in_size
+ MAX_LOOPS
* (hdr_bytes
+ 5);
1413 z_buf
= malloc(z_size
);
1416 return MALLOC_FAILED
;
1418 create_rand_repeat_data(z_buf
, z_size
);
1420 /* Else test valid flush type */
1421 ret
= compress_stateless_full_flush(in_buf
, in_size
, z_buf
, &z_size
, level
);
1424 ret
= inflate_check(z_buf
, z_size
, in_buf
, in_size
, 0);
1425 else if (ret
== COMPRESS_LOOP_COUNT_OVERFLOW
)
1431 printf("Compressed array at level %d with gzip flag %d: ", level
,
1433 print_uint8_t(z_buf
, z_size
);
1436 print_uint8_t(in_buf
, in_size
);
1450 int test_compress(uint8_t * in_buf
, uint32_t in_size
, uint32_t flush_type
)
1452 int ret
= IGZIP_COMP_OK
, fin_ret
= IGZIP_COMP_OK
;
1453 uint32_t overflow
= 0, gzip_flag
, level
;
1454 uint32_t z_size
, z_size_max
, z_compressed_size
;
1455 uint8_t *z_buf
= NULL
;
1457 /* Test a non overflow case */
1458 if (flush_type
== NO_FLUSH
)
1459 z_size_max
= 2 * in_size
+ hdr_bytes
+ 2;
1460 else if (flush_type
== SYNC_FLUSH
|| flush_type
== FULL_FLUSH
)
1461 z_size_max
= 2 * in_size
+ MAX_LOOPS
* (hdr_bytes
+ 5);
1463 printf("Invalid Flush Parameter\n");
1464 return COMPRESS_GENERAL_ERROR
;
1467 gzip_flag
= rand() % 3;
1470 z_size_max
+= gzip_extra_bytes
;
1472 z_size
= z_size_max
;
1474 z_buf
= malloc(z_size
);
1475 if (z_buf
== NULL
) {
1476 print_error(MALLOC_FAILED
);
1477 return MALLOC_FAILED
;
1479 create_rand_repeat_data(z_buf
, z_size
);
1481 ret
= compress_single_pass(in_buf
, in_size
, z_buf
, &z_size
, flush_type
,
1485 ret
= inflate_check(z_buf
, z_size
, in_buf
, in_size
, gzip_flag
);
1489 printf("Compressed array at level %d with gzip flag %d: ", level
, gzip_flag
);
1490 print_uint8_t(z_buf
, z_size
);
1493 print_uint8_t(in_buf
, in_size
);
1495 printf("Failed on compress single pass\n");
1501 z_compressed_size
= z_size
;
1502 z_size
= z_size_max
;
1503 create_rand_repeat_data(z_buf
, z_size_max
);
1506 compress_multi_pass(in_buf
, in_size
, z_buf
, &z_size
, flush_type
, gzip_flag
, level
);
1509 ret
= inflate_check(z_buf
, z_size
, in_buf
, in_size
, gzip_flag
);
1513 printf("Compressed array at level %d with gzip flag %d: ", level
, gzip_flag
);
1514 print_uint8_t(z_buf
, z_size
);
1517 print_uint8_t(in_buf
, in_size
);
1519 printf("Failed on compress multi pass\n");
1527 /* Test random overflow case */
1528 if (flush_type
== SYNC_FLUSH
&& z_compressed_size
> in_size
)
1529 z_compressed_size
= in_size
+ 1;
1531 z_size
= rand() % z_compressed_size
;
1532 create_rand_repeat_data(z_buf
, z_size_max
);
1534 overflow
= compress_single_pass(in_buf
, in_size
, z_buf
, &z_size
, flush_type
,
1537 if (overflow
!= COMPRESS_OUT_BUFFER_OVERFLOW
) {
1539 ret
= inflate_check(z_buf
, z_size
, in_buf
, in_size
, gzip_flag
);
1541 /* Rarely single pass overflow will compresses data
1542 * better than the initial run. This is to stop that
1543 * case from erroring. */
1544 if (overflow
!= 0 || ret
!= 0) {
1546 printf("overflow error = %d\n", overflow
);
1547 print_error(overflow
);
1548 printf("inflate ret = %d\n", ret
);
1549 print_error(overflow
);
1551 printf("Compressed array at level %d with gzip flag %d: ", level
,
1553 print_uint8_t(z_buf
, z_size
);
1556 print_uint8_t(in_buf
, in_size
);
1558 printf("Failed on compress multi pass overflow\n");
1560 ret
= OVERFLOW_TEST_ERROR
;
1566 if (flush_type
== NO_FLUSH
) {
1567 create_rand_repeat_data(z_buf
, z_size_max
);
1570 compress_multi_pass(in_buf
, in_size
, z_buf
, &z_size
, flush_type
,
1573 if (overflow
!= COMPRESS_OUT_BUFFER_OVERFLOW
) {
1575 ret
= inflate_check(z_buf
, z_size
, in_buf
, in_size
, gzip_flag
);
1577 /* Rarely multi pass overflow will compresses data
1578 * better than the initial run. This is to stop that
1579 * case from erroring */
1580 if (overflow
!= 0 || ret
!= 0) {
1582 printf("overflow error = %d\n", overflow
);
1583 print_error(overflow
);
1584 printf("inflate ret = %d\n", ret
);
1585 print_error(overflow
);
1587 printf("Compressed array at level %d with gzip flag %d: ",
1589 print_uint8_t(z_buf
, z_size
);
1592 print_uint8_t(in_buf
, in_size
);
1594 printf("Failed on compress multi pass overflow\n");
1596 ret
= OVERFLOW_TEST_ERROR
;
1607 /* Test swapping flush types in the middle of compression */
1608 int test_flush(uint8_t * in_buf
, uint32_t in_size
)
1610 int fin_ret
= IGZIP_COMP_OK
, ret
;
1611 uint32_t z_size
, flush_type
= 0, gzip_flag
, level
;
1612 uint8_t *z_buf
= NULL
;
1614 gzip_flag
= rand() % 3;
1617 z_size
= 2 * in_size
+ 2 * hdr_bytes
+ 8;
1619 z_size
+= gzip_extra_bytes
;
1620 z_buf
= malloc(z_size
);
1623 return MALLOC_FAILED
;
1625 create_rand_repeat_data(z_buf
, z_size
);
1627 while (flush_type
< 3)
1628 flush_type
= rand();
1630 /* Test invalid flush */
1631 ret
= compress_single_pass(in_buf
, in_size
, z_buf
, &z_size
, flush_type
,
1634 if (ret
== COMPRESS_GENERAL_ERROR
)
1637 printf("Failed when passing invalid flush parameter\n");
1638 ret
= INVALID_FLUSH_ERROR
;
1644 create_rand_repeat_data(z_buf
, z_size
);
1646 /* Test swapping flush type */
1647 ret
= compress_swap_flush(in_buf
, in_size
, z_buf
, &z_size
, rand() % 3, gzip_flag
);
1650 ret
= inflate_check(z_buf
, z_size
, in_buf
, in_size
, gzip_flag
);
1654 printf("Compressed array at level %d with gzip flag %d: ", level
, gzip_flag
);
1655 print_uint8_t(z_buf
, z_size
);
1658 print_uint8_t(in_buf
, in_size
);
1660 printf("Failed on swapping flush type\n");
1670 /* Test there are no length distance pairs across full flushes */
1671 int test_full_flush(uint8_t * in_buf
, uint32_t in_size
)
1673 int ret
= IGZIP_COMP_OK
;
1674 uint32_t z_size
, gzip_flag
, level
;
1675 uint8_t *z_buf
= NULL
;
1677 gzip_flag
= rand() % 3;
1679 z_size
= 2 * in_size
+ MAX_LOOPS
* (hdr_bytes
+ 5);
1682 z_size
+= gzip_extra_bytes
;
1684 z_buf
= malloc(z_size
);
1685 if (z_buf
== NULL
) {
1686 print_error(MALLOC_FAILED
);
1687 return MALLOC_FAILED
;
1690 create_rand_repeat_data(z_buf
, z_size
);
1692 ret
= compress_full_flush(in_buf
, in_size
, z_buf
, &z_size
, gzip_flag
, level
);
1695 ret
= inflate_check(z_buf
, z_size
, in_buf
, in_size
, gzip_flag
);
1699 printf("Compressed array: ");
1700 print_uint8_t(z_buf
, z_size
);
1703 print_uint8_t(in_buf
, in_size
);
1705 printf("Failed on compress multi pass\n");
1714 int test_inflate(struct vect_result
*in_vector
)
1716 int ret
= IGZIP_COMP_OK
;
1717 uint8_t *compress_buf
= in_vector
->vector
, *out_buf
= NULL
;
1718 uint64_t compress_len
= in_vector
->vector_length
;
1719 uint32_t out_size
= 0;
1721 out_size
= 10 * in_vector
->vector_length
;
1722 out_buf
= malloc(out_size
);
1723 if (out_buf
== NULL
)
1724 return MALLOC_FAILED
;
1726 ret
= inflate_stateless_pass(compress_buf
, compress_len
, out_buf
, &out_size
, 0);
1728 if (ret
== INFLATE_LEFTOVER_INPUT
)
1729 ret
= ISAL_DECOMP_OK
;
1731 if (ret
!= in_vector
->expected_error
)
1732 printf("Inflate return value incorrect, %d != %d\n", ret
,
1733 in_vector
->expected_error
);
1735 ret
= IGZIP_COMP_OK
;
1738 ret
= inflate_multi_pass(compress_buf
, compress_len
, out_buf
, &out_size
, 0);
1740 if (ret
== INFLATE_LEFTOVER_INPUT
)
1741 ret
= ISAL_DECOMP_OK
;
1743 if (ret
!= in_vector
->expected_error
)
1744 printf("Inflate return value incorrect, %d != %d\n", ret
,
1745 in_vector
->expected_error
);
1747 ret
= IGZIP_COMP_OK
;
1754 int get_filesize(FILE * f
)
1758 curr
= ftell(f
); /* Save current position */
1759 fseek(f
, 0L, SEEK_END
);
1761 fseek(f
, curr
, SEEK_SET
); /* Restore position */
1765 /* Run multiple compression tests on data stored in a file */
1766 int test_compress_file(char *file_name
)
1768 int ret
= IGZIP_COMP_OK
;
1770 uint8_t *in_buf
= NULL
;
1771 FILE *in_file
= NULL
;
1773 in_file
= fopen(file_name
, "rb");
1775 return FILE_READ_FAILED
;
1777 in_size
= get_filesize(in_file
);
1779 in_buf
= malloc(in_size
);
1781 return MALLOC_FAILED
;
1782 fread(in_buf
, 1, in_size
, in_file
);
1785 ret
|= test_compress_stateless(in_buf
, in_size
, NO_FLUSH
);
1786 ret
|= test_compress_stateless(in_buf
, in_size
, SYNC_FLUSH
);
1787 ret
|= test_compress_stateless(in_buf
, in_size
, FULL_FLUSH
);
1788 ret
|= test_compress(in_buf
, in_size
, NO_FLUSH
);
1789 ret
|= test_compress(in_buf
, in_size
, SYNC_FLUSH
);
1790 ret
|= test_compress(in_buf
, in_size
, FULL_FLUSH
);
1791 ret
|= test_flush(in_buf
, in_size
);
1794 printf("Failed on file %s\n", file_name
);
1802 int create_custom_hufftables(struct isal_hufftables
*hufftables_custom
, int argc
, char *argv
[])
1804 long int file_length
;
1805 uint8_t *stream
= NULL
;
1806 struct isal_huff_histogram histogram
;
1809 memset(&histogram
, 0, sizeof(histogram
));
1812 printf("Processing %s\n", argv
[argc
- 1]);
1813 file
= fopen(argv
[argc
- 1], "r");
1815 printf("Error opening file\n");
1818 fseek(file
, 0, SEEK_END
);
1819 file_length
= ftell(file
);
1820 fseek(file
, 0, SEEK_SET
);
1821 file_length
-= ftell(file
);
1823 if (file_length
> 0) {
1824 stream
= malloc(file_length
);
1825 if (stream
== NULL
) {
1826 printf("Failed to allocate memory to read in file\n");
1832 fread(stream
, 1, file_length
, file
);
1835 printf("Error occurred when reading file\n");
1842 /* Create a histogram of frequency of symbols found in stream to
1843 * generate the huffman tree.*/
1844 isal_update_histogram(stream
, file_length
, &histogram
);
1847 if (stream
!= NULL
) {
1854 return isal_create_hufftables(hufftables_custom
, &histogram
);
1858 int main(int argc
, char *argv
[])
1860 int i
= 0, ret
= 0, fin_ret
= 0;
1861 uint32_t in_size
= 0, offset
= 0;
1863 struct isal_hufftables hufftables_custom
;
1866 setbuf(stdout
, NULL
);
1869 printf("Window Size: %d K\n", IGZIP_HIST_SIZE
/ 1024);
1870 printf("Test Seed : %d\n", TEST_SEED
);
1871 printf("Randoms : %d\n", RANDOMS
);
1875 ret
= create_custom_hufftables(&hufftables_custom
, argc
, argv
);
1877 hufftables
= &hufftables_custom
;
1879 printf("Failed to generate custom hufftable");
1884 in_buf
= malloc(IBUF_SIZE
);
1885 memset(in_buf
, 0, IBUF_SIZE
);
1887 if (in_buf
== NULL
) {
1888 fprintf(stderr
, "Can't allocate in_buf memory\n");
1893 printf("igzip_rand_test files: ");
1895 for (i
= 1; i
< argc
; i
++) {
1896 ret
|= test_compress_file(argv
[i
]);
1901 printf("................");
1902 printf("%s\n", ret
? "Fail" : "Pass");
1906 printf("igzip_rand_test stateless: ");
1908 ret
= test_compress_stateless((uint8_t *) str1
, sizeof(str1
), NO_FLUSH
);
1912 ret
|= test_compress_stateless((uint8_t *) str2
, sizeof(str2
), NO_FLUSH
);
1916 for (i
= 0; i
< RANDOMS
; i
++) {
1917 in_size
= rand() % (IBUF_SIZE
+ 1);
1918 offset
= rand() % (IBUF_SIZE
+ 1 - in_size
);
1921 create_rand_repeat_data(in_buf
, in_size
);
1923 ret
|= test_compress_stateless(in_buf
, in_size
, NO_FLUSH
);
1927 if (i
% (RANDOMS
/ 16) == 0)
1934 for (i
= 0; i
< RANDOMS
/ 16; i
++) {
1935 create_rand_repeat_data(in_buf
, PAGE_SIZE
);
1936 ret
|= test_compress_stateless(in_buf
, PAGE_SIZE
, NO_FLUSH
); // good for efence
1943 ret
= test_compress_stateless((uint8_t *) str1
, sizeof(str1
), SYNC_FLUSH
);
1947 ret
|= test_compress_stateless((uint8_t *) str2
, sizeof(str2
), SYNC_FLUSH
);
1951 for (i
= 0; i
< 16; i
++) {
1952 in_size
= rand() % (IBUF_SIZE
+ 1);
1953 offset
= rand() % (IBUF_SIZE
+ 1 - in_size
);
1956 create_rand_repeat_data(in_buf
, in_size
);
1958 ret
|= test_compress_stateless(in_buf
, in_size
, SYNC_FLUSH
);
1968 printf("%s\n", ret
? "Fail" : "Pass");
1970 printf("igzip_rand_test stateless FULL_FLUSH: ");
1972 ret
= test_compress_stateless((uint8_t *) str1
, sizeof(str1
), FULL_FLUSH
);
1976 ret
|= test_compress_stateless((uint8_t *) str2
, sizeof(str2
), FULL_FLUSH
);
1980 for (i
= 0; i
< RANDOMS
; i
++) {
1981 in_size
= rand() % (IBUF_SIZE
+ 1);
1982 offset
= rand() % (IBUF_SIZE
+ 1 - in_size
);
1985 create_rand_repeat_data(in_buf
, in_size
);
1987 ret
|= test_compress_stateless(in_buf
, in_size
, FULL_FLUSH
);
1991 if (i
% (RANDOMS
/ 16) == 0)
1998 for (i
= 0; i
< RANDOMS
/ 16; i
++) {
1999 create_rand_repeat_data(in_buf
, PAGE_SIZE
);
2000 ret
|= test_compress_stateless(in_buf
, PAGE_SIZE
, FULL_FLUSH
); // good for efence
2006 printf("%s\n", ret
? "Fail" : "Pass");
2008 printf("igzip_rand_test stateful NO_FLUSH: ");
2010 ret
= test_compress((uint8_t *) str1
, sizeof(str1
), NO_FLUSH
);
2014 ret
|= test_compress((uint8_t *) str2
, sizeof(str2
), NO_FLUSH
);
2018 for (i
= 0; i
< RANDOMS
; i
++) {
2019 in_size
= rand() % (IBUF_SIZE
+ 1);
2020 offset
= rand() % (IBUF_SIZE
+ 1 - in_size
);
2023 create_rand_repeat_data(in_buf
, in_size
);
2025 ret
|= test_compress(in_buf
, in_size
, NO_FLUSH
);
2029 if (i
% (RANDOMS
/ 16) == 0)
2037 printf("%s\n", ret
? "Fail" : "Pass");
2039 printf("igzip_rand_test stateful SYNC_FLUSH: ");
2041 ret
= test_compress((uint8_t *) str1
, sizeof(str1
), SYNC_FLUSH
);
2045 ret
|= test_compress((uint8_t *) str2
, sizeof(str2
), SYNC_FLUSH
);
2049 for (i
= 0; i
< RANDOMS
; i
++) {
2050 in_size
= rand() % (IBUF_SIZE
+ 1);
2051 offset
= rand() % (IBUF_SIZE
+ 1 - in_size
);
2054 create_rand_repeat_data(in_buf
, in_size
);
2056 ret
|= test_compress(in_buf
, in_size
, SYNC_FLUSH
);
2060 if (i
% (RANDOMS
/ 16) == 0)
2068 printf("%s\n", ret
? "Fail" : "Pass");
2070 printf("igzip_rand_test stateful FULL_FLUSH: ");
2072 ret
= test_compress((uint8_t *) str1
, sizeof(str1
), FULL_FLUSH
);
2076 ret
|= test_compress((uint8_t *) str2
, sizeof(str2
), FULL_FLUSH
);
2080 for (i
= 0; i
< RANDOMS
; i
++) {
2081 in_size
= rand() % (IBUF_SIZE
+ 1);
2082 offset
= rand() % (IBUF_SIZE
+ 1 - in_size
);
2085 create_rand_repeat_data(in_buf
, in_size
);
2087 ret
|= test_compress(in_buf
, in_size
, FULL_FLUSH
);
2091 if (i
% (RANDOMS
/ 16) == 0)
2097 for (i
= 0; i
< RANDOMS
/ 8; i
++) {
2098 in_size
= rand() % (IBUF_SIZE
+ 1);
2099 offset
= rand() % (IBUF_SIZE
+ 1 - in_size
);
2102 create_rand_repeat_data(in_buf
, in_size
);
2104 ret
|= test_full_flush(in_buf
, in_size
);
2114 printf("%s\n", ret
? "Fail" : "Pass");
2116 printf("igzip_rand_test stateful Change Flush: ");
2118 ret
= test_flush((uint8_t *) str1
, sizeof(str1
));
2122 ret
|= test_flush((uint8_t *) str2
, sizeof(str2
));
2126 for (i
= 0; i
< RANDOMS
/ 4; i
++) {
2127 in_size
= rand() % (IBUF_SIZE
+ 1);
2128 offset
= rand() % (IBUF_SIZE
+ 1 - in_size
);
2131 create_rand_repeat_data(in_buf
, in_size
);
2133 ret
|= test_flush(in_buf
, in_size
);
2137 if (i
% ((RANDOMS
/ 4) / 16) == 0)
2145 printf("%s\n", ret
? "Fail" : "Pass");
2147 printf("igzip_rand_test inflate Std Vectors: ");
2149 for (i
= 0; i
< sizeof(std_vect_array
) / sizeof(struct vect_result
); i
++) {
2150 ret
= test_inflate(&std_vect_array
[i
]);
2154 printf("................");
2155 printf("%s\n", ret
? "Fail" : "Pass");
2157 printf("igzip rand test finished: %s\n",
2158 fin_ret
? "Some tests failed" : "All tests passed");
2160 return fin_ret
!= IGZIP_COMP_OK
;