xref: /isa-l/igzip/igzip_inflate_test.c (revision 55fbfabfc60f1002bc8133b730a59f6abd22cfce)
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