1 // example4.c - Uses tinfl.c to decompress a zlib stream in memory to an output file
2 // Public domain, May 15 2011, Rich Geldreich, richgel99@gmail.com. See "unlicense" statement at the end of tinfl.c.
3 #include "miniz_tinfl.h"
4 #include <stdio.h>
5 #include <limits.h>
6 
7 typedef unsigned char uint8;
8 typedef unsigned short uint16;
9 typedef unsigned int uint;
10 
11 #define my_max(a,b) (((a) > (b)) ? (a) : (b))
12 #define my_min(a,b) (((a) < (b)) ? (a) : (b))
13 
tinfl_put_buf_func(const void * pBuf,int len,void * pUser)14 static int tinfl_put_buf_func(const void* pBuf, int len, void *pUser)
15 {
16   return len == (int)fwrite(pBuf, 1, len, (FILE*)pUser);
17 }
18 
main(int argc,char * argv[])19 int main(int argc, char *argv[])
20 {
21   int status;
22   FILE *pInfile, *pOutfile;
23   uint infile_size, outfile_size;
24   size_t in_buf_size;
25   uint8 *pCmp_data;
26   long file_loc;
27 
28   if (argc != 3)
29   {
30     printf("Usage: example4 infile outfile\n");
31     printf("Decompresses zlib stream in file infile to file outfile.\n");
32     printf("Input file must be able to fit entirely in memory.\n");
33     printf("example3 can be used to create compressed zlib streams.\n");
34     return EXIT_FAILURE;
35   }
36 
37   // Open input file.
38   pInfile = fopen(argv[1], "rb");
39   if (!pInfile)
40   {
41     printf("Failed opening input file!\n");
42     return EXIT_FAILURE;
43   }
44 
45   // Determine input file's size.
46   fseek(pInfile, 0, SEEK_END);
47   file_loc = ftell(pInfile);
48   fseek(pInfile, 0, SEEK_SET);
49 
50   if ((file_loc < 0) || (file_loc > INT_MAX))
51   {
52      // This is not a limitation of miniz or tinfl, but this example.
53      printf("File is too large to be processed by this example.\n");
54      return EXIT_FAILURE;
55   }
56 
57   infile_size = (uint)file_loc;
58 
59   pCmp_data = (uint8 *)malloc(infile_size);
60   if (!pCmp_data)
61   {
62     printf("Out of memory!\n");
63     return EXIT_FAILURE;
64   }
65   if (fread(pCmp_data, 1, infile_size, pInfile) != infile_size)
66   {
67     printf("Failed reading input file!\n");
68     return EXIT_FAILURE;
69   }
70 
71   // Open output file.
72   pOutfile = fopen(argv[2], "wb");
73   if (!pOutfile)
74   {
75     printf("Failed opening output file!\n");
76     return EXIT_FAILURE;
77   }
78 
79   printf("Input file size: %u\n", infile_size);
80 
81   in_buf_size = infile_size;
82   status = tinfl_decompress_mem_to_callback(pCmp_data, &in_buf_size, tinfl_put_buf_func, pOutfile, TINFL_FLAG_PARSE_ZLIB_HEADER);
83   if (!status)
84   {
85     printf("tinfl_decompress_mem_to_callback() failed with status %i!\n", status);
86     return EXIT_FAILURE;
87   }
88 
89   outfile_size = ftell(pOutfile);
90 
91   fclose(pInfile);
92   if (EOF == fclose(pOutfile))
93   {
94     printf("Failed writing to output file!\n");
95     return EXIT_FAILURE;
96   }
97 
98   printf("Total input bytes: %u\n", (uint)in_buf_size);
99   printf("Total output bytes: %u\n", outfile_size);
100   printf("Success.\n");
101   return EXIT_SUCCESS;
102 }
103