4 * An example of using wimlib's compression API to decompress a file compressed
5 * with the compressfile.c program.
7 * This program does *not* have anything to do with WIM files other than the
8 * fact that this makes use of compression formats that are used in WIM files.
9 * This is purely an example of using the compression API.
13 * $ gcc decompressfile.c -o decompressfile -lwim
17 * $ ./decompressfile INFILE OUTFILE
21 * $ ./compressfile book.txt book.txt.lzms LZMS 1048576
23 * $ ./decompressfile book.txt.lzms book.txt
25 * The compressed file format created here is simply a series of compressed
26 * chunks. A real format would need to have checksums and other metadata.
28 * The author dedicates this file to the public domain.
29 * You can do whatever you want with this file.
33 #define _FILE_OFFSET_BITS 64
46 do_decompress(int in_fd, const char *in_filename,
47 int out_fd, const char *out_filename,
48 uint32_t chunk_size, struct wimlib_decompressor *decompressor)
52 char *ubuf = malloc(chunk_size);
53 char *cbuf = malloc(chunk_size - 1);
55 for (chunk_num = 1; ; chunk_num++) {
60 /* Read chunk uncompressed and compressed sizes. */
61 bytes_read = read(in_fd, &usize, sizeof(uint32_t));
65 if (bytes_read != sizeof(uint32_t) ||
66 read(in_fd, &csize, sizeof(uint32_t)) != sizeof(uint32_t))
68 error(1, errno, "Error reading \"%s\"", in_filename);
71 if (csize > usize || usize > chunk_size)
72 error(1, 0, "The data is invalid!");
75 if (read(in_fd, ubuf, usize) != usize) {
76 error(1, errno, "Error reading \"%s\"",
80 if (read(in_fd, cbuf, csize) != csize) {
81 error(1, errno, "Error reading \"%s\"",
85 if (wimlib_decompress(cbuf, csize, ubuf, usize,
88 error(1, 0, "The compressed data is invalid!");
92 printf("Chunk %"PRIu64": %"PRIu32" => %"PRIu32" bytes\n",
93 chunk_num, csize, usize);
95 /* Output the uncompressed chunk size, the compressed chunk
96 * size, then the chunk data. Note: a real program would need
97 * to output the chunk sizes in consistent endianness. */
98 if (write(out_fd, ubuf, usize) != usize)
99 error(1, errno, "Error writing to \"%s\"", out_filename);
105 int main(int argc, char **argv)
107 const char *in_filename;
108 const char *out_filename;
114 struct wimlib_decompressor *decompressor;
117 fprintf(stderr, "Usage: %s INFILE OUTFILE\n", argv[0]);
121 in_filename = argv[1];
122 out_filename = argv[2];
124 /* Open input file and output file. */
125 in_fd = open(in_filename, O_RDONLY);
127 error(1, errno, "Failed to open \"%s\"", in_filename);
128 out_fd = open(out_filename, O_WRONLY | O_TRUNC | O_CREAT, 0644);
130 error(1, errno, "Failed to open \"%s\"", out_filename);
132 /* Get compression type and chunk size. */
133 if (read(in_fd, &ctype, sizeof(uint32_t)) != sizeof(uint32_t) ||
134 read(in_fd, &chunk_size, sizeof(uint32_t)) != sizeof(uint32_t))
135 error(1, errno, "Error reading from \"%s\"", in_filename);
137 /* Create a decompressor for the compression type and chunk size with
138 * the default parameters. */
139 ret = wimlib_create_decompressor(ctype, chunk_size, NULL, &decompressor);
141 error(1, 0, "Failed to create decompressor: %s",
142 wimlib_get_error_string(ret));
144 /* Decompress and write the data. */
145 do_decompress(in_fd, in_filename,
146 out_fd, out_filename,
147 chunk_size, decompressor);
149 /* Cleanup and return. */
151 error(1, errno, "Error closing \"%s\"", out_filename);
152 wimlib_free_decompressor(decompressor);