10c9f50e7fb8285ae1b6787033c9f220a9217fe9bplougher/*
20c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher * Copyright (c) 2009, 2010, 2013, 2014
383d42a3fc898962aa1f1e8387f2ccb1114e0d294Phillip Lougher * Phillip Lougher <phillip@squashfs.org.uk>
40c9f50e7fb8285ae1b6787033c9f220a9217fe9bplougher *
50c9f50e7fb8285ae1b6787033c9f220a9217fe9bplougher * This program is free software; you can redistribute it and/or
60c9f50e7fb8285ae1b6787033c9f220a9217fe9bplougher * modify it under the terms of the GNU General Public License
70c9f50e7fb8285ae1b6787033c9f220a9217fe9bplougher * as published by the Free Software Foundation; either version 2,
80c9f50e7fb8285ae1b6787033c9f220a9217fe9bplougher * or (at your option) any later version.
90c9f50e7fb8285ae1b6787033c9f220a9217fe9bplougher *
100c9f50e7fb8285ae1b6787033c9f220a9217fe9bplougher * This program is distributed in the hope that it will be useful,
110c9f50e7fb8285ae1b6787033c9f220a9217fe9bplougher * but WITHOUT ANY WARRANTY; without even the implied warranty of
120c9f50e7fb8285ae1b6787033c9f220a9217fe9bplougher * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
130c9f50e7fb8285ae1b6787033c9f220a9217fe9bplougher * GNU General Public License for more details.
140c9f50e7fb8285ae1b6787033c9f220a9217fe9bplougher *
150c9f50e7fb8285ae1b6787033c9f220a9217fe9bplougher * You should have received a copy of the GNU General Public License
160c9f50e7fb8285ae1b6787033c9f220a9217fe9bplougher * along with this program; if not, write to the Free Software
170c9f50e7fb8285ae1b6787033c9f220a9217fe9bplougher * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
180c9f50e7fb8285ae1b6787033c9f220a9217fe9bplougher *
190c9f50e7fb8285ae1b6787033c9f220a9217fe9bplougher * gzip_wrapper.c
200c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher *
21ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher * Support for ZLIB compression http://www.zlib.net
220c9f50e7fb8285ae1b6787033c9f220a9217fe9bplougher */
230c9f50e7fb8285ae1b6787033c9f220a9217fe9bplougher
240c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher#include <stdio.h>
250c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher#include <string.h>
260c9f50e7fb8285ae1b6787033c9f220a9217fe9bplougher#include <stdlib.h>
270c9f50e7fb8285ae1b6787033c9f220a9217fe9bplougher#include <zlib.h>
280c9f50e7fb8285ae1b6787033c9f220a9217fe9bplougher
2923a6f30f9bcef494438dd8f1993fc22dcfb3708eplougher#include "squashfs_fs.h"
300c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher#include "gzip_wrapper.h"
3123a6f30f9bcef494438dd8f1993fc22dcfb3708eplougher#include "compressor.h"
3223a6f30f9bcef494438dd8f1993fc22dcfb3708eplougher
33ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougherstatic struct strategy strategy[] = {
34ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher	{ "default", Z_DEFAULT_STRATEGY, 0 },
35ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher	{ "filtered", Z_FILTERED, 0 },
36ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher	{ "huffman_only", Z_HUFFMAN_ONLY, 0 },
37ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher	{ "run_length_encoded", Z_RLE, 0 },
38ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher	{ "fixed", Z_FIXED, 0 },
39ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher	{ NULL, 0, 0 }
40ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher};
41ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher
42ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougherstatic int strategy_count = 0;
43ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher
440c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher/* default compression level */
450c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougherstatic int compression_level = GZIP_DEFAULT_COMPRESSION_LEVEL;
460c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher
470c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher/* default window size */
480c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougherstatic int window_size = GZIP_DEFAULT_WINDOW_SIZE;
490c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher
500c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher/*
510c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher * This function is called by the options parsing code in mksquashfs.c
520c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher * to parse any -X compressor option.
530c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher *
540c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher * This function returns:
550c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher *	>=0 (number of additional args parsed) on success
560c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher *	-1 if the option was unrecognised, or
570c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher *	-2 if the option was recognised, but otherwise bad in
580c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher *	   some way (e.g. invalid parameter)
590c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher *
600c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher * Note: this function sets internal compressor state, but does not
610c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher * pass back the results of the parsing other than success/failure.
620c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher * The gzip_dump_options() function is called later to get the options in
630c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher * a format suitable for writing to the filesystem.
640c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher */
650c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougherstatic int gzip_options(char *argv[], int argc)
660c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher{
670c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	if(strcmp(argv[0], "-Xcompression-level") == 0) {
680c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher		if(argc < 2) {
690c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher			fprintf(stderr, "gzip: -Xcompression-level missing "
700c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher				"compression level\n");
710c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher			fprintf(stderr, "gzip: -Xcompression-level it "
720c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher				"should be 1 >= n <= 9\n");
730c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher			goto failed;
740c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher		}
750c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher
760c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher		compression_level = atoi(argv[1]);
770c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher		if(compression_level < 1 || compression_level > 9) {
780c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher			fprintf(stderr, "gzip: -Xcompression-level invalid, it "
790c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher				"should be 1 >= n <= 9\n");
800c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher			goto failed;
810c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher		}
820c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher
830c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher		return 1;
840c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	} else if(strcmp(argv[0], "-Xwindow-size") == 0) {
850c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher		if(argc < 2) {
860c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher			fprintf(stderr, "gzip: -Xwindow-size missing window "
870c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher				"	size\n");
880c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher			fprintf(stderr, "gzip: -Xwindow-size <window-size>\n");
890c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher			goto failed;
900c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher		}
910c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher
920c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher		window_size = atoi(argv[1]);
930c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher		if(window_size < 8 || window_size > 15) {
940c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher			fprintf(stderr, "gzip: -Xwindow-size invalid, it "
950c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher				"should be 8 >= n <= 15\n");
960c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher			goto failed;
970c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher		}
98420660993551ae45c9fdf13f689b4e5e97cc423ePhillip Lougher
99420660993551ae45c9fdf13f689b4e5e97cc423ePhillip Lougher		return 1;
100ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher	} else if(strcmp(argv[0], "-Xstrategy") == 0) {
101ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher		char *name;
102ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher		int i;
103ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher
104ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher		if(argc < 2) {
105ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher			fprintf(stderr, "gzip: -Xstrategy missing "
106ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher							"strategies\n");
107ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher			goto failed;
108ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher		}
109ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher
110ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher		name = argv[1];
111ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher		while(name[0] != '\0') {
112ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher			for(i = 0; strategy[i].name; i++) {
113ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher				int n = strlen(strategy[i].name);
114ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher				if((strncmp(name, strategy[i].name, n) == 0) &&
115ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher						(name[n] == '\0' ||
116ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher						 name[n] == ',')) {
117ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher					if(strategy[i].selected == 0) {
118ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher				 		strategy[i].selected = 1;
119ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher						strategy_count++;
120ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher					}
121ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher					name += name[n] == ',' ? n + 1 : n;
122ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher					break;
123ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher				}
124ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher			}
125ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher			if(strategy[i].name == NULL) {
126ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher				fprintf(stderr, "gzip: -Xstrategy unrecognised "
127ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher					"strategy\n");
128ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher				goto failed;
129ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher			}
130ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher		}
131ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher
132ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher		return 1;
1330c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	}
1340c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher
1350c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	return -1;
1360c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher
1370c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougherfailed:
1380c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	return -2;
1390c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher}
1400c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher
1410c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher
1420c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher/*
143ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher * This function is called after all options have been parsed.
144ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher * It is used to do post-processing on the compressor options using
145ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher * values that were not expected to be known at option parse time.
146ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher *
147ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher * This function returns 0 on successful post processing, or
148ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher *			-1 on error
149ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher */
150ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougherstatic int gzip_options_post(int block_size)
151ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher{
152ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher	if(strategy_count == 1 && strategy[0].selected) {
153ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher		strategy_count = 0;
154ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher		strategy[0].selected = 0;
155ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher	}
156ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher
157ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher	return 0;
158ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher}
159ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher
160ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher
161ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher/*
1620c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher * This function is called by mksquashfs to dump the parsed
1630c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher * compressor options in a format suitable for writing to the
1640c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher * compressor options field in the filesystem (stored immediately
1650c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher * after the superblock).
1660c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher *
1670c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher * This function returns a pointer to the compression options structure
1680c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher * to be stored (and the size), or NULL if there are no compression
1690c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher * options
1700c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher *
1710c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher */
1720c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougherstatic void *gzip_dump_options(int block_size, int *size)
1730c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher{
1740c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	static struct gzip_comp_opts comp_opts;
175ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher	int i, strategies = 0;
1760c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher
1770c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	/*
1780c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	 * If default compression options of:
1790c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	 * compression-level: 8 and
180ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher	 * window-size: 15 and
181ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher	 * strategy_count == 0 then
1820c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	 * don't store a compression options structure (this is compatible
1830c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	 * with the legacy implementation of GZIP for Squashfs)
1840c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	 */
1850c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	if(compression_level == GZIP_DEFAULT_COMPRESSION_LEVEL &&
186ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher				window_size == GZIP_DEFAULT_WINDOW_SIZE &&
187ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher				strategy_count == 0)
1880c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher		return NULL;
1890c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher
190ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher	for(i = 0; strategy[i].name; i++)
191ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher		strategies |= strategy[i].selected << i;
192ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher
1930c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	comp_opts.compression_level = compression_level;
1940c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	comp_opts.window_size = window_size;
195ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher	comp_opts.strategy = strategies;
1960c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher
1970c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	SQUASHFS_INSWAP_COMP_OPTS(&comp_opts);
1980c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher
1990c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	*size = sizeof(comp_opts);
2000c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	return &comp_opts;
2010c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher}
2020c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher
2030c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher
2040c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher/*
2050c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher * This function is a helper specifically for the append mode of
2060c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher * mksquashfs.  Its purpose is to set the internal compressor state
2070c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher * to the stored compressor options in the passed compressor options
2080c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher * structure.
2090c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher *
2100c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher * In effect this function sets up the compressor options
2110c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher * to the same state they were when the filesystem was originally
2120c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher * generated, this is to ensure on appending, the compressor uses
2130c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher * the same compression options that were used to generate the
2140c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher * original filesystem.
2150c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher *
2160c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher * Note, even if there are no compressor options, this function is still
2170c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher * called with an empty compressor structure (size == 0), to explicitly
2180c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher * set the default options, this is to ensure any user supplied
2190c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher * -X options on the appending mksquashfs command line are over-ridden
2200c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher *
2210c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher * This function returns 0 on sucessful extraction of options, and
2220c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher *			-1 on error
2230c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher */
2240c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougherstatic int gzip_extract_options(int block_size, void *buffer, int size)
2250c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher{
2260c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	struct gzip_comp_opts *comp_opts = buffer;
227ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher	int i;
2280c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher
2290c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	if(size == 0) {
2300c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher		/* Set default values */
2310c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher		compression_level = GZIP_DEFAULT_COMPRESSION_LEVEL;
2320c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher		window_size = GZIP_DEFAULT_WINDOW_SIZE;
233ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher		strategy_count = 0;
2340c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher		return 0;
2350c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	}
2360c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher
2370c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	/* we expect a comp_opts structure of sufficient size to be present */
2380c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	if(size < sizeof(*comp_opts))
2390c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher		goto failed;
2400c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher
2410c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	SQUASHFS_INSWAP_COMP_OPTS(comp_opts);
2420c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher
2430c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	/* Check comp_opts structure for correctness */
2440c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	if(comp_opts->compression_level < 1 ||
2450c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher			comp_opts->compression_level > 9) {
2460c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher		fprintf(stderr, "gzip: bad compression level in "
2470c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher			"compression options structure\n");
2480c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher		goto failed;
2490c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	}
2500c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	compression_level = comp_opts->compression_level;
2510c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher
2520c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	if(comp_opts->window_size < 8 ||
2530c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher			comp_opts->window_size > 15) {
2540c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher		fprintf(stderr, "gzip: bad window size in "
2550c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher			"compression options structure\n");
2560c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher		goto failed;
2570c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	}
2580c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	window_size = comp_opts->window_size;
259ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher
260ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher	strategy_count = 0;
261ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher	for(i = 0; strategy[i].name; i++) {
262ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher		if((comp_opts->strategy >> i) & 1) {
263ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher			strategy[i].selected = 1;
264ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher			strategy_count ++;
265ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher		} else
266ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher			strategy[i].selected = 0;
267ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher	}
268ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher
2690c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	return 0;
2700c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher
2710c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougherfailed:
2720c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	fprintf(stderr, "gzip: error reading stored compressor options from "
2730c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher		"filesystem!\n");
2740c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher
2750c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	return -1;
2760c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher}
2770c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher
2780c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher
2790c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Loughervoid gzip_display_options(void *buffer, int size)
2800c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher{
2810c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	struct gzip_comp_opts *comp_opts = buffer;
282ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher	int i, printed;
2830c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher
2840c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	/* we expect a comp_opts structure of sufficient size to be present */
2850c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	if(size < sizeof(*comp_opts))
2860c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher		goto failed;
2870c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher
2880c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	SQUASHFS_INSWAP_COMP_OPTS(comp_opts);
2890c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher
2900c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	/* Check comp_opts structure for correctness */
2910c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	if(comp_opts->compression_level < 1 ||
2920c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher			comp_opts->compression_level > 9) {
2930c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher		fprintf(stderr, "gzip: bad compression level in "
2940c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher			"compression options structure\n");
2950c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher		goto failed;
2960c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	}
2970c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	printf("\tcompression-level %d\n", comp_opts->compression_level);
2980c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher
2990c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	if(comp_opts->window_size < 8 ||
3000c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher			comp_opts->window_size > 15) {
3010c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher		fprintf(stderr, "gzip: bad window size in "
3020c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher			"compression options structure\n");
3030c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher		goto failed;
3040c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	}
3050c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	printf("\twindow-size %d\n", comp_opts->window_size);
3060c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher
307ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher	for(i = 0, printed = 0; strategy[i].name; i++) {
308ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher		if((comp_opts->strategy >> i) & 1) {
309ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher			if(printed)
310ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher				printf(", ");
311ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher			else
312ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher				printf("\tStrategies selected: ");
313ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher			printf("%s", strategy[i].name);
314ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher			printed = 1;
315ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher		}
316ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher	}
317ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher
318ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher	if(!printed)
319ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher		printf("\tStrategies selected: default\n");
320ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher	else
321ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher		printf("\n");
322ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher
3230c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	return;
3240c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher
3250c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougherfailed:
3260c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	fprintf(stderr, "gzip: error reading stored compressor options from "
3270c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher		"filesystem!\n");
3280c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher}
3290c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher
3300c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher
3310c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher/*
3320c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher * This function is called by mksquashfs to initialise the
3330c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher * compressor, before compress() is called.
3340c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher *
3350c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher * This function returns 0 on success, and
3360c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher *			-1 on error
3370c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher */
338ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougherstatic int gzip_init(void **strm, int block_size, int datablock)
3390c9f50e7fb8285ae1b6787033c9f220a9217fe9bplougher{
340ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher	int i, j, res;
341ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher	struct gzip_stream *stream;
3423c765f0e6269d11c95accd03bb8dbb00e88a2721plougher
343ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher	if(!datablock || !strategy_count) {
344ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher		stream = malloc(sizeof(*stream) + sizeof(struct gzip_strategy));
345ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher		if(stream == NULL)
346ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher			goto failed;
347ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher
348ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher		stream->strategies = 1;
349ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher		stream->strategy[0].strategy = Z_DEFAULT_STRATEGY;
350ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher	} else {
351ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher		stream = malloc(sizeof(*stream) +
352ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher			sizeof(struct gzip_strategy) * strategy_count);
353ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher		if(stream == NULL)
354ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher			goto failed;
355ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher
356ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher		memset(stream->strategy, 0, sizeof(struct gzip_strategy) *
357ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher			strategy_count);
358ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher
359ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher		stream->strategies = strategy_count;
3603c765f0e6269d11c95accd03bb8dbb00e88a2721plougher
361ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher		for(i = 0, j = 0; strategy[i].name; i++) {
362ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher			if(!strategy[i].selected)
363ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher				continue;
3643c765f0e6269d11c95accd03bb8dbb00e88a2721plougher
365ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher			stream->strategy[j].strategy = strategy[i].strategy;
366ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher			if(j) {
367ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher				stream->strategy[j].buffer = malloc(block_size);
368ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher				if(stream->strategy[j].buffer == NULL)
369ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher					goto failed2;
370ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher			}
371ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher			j++;
372ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher		}
373ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher	}
374ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher
375ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher	stream->stream.zalloc = Z_NULL;
376ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher	stream->stream.zfree = Z_NULL;
377ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher	stream->stream.opaque = 0;
378ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher
379ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher	res = deflateInit2(&stream->stream, compression_level, Z_DEFLATED,
380ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher		window_size, 8, stream->strategy[0].strategy);
3813c765f0e6269d11c95accd03bb8dbb00e88a2721plougher	if(res != Z_OK)
3823c765f0e6269d11c95accd03bb8dbb00e88a2721plougher		goto failed2;
3833c765f0e6269d11c95accd03bb8dbb00e88a2721plougher
384ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher	*strm = stream;
3853c765f0e6269d11c95accd03bb8dbb00e88a2721plougher	return 0;
3863c765f0e6269d11c95accd03bb8dbb00e88a2721plougher
3873c765f0e6269d11c95accd03bb8dbb00e88a2721plougherfailed2:
388ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher	for(i = 1; i < stream->strategies; i++)
389ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher		free(stream->strategy[i].buffer);
3903c765f0e6269d11c95accd03bb8dbb00e88a2721plougher	free(stream);
3913c765f0e6269d11c95accd03bb8dbb00e88a2721plougherfailed:
3923c765f0e6269d11c95accd03bb8dbb00e88a2721plougher	return -1;
3933c765f0e6269d11c95accd03bb8dbb00e88a2721plougher}
3940c9f50e7fb8285ae1b6787033c9f220a9217fe9bplougher
3950c9f50e7fb8285ae1b6787033c9f220a9217fe9bplougher
3963c765f0e6269d11c95accd03bb8dbb00e88a2721plougherstatic int gzip_compress(void *strm, void *d, void *s, int size, int block_size,
3973c765f0e6269d11c95accd03bb8dbb00e88a2721plougher		int *error)
3983c765f0e6269d11c95accd03bb8dbb00e88a2721plougher{
399ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher	int i, res;
400ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher	struct gzip_stream *stream = strm;
401ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher	struct gzip_strategy *selected = NULL;
4020c9f50e7fb8285ae1b6787033c9f220a9217fe9bplougher
403ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher	stream->strategy[0].buffer = d;
4040c9f50e7fb8285ae1b6787033c9f220a9217fe9bplougher
405ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher	for(i = 0; i < stream->strategies; i++) {
406ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher		struct gzip_strategy *strategy = &stream->strategy[i];
4070c9f50e7fb8285ae1b6787033c9f220a9217fe9bplougher
408ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher		res = deflateReset(&stream->stream);
409ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher		if(res != Z_OK)
410ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher			goto failed;
411ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher
412ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher		stream->stream.next_in = s;
413ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher		stream->stream.avail_in = size;
414ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher		stream->stream.next_out = strategy->buffer;
415ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher		stream->stream.avail_out = block_size;
416ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher
417ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher		if(stream->strategies > 1) {
418ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher			res = deflateParams(&stream->stream,
419ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher				compression_level, strategy->strategy);
420ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher			if(res != Z_OK)
421ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher				goto failed;
422ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher		}
423ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher
424ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher		res = deflate(&stream->stream, Z_FINISH);
425ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher		strategy->length = stream->stream.total_out;
426ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher		if(res == Z_STREAM_END) {
427ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher			if(!selected || selected->length > strategy->length)
428ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher				selected = strategy;
429ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher		} else if(res != Z_OK)
430ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher			goto failed;
431ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher	}
432ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher
433ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher	if(!selected)
434b552f0092251f472920f73e701bfd7fffe954327plougher		/*
435b552f0092251f472920f73e701bfd7fffe954327plougher		 * Output buffer overflow.  Return out of buffer space
436b552f0092251f472920f73e701bfd7fffe954327plougher		 */
4370c9f50e7fb8285ae1b6787033c9f220a9217fe9bplougher		return 0;
438ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher
439ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher	if(selected->buffer != d)
440ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher		memcpy(d, selected->buffer, selected->length);
441ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher
442ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher	return (int) selected->length;
443ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher
4440c9f50e7fb8285ae1b6787033c9f220a9217fe9bplougherfailed:
445b552f0092251f472920f73e701bfd7fffe954327plougher	/*
446b552f0092251f472920f73e701bfd7fffe954327plougher	 * All other errors return failure, with the compressor
447b552f0092251f472920f73e701bfd7fffe954327plougher	 * specific error code in *error
448b552f0092251f472920f73e701bfd7fffe954327plougher	 */
4490c9f50e7fb8285ae1b6787033c9f220a9217fe9bplougher	*error = res;
4500c9f50e7fb8285ae1b6787033c9f220a9217fe9bplougher	return -1;
4510c9f50e7fb8285ae1b6787033c9f220a9217fe9bplougher}
4524ab07197d7f0880945f1b15eb5507dde609c449cplougher
4534ab07197d7f0880945f1b15eb5507dde609c449cplougher
4548a4692825eb1840d52f2f921e40346d0f8c7e702Phillip Lougherstatic int gzip_uncompress(void *d, void *s, int size, int outsize, int *error)
4554ab07197d7f0880945f1b15eb5507dde609c449cplougher{
4564ab07197d7f0880945f1b15eb5507dde609c449cplougher	int res;
4578a4692825eb1840d52f2f921e40346d0f8c7e702Phillip Lougher	unsigned long bytes = outsize;
4584ab07197d7f0880945f1b15eb5507dde609c449cplougher
459501fdfa23260cbcdd72ec79fa3940cff13aaf682plougher	res = uncompress(d, &bytes, s, size);
4604ab07197d7f0880945f1b15eb5507dde609c449cplougher
461cb39504592e9531436375d35ca415ee8bfcb8ad5Phillip Lougher	if(res == Z_OK)
462cb39504592e9531436375d35ca415ee8bfcb8ad5Phillip Lougher		return (int) bytes;
463cb39504592e9531436375d35ca415ee8bfcb8ad5Phillip Lougher	else {
464cb39504592e9531436375d35ca415ee8bfcb8ad5Phillip Lougher		*error = res;
465cb39504592e9531436375d35ca415ee8bfcb8ad5Phillip Lougher		return -1;
466cb39504592e9531436375d35ca415ee8bfcb8ad5Phillip Lougher	}
4674ab07197d7f0880945f1b15eb5507dde609c449cplougher}
46823a6f30f9bcef494438dd8f1993fc22dcfb3708eplougher
46923a6f30f9bcef494438dd8f1993fc22dcfb3708eplougher
4700c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Loughervoid gzip_usage()
4710c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher{
4720c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	fprintf(stderr, "\t  -Xcompression-level <compression-level>\n");
4730c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	fprintf(stderr, "\t\t<compression-level> should be 1 .. 9 (default "
4740c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher		"%d)\n", GZIP_DEFAULT_COMPRESSION_LEVEL);
4750c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	fprintf(stderr, "\t  -Xwindow-size <window-size>\n");
4760c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	fprintf(stderr, "\t\t<window-size> should be 8 .. 15 (default "
4770c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher		"%d)\n", GZIP_DEFAULT_WINDOW_SIZE);
478ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher	fprintf(stderr, "\t  -Xstrategy strategy1,strategy2,...,strategyN\n");
479ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher	fprintf(stderr, "\t\tCompress using strategy1,strategy2,...,strategyN"
480ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher		" in turn\n");
481ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher	fprintf(stderr, "\t\tand choose the best compression.\n");
482ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher	fprintf(stderr, "\t\tAvailable strategies: default, filtered, "
483ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher		"huffman_only,\n\t\trun_length_encoded and fixed\n");
4840c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher}
4850c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher
4860c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher
48723a6f30f9bcef494438dd8f1993fc22dcfb3708eplougherstruct compressor gzip_comp_ops = {
4883c765f0e6269d11c95accd03bb8dbb00e88a2721plougher	.init = gzip_init,
48923a6f30f9bcef494438dd8f1993fc22dcfb3708eplougher	.compress = gzip_compress,
49023a6f30f9bcef494438dd8f1993fc22dcfb3708eplougher	.uncompress = gzip_uncompress,
4910c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	.options = gzip_options,
492ef50ceabd93384b842032e0f6abec2a10256bdedPhillip Lougher	.options_post = gzip_options_post,
4930c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	.dump_options = gzip_dump_options,
4940c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	.extract_options = gzip_extract_options,
4950c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	.display_options = gzip_display_options,
4960c84e6ffcd10f9eace6be2d4a085c25928ed77ddPhillip Lougher	.usage = gzip_usage,
49723a6f30f9bcef494438dd8f1993fc22dcfb3708eplougher	.id = ZLIB_COMPRESSION,
49823a6f30f9bcef494438dd8f1993fc22dcfb3708eplougher	.name = "gzip",
49923a6f30f9bcef494438dd8f1993fc22dcfb3708eplougher	.supported = 1
50023a6f30f9bcef494438dd8f1993fc22dcfb3708eplougher};
501