1660f49b0SGreg Tucker /**********************************************************************
2660f49b0SGreg Tucker Copyright(c) 2011-2016 Intel Corporation All rights reserved.
3660f49b0SGreg Tucker
4660f49b0SGreg Tucker Redistribution and use in source and binary forms, with or without
5660f49b0SGreg Tucker modification, are permitted provided that the following conditions
6660f49b0SGreg Tucker are met:
7660f49b0SGreg Tucker * Redistributions of source code must retain the above copyright
8660f49b0SGreg Tucker notice, this list of conditions and the following disclaimer.
9660f49b0SGreg Tucker * Redistributions in binary form must reproduce the above copyright
10660f49b0SGreg Tucker notice, this list of conditions and the following disclaimer in
11660f49b0SGreg Tucker the documentation and/or other materials provided with the
12660f49b0SGreg Tucker distribution.
13660f49b0SGreg Tucker * Neither the name of Intel Corporation nor the names of its
14660f49b0SGreg Tucker contributors may be used to endorse or promote products derived
15660f49b0SGreg Tucker from this software without specific prior written permission.
16660f49b0SGreg Tucker
17660f49b0SGreg Tucker THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18660f49b0SGreg Tucker "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19660f49b0SGreg Tucker LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20660f49b0SGreg Tucker A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21660f49b0SGreg Tucker OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22660f49b0SGreg Tucker SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23660f49b0SGreg Tucker LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24660f49b0SGreg Tucker DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25660f49b0SGreg Tucker THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26660f49b0SGreg Tucker (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27660f49b0SGreg Tucker OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28660f49b0SGreg Tucker **********************************************************************/
29660f49b0SGreg Tucker
3052f644d3SHailiang Wang #define _FILE_OFFSET_BITS 64
31660f49b0SGreg Tucker #include <stdint.h>
32660f49b0SGreg Tucker #include <stdio.h>
3357eed2f0SYibo Cai #include <stdlib.h>
34660f49b0SGreg Tucker #include <zlib.h>
3588f95d85SRoy Oursler #include "igzip_lib.h"
36660f49b0SGreg Tucker #include "huff_codes.h"
3752f644d3SHailiang Wang #include "test.h"
38660f49b0SGreg Tucker
39660f49b0SGreg Tucker /*Don't use file larger memory can support because compression and decompression
40660f49b0SGreg Tucker * are done in a stateless manner. */
41ff9c0c18SHailiang Wang #if __WORDSIZE == 64
42660f49b0SGreg Tucker #define MAX_INPUT_FILE_SIZE 2L * 1024L * 1024L * 1024L
43ff9c0c18SHailiang Wang #else
44ff9c0c18SHailiang Wang #define MAX_INPUT_FILE_SIZE 512L * 1024L * 1024L
45ff9c0c18SHailiang Wang #endif
46660f49b0SGreg Tucker
47*55fbfabfSMarcel Cornu int
inflate_multi_pass(uint8_t * compress_buf,uint64_t compress_len,uint8_t * uncompress_buf,uint32_t * uncompress_len)48*55fbfabfSMarcel Cornu inflate_multi_pass(uint8_t *compress_buf, uint64_t compress_len, uint8_t *uncompress_buf,
49*55fbfabfSMarcel Cornu uint32_t *uncompress_len)
50660f49b0SGreg Tucker {
51340e0f99SRoy Oursler struct inflate_state *state = NULL;
52340e0f99SRoy Oursler int ret = 0;
53340e0f99SRoy Oursler uint8_t *comp_tmp = NULL, *uncomp_tmp = NULL;
54340e0f99SRoy Oursler uint32_t comp_tmp_size = 0, uncomp_tmp_size = 0;
55340e0f99SRoy Oursler uint32_t comp_processed = 0, uncomp_processed = 0;
56340e0f99SRoy Oursler
57340e0f99SRoy Oursler state = malloc(sizeof(struct inflate_state));
58340e0f99SRoy Oursler if (state == NULL) {
59340e0f99SRoy Oursler printf("Failed to allocate memory\n");
60340e0f99SRoy Oursler exit(0);
61340e0f99SRoy Oursler }
62340e0f99SRoy Oursler
63340e0f99SRoy Oursler isal_inflate_init(state);
64340e0f99SRoy Oursler
65340e0f99SRoy Oursler state->next_in = NULL;
66340e0f99SRoy Oursler state->next_out = NULL;
67340e0f99SRoy Oursler state->avail_in = 0;
68340e0f99SRoy Oursler state->avail_out = 0;
69340e0f99SRoy Oursler
70340e0f99SRoy Oursler while (1) {
71340e0f99SRoy Oursler if (state->avail_in == 0) {
72340e0f99SRoy Oursler comp_tmp_size = rand() % (compress_len + 1);
73340e0f99SRoy Oursler
74340e0f99SRoy Oursler if (comp_tmp_size >= compress_len - comp_processed)
75340e0f99SRoy Oursler comp_tmp_size = compress_len - comp_processed;
76340e0f99SRoy Oursler
77340e0f99SRoy Oursler if (comp_tmp_size != 0) {
785a00eaecSTomasz Kantecki if (comp_tmp != NULL)
79340e0f99SRoy Oursler free(comp_tmp);
80340e0f99SRoy Oursler
81340e0f99SRoy Oursler comp_tmp = malloc(comp_tmp_size);
82340e0f99SRoy Oursler
83340e0f99SRoy Oursler if (comp_tmp == NULL) {
84340e0f99SRoy Oursler printf("Failed to allocate memory\n");
85340e0f99SRoy Oursler exit(0);
86340e0f99SRoy Oursler }
87340e0f99SRoy Oursler
88340e0f99SRoy Oursler memcpy(comp_tmp, compress_buf + comp_processed, comp_tmp_size);
89340e0f99SRoy Oursler comp_processed += comp_tmp_size;
90340e0f99SRoy Oursler
91340e0f99SRoy Oursler state->next_in = comp_tmp;
92340e0f99SRoy Oursler state->avail_in = comp_tmp_size;
93340e0f99SRoy Oursler }
94340e0f99SRoy Oursler }
95340e0f99SRoy Oursler
96340e0f99SRoy Oursler if (state->avail_out == 0) {
97340e0f99SRoy Oursler /* Save uncompressed data into uncompress_buf */
98340e0f99SRoy Oursler if (uncomp_tmp != NULL) {
99340e0f99SRoy Oursler memcpy(uncompress_buf + uncomp_processed, uncomp_tmp,
100340e0f99SRoy Oursler uncomp_tmp_size);
101340e0f99SRoy Oursler uncomp_processed += uncomp_tmp_size;
102340e0f99SRoy Oursler }
103340e0f99SRoy Oursler
104340e0f99SRoy Oursler uncomp_tmp_size = rand() % (*uncompress_len + 1);
105340e0f99SRoy Oursler
106340e0f99SRoy Oursler /* Limit size of buffer to be smaller than maximum */
107340e0f99SRoy Oursler if (uncomp_tmp_size > *uncompress_len - uncomp_processed)
108340e0f99SRoy Oursler uncomp_tmp_size = *uncompress_len - uncomp_processed;
109340e0f99SRoy Oursler
110340e0f99SRoy Oursler if (uncomp_tmp_size != 0) {
111340e0f99SRoy Oursler
112340e0f99SRoy Oursler if (uncomp_tmp != NULL) {
113340e0f99SRoy Oursler fflush(0);
114340e0f99SRoy Oursler free(uncomp_tmp);
115340e0f99SRoy Oursler }
116340e0f99SRoy Oursler
117340e0f99SRoy Oursler uncomp_tmp = malloc(uncomp_tmp_size);
118340e0f99SRoy Oursler if (uncomp_tmp == NULL) {
119340e0f99SRoy Oursler printf("Failed to allocate memory\n");
120340e0f99SRoy Oursler exit(0);
121340e0f99SRoy Oursler }
122340e0f99SRoy Oursler
123340e0f99SRoy Oursler state->avail_out = uncomp_tmp_size;
124340e0f99SRoy Oursler state->next_out = uncomp_tmp;
125340e0f99SRoy Oursler }
126340e0f99SRoy Oursler }
127340e0f99SRoy Oursler
128340e0f99SRoy Oursler ret = isal_inflate(state);
129340e0f99SRoy Oursler
130340e0f99SRoy Oursler if (state->block_state == ISAL_BLOCK_FINISH || ret != 0) {
131340e0f99SRoy Oursler memcpy(uncompress_buf + uncomp_processed, uncomp_tmp, uncomp_tmp_size);
132340e0f99SRoy Oursler *uncompress_len = state->total_out;
133340e0f99SRoy Oursler break;
134340e0f99SRoy Oursler }
135340e0f99SRoy Oursler }
136340e0f99SRoy Oursler
137340e0f99SRoy Oursler if (comp_tmp != NULL) {
138340e0f99SRoy Oursler free(comp_tmp);
139340e0f99SRoy Oursler comp_tmp = NULL;
140340e0f99SRoy Oursler }
141340e0f99SRoy Oursler if (uncomp_tmp != NULL) {
142340e0f99SRoy Oursler free(uncomp_tmp);
143340e0f99SRoy Oursler uncomp_tmp = NULL;
144340e0f99SRoy Oursler }
145340e0f99SRoy Oursler
146340e0f99SRoy Oursler free(state);
147340e0f99SRoy Oursler return ret;
148340e0f99SRoy Oursler }
149340e0f99SRoy Oursler
150*55fbfabfSMarcel Cornu int
test(uint8_t * compressed_stream,uint64_t * compressed_length,uint8_t * uncompressed_stream,uint32_t uncompressed_length,uint8_t * uncompressed_test_stream,uint32_t uncompressed_test_stream_length)151*55fbfabfSMarcel Cornu test(uint8_t *compressed_stream, uint64_t *compressed_length, uint8_t *uncompressed_stream,
152*55fbfabfSMarcel Cornu uint32_t uncompressed_length, uint8_t *uncompressed_test_stream,
153*55fbfabfSMarcel Cornu uint32_t uncompressed_test_stream_length)
154340e0f99SRoy Oursler {
155660f49b0SGreg Tucker int ret;
156*55fbfabfSMarcel Cornu ret = compress2(compressed_stream, (uLongf *) compressed_length, uncompressed_stream,
157*55fbfabfSMarcel Cornu uncompressed_length, 6);
158660f49b0SGreg Tucker if (ret) {
159660f49b0SGreg Tucker printf("Failed compressing input with exit code %d", ret);
160660f49b0SGreg Tucker return ret;
161660f49b0SGreg Tucker }
162660f49b0SGreg Tucker
163*55fbfabfSMarcel Cornu ret = inflate_multi_pass(compressed_stream + 2, *compressed_length - 2 - 4,
164340e0f99SRoy Oursler uncompressed_test_stream, &uncompressed_test_stream_length);
165660f49b0SGreg Tucker switch (ret) {
166660f49b0SGreg Tucker case 0:
167660f49b0SGreg Tucker break;
16888f95d85SRoy Oursler case ISAL_END_INPUT:
169660f49b0SGreg Tucker printf(" did not decompress all input\n");
17088f95d85SRoy Oursler return ISAL_END_INPUT;
171660f49b0SGreg Tucker break;
17288f95d85SRoy Oursler case ISAL_INVALID_BLOCK:
173660f49b0SGreg Tucker printf(" invalid header\n");
17488f95d85SRoy Oursler return ISAL_INVALID_BLOCK;
175660f49b0SGreg Tucker break;
17688f95d85SRoy Oursler case ISAL_INVALID_SYMBOL:
177660f49b0SGreg Tucker printf(" invalid symbol\n");
17888f95d85SRoy Oursler return ISAL_INVALID_SYMBOL;
179660f49b0SGreg Tucker break;
18088f95d85SRoy Oursler case ISAL_OUT_OVERFLOW:
181660f49b0SGreg Tucker printf(" out buffer overflow\n");
18288f95d85SRoy Oursler return ISAL_OUT_OVERFLOW;
183660f49b0SGreg Tucker break;
18488f95d85SRoy Oursler case ISAL_INVALID_LOOKBACK:
185660f49b0SGreg Tucker printf("Invalid lookback distance");
18688f95d85SRoy Oursler return ISAL_INVALID_LOOKBACK;
187660f49b0SGreg Tucker break;
188660f49b0SGreg Tucker default:
189660f49b0SGreg Tucker printf(" error\n");
190660f49b0SGreg Tucker return -1;
191660f49b0SGreg Tucker break;
192660f49b0SGreg Tucker }
193660f49b0SGreg Tucker
194340e0f99SRoy Oursler if (uncompressed_test_stream_length != uncompressed_length) {
195660f49b0SGreg Tucker printf("incorrect amount of data was decompressed from compressed data\n");
196*55fbfabfSMarcel Cornu printf("%d decompressed of %d compressed", uncompressed_test_stream_length,
197*55fbfabfSMarcel Cornu uncompressed_length);
198660f49b0SGreg Tucker return -1;
199660f49b0SGreg Tucker }
200660f49b0SGreg Tucker if (memcmp(uncompressed_stream, uncompressed_test_stream, uncompressed_length)) {
20109a5a243SRoy Oursler int i;
20209a5a243SRoy Oursler for (i = 0; i < uncompressed_length; i++) {
20309a5a243SRoy Oursler if (uncompressed_stream[i] != uncompressed_test_stream[i]) {
20409a5a243SRoy Oursler printf("first error at %d, 0x%x != 0x%x\n", i,
20509a5a243SRoy Oursler uncompressed_stream[i], uncompressed_test_stream[i]);
20609a5a243SRoy Oursler }
20709a5a243SRoy Oursler }
208660f49b0SGreg Tucker printf(" decompressed data is not the same as the compressed data\n");
209660f49b0SGreg Tucker return -1;
210660f49b0SGreg Tucker }
211340e0f99SRoy Oursler
212660f49b0SGreg Tucker return 0;
213660f49b0SGreg Tucker }
214660f49b0SGreg Tucker
215*55fbfabfSMarcel Cornu int
main(int argc,char ** argv)216*55fbfabfSMarcel Cornu main(int argc, char **argv)
217660f49b0SGreg Tucker {
218660f49b0SGreg Tucker int i, j, ret = 0, fin_ret = 0;
21909a5a243SRoy Oursler FILE *file = NULL;
22009a5a243SRoy Oursler uint64_t compressed_length, file_length;
22109a5a243SRoy Oursler uint64_t uncompressed_length, uncompressed_test_stream_length;
22209a5a243SRoy Oursler uint8_t *uncompressed_stream = NULL;
22309a5a243SRoy Oursler uint8_t *compressed_stream = NULL;
22409a5a243SRoy Oursler uint8_t *uncompressed_test_stream = NULL;
225660f49b0SGreg Tucker
226660f49b0SGreg Tucker if (argc == 1)
227660f49b0SGreg Tucker printf("Error, no input file\n");
228660f49b0SGreg Tucker for (i = 1; i < argc; i++) {
2291a7c640eSRoy Oursler
2301a7c640eSRoy Oursler file = NULL;
2311a7c640eSRoy Oursler uncompressed_stream = NULL;
2321a7c640eSRoy Oursler compressed_stream = NULL;
2331a7c640eSRoy Oursler uncompressed_test_stream = NULL;
2341a7c640eSRoy Oursler
235660f49b0SGreg Tucker file = fopen(argv[i], "r");
236660f49b0SGreg Tucker if (file == NULL) {
237660f49b0SGreg Tucker printf("Error opening file %s\n", argv[i]);
238660f49b0SGreg Tucker return 1;
239660f49b0SGreg Tucker } else
240660f49b0SGreg Tucker printf("Starting file %s", argv[i]);
241340e0f99SRoy Oursler fflush(0);
24252f644d3SHailiang Wang file_length = get_filesize(file);
243660f49b0SGreg Tucker if (file_length > MAX_INPUT_FILE_SIZE) {
244ff9c0c18SHailiang Wang printf("\nFile too large to run on this test,"
245ff9c0c18SHailiang Wang " Max 512MB for 32bit OS, 2GB for 64bit OS.\n");
246ff9c0c18SHailiang Wang printf(" ... Fail\n");
247660f49b0SGreg Tucker fclose(file);
248660f49b0SGreg Tucker continue;
249660f49b0SGreg Tucker }
250660f49b0SGreg Tucker
25109a5a243SRoy Oursler compressed_length = compressBound(file_length);
2521a7c640eSRoy Oursler
25309a5a243SRoy Oursler if (file_length != 0) {
25409a5a243SRoy Oursler uncompressed_stream = malloc(file_length);
25509a5a243SRoy Oursler uncompressed_test_stream = malloc(file_length);
25609a5a243SRoy Oursler }
2571a7c640eSRoy Oursler
25809a5a243SRoy Oursler compressed_stream = malloc(compressed_length);
25909a5a243SRoy Oursler if (uncompressed_stream == NULL && file_length != 0) {
2601a7c640eSRoy Oursler printf("\nFailed to allocate input memory\n");
261660f49b0SGreg Tucker exit(0);
262660f49b0SGreg Tucker }
263660f49b0SGreg Tucker
264660f49b0SGreg Tucker if (compressed_stream == NULL) {
2651a7c640eSRoy Oursler printf("\nFailed to allocate output memory\n");
266660f49b0SGreg Tucker exit(0);
267660f49b0SGreg Tucker }
268660f49b0SGreg Tucker
2691a7c640eSRoy Oursler if (uncompressed_test_stream == NULL && file_length != 0) {
2701a7c640eSRoy Oursler printf("\nFailed to allocate decompressed memory\n");
271660f49b0SGreg Tucker exit(0);
272660f49b0SGreg Tucker }
273660f49b0SGreg Tucker
274*55fbfabfSMarcel Cornu uncompressed_length = (uncompressed_stream == NULL)
275*55fbfabfSMarcel Cornu ? 0
276*55fbfabfSMarcel Cornu : fread(uncompressed_stream, 1, file_length, file);
277456be4cfSRoy Oursler uncompressed_test_stream_length = uncompressed_length;
278*55fbfabfSMarcel Cornu ret = test(compressed_stream, &compressed_length, uncompressed_stream,
27909a5a243SRoy Oursler uncompressed_length, uncompressed_test_stream,
28009a5a243SRoy Oursler uncompressed_test_stream_length);
281660f49b0SGreg Tucker if (ret) {
282660f49b0SGreg Tucker for (j = 0; j < compressed_length; j++) {
283660f49b0SGreg Tucker if ((j & 31) == 0)
284660f49b0SGreg Tucker printf("\n");
285660f49b0SGreg Tucker else
286660f49b0SGreg Tucker printf(" ");
287660f49b0SGreg Tucker printf("0x%02x,", compressed_stream[j]);
288660f49b0SGreg Tucker }
289660f49b0SGreg Tucker printf("\n");
290660f49b0SGreg Tucker }
291660f49b0SGreg Tucker
29209a5a243SRoy Oursler fflush(0);
293660f49b0SGreg Tucker fclose(file);
2941a7c640eSRoy Oursler if (compressed_stream != NULL)
295660f49b0SGreg Tucker free(compressed_stream);
29609a5a243SRoy Oursler if (uncompressed_stream != NULL)
297660f49b0SGreg Tucker free(uncompressed_stream);
29809a5a243SRoy Oursler if (uncompressed_test_stream != NULL)
299660f49b0SGreg Tucker free(uncompressed_test_stream);
300660f49b0SGreg Tucker if (ret) {
301660f49b0SGreg Tucker printf(" ... Fail with exit code %d\n", ret);
302660f49b0SGreg Tucker return ret;
303660f49b0SGreg Tucker } else
304660f49b0SGreg Tucker printf(" ... Pass\n");
305660f49b0SGreg Tucker fin_ret |= ret;
306660f49b0SGreg Tucker }
307660f49b0SGreg Tucker return fin_ret;
308660f49b0SGreg Tucker }
309