xz_wrapper.c revision 7aa2f2a969f8bd684f1c31a14af9d6bba453d7f8
1f5e8c0f128f48463630358bcea6063d0024cfd5aplougher/*
2f5e8c0f128f48463630358bcea6063d0024cfd5aplougher * Copyright (c) 2010
3f5e8c0f128f48463630358bcea6063d0024cfd5aplougher * Phillip Lougher <phillip@lougher.demon.co.uk>
4f5e8c0f128f48463630358bcea6063d0024cfd5aplougher *
5f5e8c0f128f48463630358bcea6063d0024cfd5aplougher * This program is free software; you can redistribute it and/or
6f5e8c0f128f48463630358bcea6063d0024cfd5aplougher * modify it under the terms of the GNU General Public License
7f5e8c0f128f48463630358bcea6063d0024cfd5aplougher * as published by the Free Software Foundation; either version 2,
8f5e8c0f128f48463630358bcea6063d0024cfd5aplougher * or (at your option) any later version.
9f5e8c0f128f48463630358bcea6063d0024cfd5aplougher *
10f5e8c0f128f48463630358bcea6063d0024cfd5aplougher * This program is distributed in the hope that it will be useful,
11f5e8c0f128f48463630358bcea6063d0024cfd5aplougher * but WITHOUT ANY WARRANTY; without even the implied warranty of
12f5e8c0f128f48463630358bcea6063d0024cfd5aplougher * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13f5e8c0f128f48463630358bcea6063d0024cfd5aplougher * GNU General Public License for more details.
14f5e8c0f128f48463630358bcea6063d0024cfd5aplougher *
15f5e8c0f128f48463630358bcea6063d0024cfd5aplougher * You should have received a copy of the GNU General Public License
16f5e8c0f128f48463630358bcea6063d0024cfd5aplougher * along with this program; if not, write to the Free Software
17f5e8c0f128f48463630358bcea6063d0024cfd5aplougher * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18f5e8c0f128f48463630358bcea6063d0024cfd5aplougher *
19f5e8c0f128f48463630358bcea6063d0024cfd5aplougher * xz_wrapper.c
2067dfce9c3751f0580633e8a33cea28bcfbefec04plougher *
2167dfce9c3751f0580633e8a33cea28bcfbefec04plougher * Support for XZ (LZMA2) compression using XZ Utils liblzma http://tukaani.org/xz/
22f5e8c0f128f48463630358bcea6063d0024cfd5aplougher */
2367dfce9c3751f0580633e8a33cea28bcfbefec04plougher
2467dfce9c3751f0580633e8a33cea28bcfbefec04plougher#include <stdio.h>
2567dfce9c3751f0580633e8a33cea28bcfbefec04plougher#include <string.h>
267b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher#include <stdlib.h>
2767dfce9c3751f0580633e8a33cea28bcfbefec04plougher#include <lzma.h>
2867dfce9c3751f0580633e8a33cea28bcfbefec04plougher
2967dfce9c3751f0580633e8a33cea28bcfbefec04plougher#include "squashfs_fs.h"
3067dfce9c3751f0580633e8a33cea28bcfbefec04plougher#include "compressor.h"
3167dfce9c3751f0580633e8a33cea28bcfbefec04plougher
3267dfce9c3751f0580633e8a33cea28bcfbefec04plougher#define MEMLIMIT (32 * 1024 * 1024)
3367dfce9c3751f0580633e8a33cea28bcfbefec04plougher
347b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougherstatic struct bcj {
357b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher	char	 	*name;
367b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher	lzma_vli	id;
377b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher	int		selected;
387b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher} bcj[] = {
397b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher	{ "x86", LZMA_FILTER_X86, 0 },
407b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher	{ "powerpc", LZMA_FILTER_POWERPC, 0 },
417b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher	{ "ia64", LZMA_FILTER_IA64, 0 },
427b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher	{ "arm", LZMA_FILTER_ARM, 0 },
437b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher	{ "armthumb", LZMA_FILTER_ARMTHUMB, 0 },
447b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher	{ "sparc", LZMA_FILTER_SPARC, 0 },
457b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher	{ NULL, LZMA_VLI_UNKNOWN, 0 }
4667dfce9c3751f0580633e8a33cea28bcfbefec04plougher};
4767dfce9c3751f0580633e8a33cea28bcfbefec04plougher
487b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougherstruct filter {
497b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher	void		*buffer;
507b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher	lzma_filter	filter[3];
517b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher	size_t		length;
527b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher};
5367dfce9c3751f0580633e8a33cea28bcfbefec04plougher
547b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougherstruct xz_stream {
557b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher	struct filter	*filter;
567b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher	int		filters;
577b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher	lzma_options_lzma opt;
587b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher};
597b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher
607b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougherstatic int filter_count = 1;
617b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher
627b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher
637b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougherstatic int xz_options(char *argv[], int argc)
6467dfce9c3751f0580633e8a33cea28bcfbefec04plougher{
657b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher	int i;
667b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher	char *name;
677b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher
687b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher	if(strcmp(argv[0], "-Xbcj") == 0) {
697b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher		if(argc < 2) {
707b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher			fprintf(stderr, "xz: -Xbcj missing filter\n");
717b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher			goto failed;
727b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher		}
737b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher
747b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher		name = argv[1];
757b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher		while(name[0] != '\0') {
767b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher			for(i = 0; bcj[i].name; i++) {
777b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher				int n = strlen(bcj[i].name);
787b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher				if((strncmp(name, bcj[i].name, n) == 0) &&
797b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher						(name[n] == '\0' ||
807b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher						 name[n] == ',')) {
817b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher					if(bcj[i].selected == 0) {
827b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher				 		bcj[i].selected = 1;
837b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher						filter_count++;
847b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher					}
857b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher					name += name[n] == ',' ? n + 1 : n;
867b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher					break;
877b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher				}
887b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher			}
897b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher			if(bcj[i].name == NULL) {
907b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher				fprintf(stderr, "xz: -Xbcj unrecognised filter\n");
917b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher				goto failed;
927b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher			}
937b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher		}
947b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher
957b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher		return 1;
967b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher	}
977b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher
987b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher	return -1;
99d886567331690a0781c695a590e43ac37b78ad10plougher
100d886567331690a0781c695a590e43ac37b78ad10plougherfailed:
101d886567331690a0781c695a590e43ac37b78ad10plougher	return -2;
1027b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher}
1037b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher
1047b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher
1057aa2f2a969f8bd684f1c31a14af9d6bba453d7f8ploughervoid xz_usage()
1067aa2f2a969f8bd684f1c31a14af9d6bba453d7f8plougher{
1077aa2f2a969f8bd684f1c31a14af9d6bba453d7f8plougher	fprintf(stderr, "\t  -Xbcj filter1,filter2,...,filterN\n");
1087aa2f2a969f8bd684f1c31a14af9d6bba453d7f8plougher	fprintf(stderr, "\t\tCompress using filter1,filter2,...,filterN in");
1097aa2f2a969f8bd684f1c31a14af9d6bba453d7f8plougher	fprintf(stderr, " turn\n\t\t(in addition to no filter), and choose");
1107aa2f2a969f8bd684f1c31a14af9d6bba453d7f8plougher	fprintf(stderr, " the best compression.\n");
1117aa2f2a969f8bd684f1c31a14af9d6bba453d7f8plougher	fprintf(stderr, "\t\tAvailable filters: x86, arm, armthumb,");
1127aa2f2a969f8bd684f1c31a14af9d6bba453d7f8plougher	fprintf(stderr, " powerpc, sparc, ia64\n");
1137aa2f2a969f8bd684f1c31a14af9d6bba453d7f8plougher}
1147aa2f2a969f8bd684f1c31a14af9d6bba453d7f8plougher
1157aa2f2a969f8bd684f1c31a14af9d6bba453d7f8plougher
1167b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougherstatic int xz_init(void **strm, int block_size, int flags)
1177b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher{
1187b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher	int i, j, filters = flags ? filter_count : 1;
1197b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher	struct filter *filter = malloc(filters * sizeof(struct filter));
1207b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher	struct xz_stream *stream;
1217b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher
1227b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher	if(filter == NULL)
1237b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher		goto failed;
1247b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher
1257b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher	stream = *strm = malloc(sizeof(struct xz_stream));
1267b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher	if(stream == NULL)
1277b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher		goto failed2;
12867dfce9c3751f0580633e8a33cea28bcfbefec04plougher
1297b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher	stream->filter = filter;
1307b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher	stream->filters = filters;
13167dfce9c3751f0580633e8a33cea28bcfbefec04plougher
1327b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher	memset(filter, 0, filters * sizeof(struct filter));
13367dfce9c3751f0580633e8a33cea28bcfbefec04plougher
1347b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher	filter[0].filter[0].id = LZMA_FILTER_LZMA2;
1357b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher	filter[0].filter[0].options = &stream->opt;
1367b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher	filter[0].filter[1].id = LZMA_VLI_UNKNOWN;
13767dfce9c3751f0580633e8a33cea28bcfbefec04plougher
1387b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher	for(i = 0, j = 1; flags && bcj[i].name; i++) {
1397b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher		if(bcj[i].selected) {
1407b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher			filter[j].buffer = malloc(block_size);
1417b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher			if(filter[j].buffer == NULL)
1427b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher				goto failed3;
1437b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher			filter[j].filter[0].id = bcj[i].id;
1447b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher			filter[j].filter[1].id = LZMA_FILTER_LZMA2;
1457b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher			filter[j].filter[1].options = &stream->opt;
1467b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher			filter[j].filter[2].id = LZMA_VLI_UNKNOWN;
1477b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher			j++;
1487b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher		}
1497b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher	}
1507b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher
1517b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher	return 0;
1527b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher
1537b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougherfailed3:
1547b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher	for(i = 1; i < filters; i++)
1557b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher		free(filter[i].buffer);
1567b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher	free(stream);
1577b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher
1587b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougherfailed2:
1597b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher	free(filter);
1607b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher
1617b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougherfailed:
1627b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher	return -1;
1637b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher}
1647b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher
1657b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher
1667b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougherstatic int xz_compress(void *strm, void *dest, void *src,  int size,
1677b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher	int block_size, int *error)
1687b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher{
1697b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher	int i;
1707b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher        lzma_ret res = 0;
1717b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher	struct xz_stream *stream = strm;
1727b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher	struct filter *selected = NULL;
1737b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher
1747b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher	stream->filter[0].buffer = dest;
1757b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher
1767b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher	for(i = 0; i < stream->filters; i++) {
1777b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher		struct filter *filter = &stream->filter[i];
1787b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher
1797b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher        	if(lzma_lzma_preset(&stream->opt, LZMA_PRESET_DEFAULT))
1807b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher                	goto failed;
1817b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher
1820283718e13a5a7b2dc21bffa0041d001ecbcdb1aplougher		stream->opt.dict_size = block_size;
1837b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher		filter->length = 0;
1847b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher		res = lzma_stream_buffer_encode(filter->filter,
1857b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher			LZMA_CHECK_CRC32, NULL, src, size, filter->buffer,
1867b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher			&filter->length, block_size);
1877b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher
1887b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher		if(res == LZMA_OK) {
1897b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher			if(!selected || selected->length > filter->length)
1907b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher				selected = filter;
1917b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher		} else if(res != LZMA_BUF_ERROR)
1927b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher			goto failed;
1937b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher	}
1947b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher
1957b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher	if(!selected)
19667dfce9c3751f0580633e8a33cea28bcfbefec04plougher		/*
19767dfce9c3751f0580633e8a33cea28bcfbefec04plougher	 	 * Output buffer overflow.  Return out of buffer space
19867dfce9c3751f0580633e8a33cea28bcfbefec04plougher	 	 */
19967dfce9c3751f0580633e8a33cea28bcfbefec04plougher		return 0;
20067dfce9c3751f0580633e8a33cea28bcfbefec04plougher
2017b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher	if(selected->buffer != dest)
2027b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher		memcpy(dest, selected->buffer, selected->length);
2037b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher
2047b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher	return (int) selected->length;
2057b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher
20667dfce9c3751f0580633e8a33cea28bcfbefec04plougherfailed:
20767dfce9c3751f0580633e8a33cea28bcfbefec04plougher	/*
20867dfce9c3751f0580633e8a33cea28bcfbefec04plougher	 * All other errors return failure, with the compressor
20967dfce9c3751f0580633e8a33cea28bcfbefec04plougher	 * specific error code in *error
21067dfce9c3751f0580633e8a33cea28bcfbefec04plougher	 */
21167dfce9c3751f0580633e8a33cea28bcfbefec04plougher	*error = res;
21267dfce9c3751f0580633e8a33cea28bcfbefec04plougher	return -1;
21367dfce9c3751f0580633e8a33cea28bcfbefec04plougher}
21467dfce9c3751f0580633e8a33cea28bcfbefec04plougher
21567dfce9c3751f0580633e8a33cea28bcfbefec04plougher
21667dfce9c3751f0580633e8a33cea28bcfbefec04plougherstatic int xz_uncompress(void *dest, void *src, int size, int block_size,
21767dfce9c3751f0580633e8a33cea28bcfbefec04plougher	int *error)
21867dfce9c3751f0580633e8a33cea28bcfbefec04plougher{
21967dfce9c3751f0580633e8a33cea28bcfbefec04plougher	size_t src_pos = 0;
22067dfce9c3751f0580633e8a33cea28bcfbefec04plougher	size_t dest_pos = 0;
22167dfce9c3751f0580633e8a33cea28bcfbefec04plougher	uint64_t memlimit = MEMLIMIT;
2227b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher
22367dfce9c3751f0580633e8a33cea28bcfbefec04plougher	lzma_ret res = lzma_stream_buffer_decode(&memlimit, 0, NULL,
22467dfce9c3751f0580633e8a33cea28bcfbefec04plougher			src, &src_pos, size, dest, &dest_pos, block_size);
22567dfce9c3751f0580633e8a33cea28bcfbefec04plougher
22667dfce9c3751f0580633e8a33cea28bcfbefec04plougher	*error = res;
22767dfce9c3751f0580633e8a33cea28bcfbefec04plougher	return res == LZMA_OK && size == (int) src_pos ? (int) dest_pos : -1;
22867dfce9c3751f0580633e8a33cea28bcfbefec04plougher}
22967dfce9c3751f0580633e8a33cea28bcfbefec04plougher
23067dfce9c3751f0580633e8a33cea28bcfbefec04plougher
23167dfce9c3751f0580633e8a33cea28bcfbefec04plougherstruct compressor xz_comp_ops = {
2327b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher	.init = xz_init,
23367dfce9c3751f0580633e8a33cea28bcfbefec04plougher	.compress = xz_compress,
23467dfce9c3751f0580633e8a33cea28bcfbefec04plougher	.uncompress = xz_uncompress,
2357b6b352b70dcd9f8e71027e8a4c1e4807fc7240dplougher	.options = xz_options,
2367aa2f2a969f8bd684f1c31a14af9d6bba453d7f8plougher	.usage = xz_usage,
23767dfce9c3751f0580633e8a33cea28bcfbefec04plougher	.id = XZ_COMPRESSION,
23867dfce9c3751f0580633e8a33cea28bcfbefec04plougher	.name = "xz",
23967dfce9c3751f0580633e8a33cea28bcfbefec04plougher	.supported = 1
24067dfce9c3751f0580633e8a33cea28bcfbefec04plougher};
24167dfce9c3751f0580633e8a33cea28bcfbefec04plougher
242