1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#include <stdio.h>
#include <string.h>
#include "tinfl.c"
// Checks to see if the first block of data in in_buf is valid zlib compressed data.
// Returns 1 if valid, 0 if invalid.
int is_valid_zlib_data(char *in_buf, size_t in_buf_size);
#define BLOCK_SIZE (32*1024)
char *inflate_block(char *buf, size_t buf_size)
{
size_t out_size = BLOCK_SIZE;
return (char *) tinfl_decompress_mem_to_heap((const void *) buf, buf_size, (size_t *) &out_size, 0);
}
/* CJH */
int is_deflated_callback(const void *pBuf, int len, void *pUser)
{
int *decomp_size = pUser;
*decomp_size += len;
if(len > 0)
{
return 1;
}
return 0;
}
/*
* Tries to determine if a given buffer contains valid deflated data.
*
* @buf - The buffer of data to check for deflated data.
* @buf_size - The size of @buf.
* @includes_zlib_header - Set to 1 if the buffer should start with a valid zlib header.
*
* Returns the size of the inflated data if @buf inflated to a value larger than 32KB,
* or if it contained a valid zlib header/footer; else, returns 0.
*
* Thus, it is recommended to provide more than 32KB of data in @buf for the most accurate results.
*/
int is_deflated(char *buf, size_t buf_size, int includes_zlib_header)
{
int flags = TINFL_FLAG_HAS_MORE_INPUT;
int retval = 0, decomp_size = 0;
if(includes_zlib_header)
{
flags |= TINFL_FLAG_PARSE_ZLIB_HEADER | TINFL_FLAG_COMPUTE_ADLER32;
}
retval = tinfl_decompress_mem_to_callback(buf, &buf_size, is_deflated_callback, (void *) &decomp_size, flags);
if(retval == 1 || decomp_size > BLOCK_SIZE)
{
return decomp_size;
}
return 0;
}
int inflate_raw_file_callback(const void *pBuf, int len, void *pUser)
{
if(fwrite(pBuf, 1, len, (FILE *) pUser) == len)
{
return 1;
}
return 0;
}
/* Inflates a file containing raw deflated data.
*
* @in_file - Input file containing raw deflated data.
* @out_file - Output file where inflated data will be saved.
*
* Returns void.
*/
void inflate_raw_file(char *in_file, char *out_file)
{
char *compressed_data = NULL;
size_t in_size = 0, nbytes = 0;
FILE *fp_in = NULL, *fp_out = NULL;
fp_in = fopen(in_file, "rb");
if(fp_in)
{
fp_out = fopen(out_file, "wb");
if(fp_out)
{
fseek(fp_in, 0L, SEEK_END);
in_size = ftell(fp_in);
fseek(fp_in, 0L, SEEK_SET);
compressed_data = malloc(in_size);
if(compressed_data)
{
memset(compressed_data, 0, in_size);
nbytes = fread(compressed_data, 1, in_size, fp_in);
if(nbytes > 0)
{
tinfl_decompress_mem_to_callback(compressed_data, &nbytes, inflate_raw_file_callback, (void *) fp_out, 0);
}
free(compressed_data);
}
}
}
if(fp_in) fclose(fp_in);
if(fp_out) fclose(fp_out);
return;
}
#ifdef MAIN
int main(int argc, char *argv[])
{
if(argc != 3)
{
fprintf(stderr, "Usage: %s <input file> <output file>\n", argv[0]);
return EXIT_FAILURE;
}
inflate_raw_file(argv[1], argv[2]);
return EXIT_SUCCESS;
}
#endif