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