| Index: doc/examples/03_compress_custom.c
|
| ===================================================================
|
| --- doc/examples/03_compress_custom.c (revision 0)
|
| +++ doc/examples/03_compress_custom.c (revision 0)
|
| @@ -0,0 +1,193 @@
|
| +///////////////////////////////////////////////////////////////////////////////
|
| +//
|
| +/// \file 03_compress_custom.c
|
| +/// \brief Compress in multi-call mode using x86 BCJ and LZMA2
|
| +///
|
| +/// Usage: ./03_compress_custom < INFILE > OUTFILE
|
| +///
|
| +/// Example: ./03_compress_custom < foo > foo.xz
|
| +//
|
| +// Author: Lasse Collin
|
| +//
|
| +// This file has been put into the public domain.
|
| +// You can do whatever you want with this file.
|
| +//
|
| +///////////////////////////////////////////////////////////////////////////////
|
| +
|
| +#include <stdbool.h>
|
| +#include <stdlib.h>
|
| +#include <stdio.h>
|
| +#include <string.h>
|
| +#include <errno.h>
|
| +#include <lzma.h>
|
| +
|
| +
|
| +static bool
|
| +init_encoder(lzma_stream *strm)
|
| +{
|
| + // Use the default preset (6) for LZMA2.
|
| + //
|
| + // The lzma_options_lzma structure and the lzma_lzma_preset() function
|
| + // are declared in lzma/lzma.h (src/liblzma/api/lzma/lzma.h in the
|
| + // source package or e.g. /usr/include/lzma/lzma.h depending on
|
| + // the install prefix).
|
| + lzma_options_lzma opt_lzma2;
|
| + if (lzma_lzma_preset(&opt_lzma2, LZMA_PRESET_DEFAULT)) {
|
| + // It should never fail because the default preset
|
| + // (and presets 0-9 optionally with LZMA_PRESET_EXTREME)
|
| + // are supported by all stable liblzma versions.
|
| + //
|
| + // (The encoder initialization later in this function may
|
| + // still fail due to unsupported preset *if* the features
|
| + // required by the preset have been disabled at build time,
|
| + // but no-one does such things except on embedded systems.)
|
| + fprintf(stderr, "Unsupported preset, possibly a bug\n");
|
| + return false;
|
| + }
|
| +
|
| + // Now we could customize the LZMA2 options if we wanted. For example,
|
| + // we could set the the dictionary size (opt_lzma2.dict_size) to
|
| + // something else than the default (8 MiB) of the default preset.
|
| + // See lzma/lzma.h for details of all LZMA2 options.
|
| + //
|
| + // The x86 BCJ filter will try to modify the x86 instruction stream so
|
| + // that LZMA2 can compress it better. The x86 BCJ filter doesn't need
|
| + // any options so it will be set to NULL below.
|
| + //
|
| + // Construct the filter chain. The uncompressed data goes first to
|
| + // the first filter in the array, in this case the x86 BCJ filter.
|
| + // The array is always terminated by setting .id = LZMA_VLI_UNKNOWN.
|
| + //
|
| + // See lzma/filter.h for more information about the lzma_filter
|
| + // structure.
|
| + lzma_filter filters[] = {
|
| + { .id = LZMA_FILTER_X86, .options = NULL },
|
| + { .id = LZMA_FILTER_LZMA2, .options = &opt_lzma2 },
|
| + { .id = LZMA_VLI_UNKNOWN, .options = NULL },
|
| + };
|
| +
|
| + // Initialize the encoder using the custom filter chain.
|
| + lzma_ret ret = lzma_stream_encoder(strm, filters, LZMA_CHECK_CRC64);
|
| +
|
| + if (ret == LZMA_OK)
|
| + return true;
|
| +
|
| + const char *msg;
|
| + switch (ret) {
|
| + case LZMA_MEM_ERROR:
|
| + msg = "Memory allocation failed";
|
| + break;
|
| +
|
| + case LZMA_OPTIONS_ERROR:
|
| + // We are no longer using a plain preset so this error
|
| + // message has been edited accordingly compared to
|
| + // 01_compress_easy.c.
|
| + msg = "Specified filter chain is not supported";
|
| + break;
|
| +
|
| + case LZMA_UNSUPPORTED_CHECK:
|
| + msg = "Specified integrity check is not supported";
|
| + break;
|
| +
|
| + default:
|
| + msg = "Unknown error, possibly a bug";
|
| + break;
|
| + }
|
| +
|
| + fprintf(stderr, "Error initializing the encoder: %s (error code %u)\n",
|
| + msg, ret);
|
| + return false;
|
| +}
|
| +
|
| +
|
| +// This function is identical to the one in 01_compress_easy.c.
|
| +static bool
|
| +compress(lzma_stream *strm, FILE *infile, FILE *outfile)
|
| +{
|
| + lzma_action action = LZMA_RUN;
|
| +
|
| + uint8_t inbuf[BUFSIZ];
|
| + uint8_t outbuf[BUFSIZ];
|
| +
|
| + strm->next_in = NULL;
|
| + strm->avail_in = 0;
|
| + strm->next_out = outbuf;
|
| + strm->avail_out = sizeof(outbuf);
|
| +
|
| + while (true) {
|
| + if (strm->avail_in == 0 && !feof(infile)) {
|
| + strm->next_in = inbuf;
|
| + strm->avail_in = fread(inbuf, 1, sizeof(inbuf),
|
| + infile);
|
| +
|
| + if (ferror(infile)) {
|
| + fprintf(stderr, "Read error: %s\n",
|
| + strerror(errno));
|
| + return false;
|
| + }
|
| +
|
| + if (feof(infile))
|
| + action = LZMA_FINISH;
|
| + }
|
| +
|
| + lzma_ret ret = lzma_code(strm, action);
|
| +
|
| + if (strm->avail_out == 0 || ret == LZMA_STREAM_END) {
|
| + size_t write_size = sizeof(outbuf) - strm->avail_out;
|
| +
|
| + if (fwrite(outbuf, 1, write_size, outfile)
|
| + != write_size) {
|
| + fprintf(stderr, "Write error: %s\n",
|
| + strerror(errno));
|
| + return false;
|
| + }
|
| +
|
| + strm->next_out = outbuf;
|
| + strm->avail_out = sizeof(outbuf);
|
| + }
|
| +
|
| + if (ret != LZMA_OK) {
|
| + if (ret == LZMA_STREAM_END)
|
| + return true;
|
| +
|
| + const char *msg;
|
| + switch (ret) {
|
| + case LZMA_MEM_ERROR:
|
| + msg = "Memory allocation failed";
|
| + break;
|
| +
|
| + case LZMA_DATA_ERROR:
|
| + msg = "File size limits exceeded";
|
| + break;
|
| +
|
| + default:
|
| + msg = "Unknown error, possibly a bug";
|
| + break;
|
| + }
|
| +
|
| + fprintf(stderr, "Encoder error: %s (error code %u)\n",
|
| + msg, ret);
|
| + return false;
|
| + }
|
| + }
|
| +}
|
| +
|
| +
|
| +extern int
|
| +main(void)
|
| +{
|
| + lzma_stream strm = LZMA_STREAM_INIT;
|
| +
|
| + bool success = init_encoder(&strm);
|
| + if (success)
|
| + success = compress(&strm, stdin, stdout);
|
| +
|
| + lzma_end(&strm);
|
| +
|
| + if (fclose(stdout)) {
|
| + fprintf(stderr, "Write error: %s\n", strerror(errno));
|
| + success = false;
|
| + }
|
| +
|
| + return success ? EXIT_SUCCESS : EXIT_FAILURE;
|
| +}
|
|
|
| Property changes on: doc/examples/03_compress_custom.c
|
| ___________________________________________________________________
|
| Added: svn:eol-style
|
| + LF
|
|
|
|
|