1///////////////////////////////////////////////////////////////////////////////
2//
3/// \file       full_flush.c
4/// \brief      Encode files using LZMA_FULL_FLUSH
5//
6//  Author:     Lasse Collin
7//
8//  This file has been put into the public domain.
9//  You can do whatever you want with this file.
10//
11///////////////////////////////////////////////////////////////////////////////
12
13#include "sysdefs.h"
14#include "lzma.h"
15#include <stdio.h>
16
17
18static lzma_stream strm = LZMA_STREAM_INIT;
19static FILE *file_in;
20
21
22static void
23encode(size_t size, lzma_action action)
24{
25	static const size_t CHUNK = 64;
26	uint8_t in[CHUNK];
27	uint8_t out[CHUNK];
28	lzma_ret ret;
29
30	do {
31		if (strm.avail_in == 0 && size > 0) {
32			const size_t amount = my_min(size, CHUNK);
33			strm.avail_in = fread(in, 1, amount, file_in);
34			strm.next_in = in;
35			size -= amount; // Intentionally not using avail_in.
36		}
37
38		strm.next_out = out;
39		strm.avail_out = CHUNK;
40
41		ret = lzma_code(&strm, size == 0 ? action : LZMA_RUN);
42
43		if (ret != LZMA_OK && ret != LZMA_STREAM_END) {
44			fprintf(stderr, "%s:%u: %s: ret == %d\n",
45					__FILE__, __LINE__, __func__, ret);
46			exit(1);
47		}
48
49		fwrite(out, 1, CHUNK - strm.avail_out, stdout);
50
51	} while (size > 0 || strm.avail_out == 0);
52
53	if ((action == LZMA_RUN && ret != LZMA_OK)
54			|| (action != LZMA_RUN && ret != LZMA_STREAM_END)) {
55		fprintf(stderr, "%s:%u: %s: ret == %d\n",
56				__FILE__, __LINE__, __func__, ret);
57		exit(1);
58	}
59}
60
61
62int
63main(int argc, char **argv)
64{
65	file_in = argc > 1 ? fopen(argv[1], "rb") : stdin;
66
67
68	// Config
69	lzma_options_lzma opt_lzma;
70	if (lzma_lzma_preset(&opt_lzma, 1)) {
71		fprintf(stderr, "preset failed\n");
72		exit(1);
73	}
74	lzma_filter filters[LZMA_FILTERS_MAX + 1];
75	filters[0].id = LZMA_FILTER_LZMA2;
76	filters[0].options = &opt_lzma;
77	filters[1].id = LZMA_VLI_UNKNOWN;
78
79	// Init
80	if (lzma_stream_encoder(&strm, filters, LZMA_CHECK_CRC32) != LZMA_OK) {
81		fprintf(stderr, "init failed\n");
82		exit(1);
83	}
84
85// 	if (lzma_easy_encoder(&strm, 1)) {
86// 		fprintf(stderr, "init failed\n");
87// 		exit(1);
88// 	}
89
90	// Encoding
91	encode(0, LZMA_FULL_FLUSH);
92	encode(6, LZMA_FULL_FLUSH);
93	encode(0, LZMA_FULL_FLUSH);
94	encode(7, LZMA_FULL_FLUSH);
95	encode(0, LZMA_FULL_FLUSH);
96	encode(0, LZMA_FINISH);
97
98	// Clean up
99	lzma_end(&strm);
100
101	return 0;
102}
103