zopfli_bin.c revision d5eb5f507386e9933f2d8248d311ceca41fe1df1
1d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne/*
2d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode VandevenneCopyright 2011 Google Inc. All Rights Reserved.
3d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne
4d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode VandevenneLicensed under the Apache License, Version 2.0 (the "License");
5d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenneyou may not use this file except in compliance with the License.
6d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode VandevenneYou may obtain a copy of the License at
7d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne
8d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne    http://www.apache.org/licenses/LICENSE-2.0
9d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne
10d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode VandevenneUnless required by applicable law or agreed to in writing, software
11d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevennedistributed under the License is distributed on an "AS IS" BASIS,
12d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode VandevenneWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode VandevenneSee the License for the specific language governing permissions and
14d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevennelimitations under the License.
15d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne
16d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode VandevenneAuthor: lode.vandevenne@gmail.com (Lode Vandevenne)
17d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode VandevenneAuthor: jyrki.alakuijala@gmail.com (Jyrki Alakuijala)
18d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne*/
19d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne
20d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne/*
21d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode VandevenneZopfli compressor program. It can output gzip-, zlib- or deflate-compatible
22d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevennedata. By default it creates a .gz file. This tool can only compress, not
23d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevennedecompress. Decompression can be done by any standard gzip, zlib or deflate
24d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevennedecompressor.
25d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne*/
26d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne
27d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne#include <assert.h>
28d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne#include <stdio.h>
29d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne#include <stdlib.h>
30d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne#include <string.h>
31d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne
32d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne#include "deflate.h"
33d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne#include "gzip_container.h"
34d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne#include "zlib_container.h"
35d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne
36d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne/*
37d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode VandevenneLoads a file into a memory array.
38d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne*/
39d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevennestatic void LoadFile(const char* filename,
40d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne                     unsigned char** out, size_t* outsize) {
41d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  FILE* file;
42d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne
43d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  *out = 0;
44d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  *outsize = 0;
45d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  file = fopen(filename, "rb");
46d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  if (!file) return;
47d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne
48d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  fseek(file , 0 , SEEK_END);
49d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  *outsize = ftell(file);
50d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  rewind(file);
51d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne
52d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  *out = (unsigned char*)malloc(*outsize);
53d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne
54d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  if (*outsize && (*out)) {
55d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne    size_t testsize = fread(*out, 1, *outsize, file);
56d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne    if (testsize != *outsize) {
57d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne      /* It could be a directory */
58d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne      free(*out);
59d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne      *out = 0;
60d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne      *outsize = 0;
61d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne    }
62d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  }
63d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne
64d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  assert(!(*outsize) || out);  /* If size is not zero, out must be allocated. */
65d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  fclose(file);
66d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne}
67d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne
68d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne/*
69d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode VandevenneSaves a file from a memory array, overwriting the file if it existed.
70d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne*/
71d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevennestatic void SaveFile(const char* filename,
72d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne                     const unsigned char* in, size_t insize) {
73d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  FILE* file = fopen(filename, "wb" );
74d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  assert(file);
75d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  fwrite((char*)in, 1, insize, file);
76d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  fclose(file);
77d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne}
78d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne
79d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevennetypedef enum {
80d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  OUTPUT_GZIP,
81d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  OUTPUT_ZLIB,
82d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  OUTPUT_DEFLATE
83d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne} OutputType;
84d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne
85d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne/*
86d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenneoutfilename: filename to write output to, or 0 to write to stdout instead
87d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne*/
88d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevennevoid CompressFile(const Options* options,
89d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne                  OutputType output_type,
90d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne                  const char* infilename,
91d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne                  const char* outfilename) {
92d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  unsigned char* in;
93d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  size_t insize;
94d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  unsigned char* out = 0;
95d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  size_t outsize = 0;
96d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  LoadFile(infilename, &in, &insize);
97d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  if (insize == 0) {
98d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne    fprintf(stderr, "Invalid filename: %s\n", infilename);
99d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne    return;
100d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  }
101d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  if (output_type == OUTPUT_GZIP) {
102d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne    GzipCompress(options, in, insize, &out, &outsize);
103d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  } else if (output_type == OUTPUT_ZLIB) {
104d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne    ZlibCompress(options, in, insize, &out, &outsize);
105d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  } else if (output_type == OUTPUT_DEFLATE) {
106d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne    unsigned char bp = 0;
107d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne    Deflate(options, 2 /* Dynamic block */, 1, in, insize, &bp, &out, &outsize);
108d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  } else {
109d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne    assert(0);
110d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  }
111d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  if (outfilename) {
112d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne    SaveFile(outfilename, out, outsize);
113d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  } else {
114d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne    size_t i;
115d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne    for (i = 0; i < outsize; i++) {
116d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne      /* Works only if terminal does not convert newlines. */
117d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne      printf("%c", out[i]);
118d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne    }
119d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  }
120d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne
121d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  free(out);
122d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  free(in);
123d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne}
124d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne
125d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne/*
126d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode VandevenneAdd two strings together. Size does not matter. Result must be freed.
127d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne*/
128d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevennestatic char* AddStrings(const char* str1, const char* str2) {
129d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  size_t len = strlen(str1) + strlen(str2);
130d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  char* result = (char*)malloc(len + 1);
131d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  if (!result) exit(-1); /* Allocation failed. */
132d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  strcpy(result, str1);
133d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  strcat(result, str2);
134d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  return result;
135d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne}
136d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne
137d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevennestatic char StringsEqual(const char* str1, const char* str2) {
138d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  return strcmp(str1, str2) == 0;
139d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne}
140d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne
141d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenneint main(int argc, char* argv[]) {
142d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  Options options;
143d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  const char* filename = 0;
144d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  int output_to_stdout = 0;
145d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  int i;
146d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  OutputType output_type = OUTPUT_GZIP;
147d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne
148d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  InitOptions(&options);
149d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne
150d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  for (i = 1; i < argc; i++) {
151d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne    if (StringsEqual(argv[i], "-v")) options.verbose = 1;
152d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne    else if (StringsEqual(argv[i], "-c")) output_to_stdout = 1;
153d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne    else if (StringsEqual(argv[i], "--deflate")) output_type = OUTPUT_DEFLATE;
154d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne    else if (StringsEqual(argv[i], "--zlib")) output_type = OUTPUT_ZLIB;
155d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne    else if (StringsEqual(argv[i], "--gzip")) output_type = OUTPUT_GZIP;
156d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne    else if (StringsEqual(argv[i], "--i5")) options.numiterations = 5;
157d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne    else if (StringsEqual(argv[i], "--i10")) options.numiterations = 10;
158d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne    else if (StringsEqual(argv[i], "--i15")) options.numiterations = 15;
159d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne    else if (StringsEqual(argv[i], "--i25")) options.numiterations = 25;
160d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne    else if (StringsEqual(argv[i], "--i50")) options.numiterations = 50;
161d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne    else if (StringsEqual(argv[i], "--i100")) options.numiterations = 100;
162d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne    else if (StringsEqual(argv[i], "--i250")) options.numiterations = 250;
163d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne    else if (StringsEqual(argv[i], "--i500")) options.numiterations = 500;
164d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne    else if (StringsEqual(argv[i], "--i1000")) options.numiterations = 1000;
165d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne    else if (StringsEqual(argv[i], "-h")) {
166d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne      fprintf(stderr, "Usage: zopfli [OPTION]... FILE\n"
167d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne          "  -h    gives this help\n"
168d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne          "  -c    write the result on standard output, instead of disk"
169d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne          " filename + '.gz'\n"
170d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne          "  -v    verbose mode\n"
171d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne          "  --gzip  output to gzip format (default)\n"
172d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne          "  --deflate  output to deflate format instead of gzip\n"
173d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne          "  --zlib  output to zlib format instead of gzip\n");
174d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne      fprintf(stderr, "  --i5  less compression, but faster\n"
175d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne          "  --i10  less compression, but faster\n"
176d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne          "  --i15  default compression, 15 iterations\n"
177d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne          "  --i25  more compression, but slower\n"
178d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne          "  --i50  more compression, but slower\n"
179d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne          "  --i100  more compression, but slower\n"
180d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne          "  --i250  more compression, but slower\n"
181d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne          "  --i500  more compression, but slower\n"
182d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne          "  --i1000  more compression, but slower\n");
183d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne      return 0;
184d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne    }
185d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  }
186d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne
187d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  for (i = 1; i < argc; i++) {
188d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne    if (argv[i][0] != '-') {
189d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne      char* outfilename;
190d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne      filename = argv[i];
191d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne      if (output_to_stdout) {
192d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne        outfilename = 0;
193d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne      } else if (output_type == OUTPUT_GZIP) {
194d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne        outfilename = AddStrings(filename, ".gz");
195d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne      } else if (output_type == OUTPUT_ZLIB) {
196d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne        outfilename = AddStrings(filename, ".zlib");
197d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne      } else if (output_type == OUTPUT_DEFLATE) {
198d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne        outfilename = AddStrings(filename, ".deflate");
199d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne      } else {
200d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne        assert(0);
201d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne      }
202d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne      if (options.verbose && outfilename) {
203d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne        fprintf(stderr, "Saving to: %s\n", outfilename);
204d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne      }
205d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne      CompressFile(&options, output_type, filename, outfilename);
206d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne      free(outfilename);
207d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne    }
208d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  }
209d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne
210d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  if (!filename) {
211d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne    fprintf(stderr,
212d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne            "Please provide filename\nFor help, type: %s -h\n", argv[0]);
213d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  }
214d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne
215d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne  return 0;
216d5eb5f507386e9933f2d8248d311ceca41fe1df1Lode Vandevenne}
217