|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include <stdio.h> |
|
#include <stdint.h> |
|
#include <inttypes.h> |
|
#include <stdbool.h> |
|
#include <lzma.h> |
|
|
|
|
|
|
|
|
|
|
|
#define COMPRESSION_LEVEL 6 |
|
|
|
|
|
#define COMPRESSION_EXTREME true |
|
|
|
|
|
#define INTEGRITY_CHECK LZMA_CHECK_CRC64 |
|
|
|
|
|
|
|
#define IN_BUF_MAX 4096 |
|
#define OUT_BUF_MAX 4096 |
|
|
|
|
|
#define RET_OK 0 |
|
#define RET_ERROR_INIT 1 |
|
#define RET_ERROR_INPUT 2 |
|
#define RET_ERROR_OUTPUT 3 |
|
#define RET_ERROR_COMPRESSION 4 |
|
|
|
|
|
|
|
int xz_compress (FILE *in_file, FILE *out_file) |
|
{ |
|
uint32_t preset = COMPRESSION_LEVEL | (COMPRESSION_EXTREME ? LZMA_PRESET_EXTREME : 0); |
|
lzma_check check = INTEGRITY_CHECK; |
|
lzma_stream strm = LZMA_STREAM_INIT; |
|
uint8_t in_buf [IN_BUF_MAX]; |
|
uint8_t out_buf [OUT_BUF_MAX]; |
|
size_t in_len; |
|
size_t out_len; |
|
bool in_finished = false; |
|
bool out_finished = false; |
|
lzma_action action; |
|
lzma_ret ret_xz; |
|
int ret; |
|
|
|
ret = RET_OK; |
|
|
|
|
|
ret_xz = lzma_easy_encoder (&strm, preset, check); |
|
if (ret_xz != LZMA_OK) { |
|
fprintf (stderr, "lzma_easy_encoder error: %d\n", (int) ret_xz); |
|
return RET_ERROR_INIT; |
|
} |
|
|
|
while ((! in_finished) && (! out_finished)) { |
|
|
|
in_len = fread (in_buf, 1, IN_BUF_MAX, in_file); |
|
|
|
if (feof (in_file)) { |
|
in_finished = true; |
|
} |
|
if (ferror (in_file)) { |
|
in_finished = true; |
|
ret = RET_ERROR_INPUT; |
|
} |
|
|
|
strm.next_in = in_buf; |
|
strm.avail_in = in_len; |
|
|
|
|
|
|
|
|
|
action = in_finished ? LZMA_FINISH : LZMA_RUN; |
|
|
|
|
|
do { |
|
|
|
strm.next_out = out_buf; |
|
strm.avail_out = OUT_BUF_MAX; |
|
|
|
|
|
ret_xz = lzma_code (&strm, action); |
|
|
|
if ((ret_xz != LZMA_OK) && (ret_xz != LZMA_STREAM_END)) { |
|
fprintf (stderr, "lzma_code error: %d\n", (int) ret_xz); |
|
out_finished = true; |
|
ret = RET_ERROR_COMPRESSION; |
|
} else { |
|
|
|
out_len = OUT_BUF_MAX - strm.avail_out; |
|
fwrite (out_buf, 1, out_len, out_file); |
|
if (ferror (out_file)) { |
|
out_finished = true; |
|
ret = RET_ERROR_OUTPUT; |
|
} |
|
} |
|
} while (strm.avail_out == 0); |
|
} |
|
|
|
lzma_end (&strm); |
|
return ret; |
|
} |
|
|
|
int main () |
|
{ |
|
int ret; |
|
|
|
ret = xz_compress (stdin, stdout); |
|
return ret; |
|
} |
|
|
|
|