xz-utils (5.4.5)

(root)/
share/
doc/
xz/
examples_old/
xz_pipe_comp.c
       1  /*
       2   * xz_pipe_comp.c
       3   * A simple example of pipe-only xz compressor implementation.
       4   * version: 2010-07-12 - by Daniel Mealha Cabrita
       5   * Not copyrighted -- provided to the public domain.
       6   *
       7   * Compiling:
       8   * Link with liblzma. GCC example:
       9   * $ gcc -llzma xz_pipe_comp.c -o xz_pipe_comp
      10   *
      11   * Usage example:
      12   * $ cat some_file | ./xz_pipe_comp > some_file.xz
      13   */
      14  
      15  #include <stdio.h>
      16  #include <stdint.h>
      17  #include <inttypes.h>
      18  #include <stdbool.h>
      19  #include <lzma.h>
      20  
      21  
      22  /* COMPRESSION SETTINGS */
      23  
      24  /* analogous to xz CLI options: -0 to -9 */
      25  #define COMPRESSION_LEVEL 6
      26  
      27  /* boolean setting, analogous to xz CLI option: -e */
      28  #define COMPRESSION_EXTREME true
      29  
      30  /* see: /usr/include/lzma/check.h LZMA_CHECK_* */
      31  #define INTEGRITY_CHECK LZMA_CHECK_CRC64
      32  
      33  
      34  /* read/write buffer sizes */
      35  #define IN_BUF_MAX	4096
      36  #define OUT_BUF_MAX	4096
      37  
      38  /* error codes */
      39  #define RET_OK			0
      40  #define RET_ERROR_INIT		1
      41  #define RET_ERROR_INPUT		2
      42  #define RET_ERROR_OUTPUT	3
      43  #define RET_ERROR_COMPRESSION	4
      44  
      45  
      46  /* note: in_file and out_file must be open already */
      47  int xz_compress (FILE *in_file, FILE *out_file)
      48  {
      49  	uint32_t preset = COMPRESSION_LEVEL | (COMPRESSION_EXTREME ? LZMA_PRESET_EXTREME : 0);
      50  	lzma_check check = INTEGRITY_CHECK;
      51  	lzma_stream strm = LZMA_STREAM_INIT; /* alloc and init lzma_stream struct */
      52  	uint8_t in_buf [IN_BUF_MAX];
      53  	uint8_t out_buf [OUT_BUF_MAX];
      54  	size_t in_len;	/* length of useful data in in_buf */
      55  	size_t out_len;	/* length of useful data in out_buf */
      56  	bool in_finished = false;
      57  	bool out_finished = false;
      58  	lzma_action action;
      59  	lzma_ret ret_xz;
      60  	int ret;
      61  
      62  	ret = RET_OK;
      63  
      64  	/* initialize xz encoder */
      65  	ret_xz = lzma_easy_encoder (&strm, preset, check);
      66  	if (ret_xz != LZMA_OK) {
      67  		fprintf (stderr, "lzma_easy_encoder error: %d\n", (int) ret_xz);
      68  		return RET_ERROR_INIT;
      69  	}
      70  
      71  	while ((! in_finished) && (! out_finished)) {
      72  		/* read incoming data */
      73  		in_len = fread (in_buf, 1, IN_BUF_MAX, in_file);
      74  
      75  		if (feof (in_file)) {
      76  			in_finished = true;
      77  		}
      78  		if (ferror (in_file)) {
      79  			in_finished = true;
      80  			ret = RET_ERROR_INPUT;
      81  		}
      82  
      83  		strm.next_in = in_buf;
      84  		strm.avail_in = in_len;
      85  
      86  		/* if no more data from in_buf, flushes the
      87  		   internal xz buffers and closes the xz data
      88  		   with LZMA_FINISH */
      89  		action = in_finished ? LZMA_FINISH : LZMA_RUN;
      90  
      91  		/* loop until there's no pending compressed output */
      92  		do {
      93  			/* out_buf is clean at this point */
      94  			strm.next_out = out_buf;
      95  			strm.avail_out = OUT_BUF_MAX;
      96  
      97  			/* compress data */
      98  			ret_xz = lzma_code (&strm, action);
      99  
     100  			if ((ret_xz != LZMA_OK) && (ret_xz != LZMA_STREAM_END)) {
     101  				fprintf (stderr, "lzma_code error: %d\n", (int) ret_xz);
     102  				out_finished = true;
     103  				ret = RET_ERROR_COMPRESSION;
     104  			} else {
     105  				/* write compressed data */
     106  				out_len = OUT_BUF_MAX - strm.avail_out;
     107  				fwrite (out_buf, 1, out_len, out_file);
     108  				if (ferror (out_file)) {
     109  					out_finished = true;
     110  					ret = RET_ERROR_OUTPUT;
     111  				}
     112  			}
     113  		} while (strm.avail_out == 0);
     114  	}
     115  
     116  	lzma_end (&strm);
     117  	return ret;
     118  }
     119  
     120  int main ()
     121  {
     122  	int ret;
     123  
     124  	ret = xz_compress (stdin, stdout);
     125  	return ret;
     126  }
     127