From 4975aa5e50761cdeb335b3bf029332df469aa472 Mon Sep 17 00:00:00 2001 From: Lode Vandevenne Date: Thu, 25 Apr 2013 16:00:01 +0200 Subject: Improved directory structure with the source code under src --- src/zopfli/zopfli_bin.c | 203 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 203 insertions(+) create mode 100644 src/zopfli/zopfli_bin.c (limited to 'src/zopfli/zopfli_bin.c') diff --git a/src/zopfli/zopfli_bin.c b/src/zopfli/zopfli_bin.c new file mode 100644 index 0000000..8a147ef --- /dev/null +++ b/src/zopfli/zopfli_bin.c @@ -0,0 +1,203 @@ +/* +Copyright 2011 Google Inc. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +Author: lode.vandevenne@gmail.com (Lode Vandevenne) +Author: jyrki.alakuijala@gmail.com (Jyrki Alakuijala) +*/ + +/* +Zopfli compressor program. It can output gzip-, zlib- or deflate-compatible +data. By default it creates a .gz file. This tool can only compress, not +decompress. Decompression can be done by any standard gzip, zlib or deflate +decompressor. +*/ + +#include +#include +#include +#include + +#include "deflate.h" +#include "gzip_container.h" +#include "zlib_container.h" + +/* +Loads a file into a memory array. +*/ +static void LoadFile(const char* filename, + unsigned char** out, size_t* outsize) { + FILE* file; + + *out = 0; + *outsize = 0; + file = fopen(filename, "rb"); + if (!file) return; + + fseek(file , 0 , SEEK_END); + *outsize = ftell(file); + rewind(file); + + *out = (unsigned char*)malloc(*outsize); + + if (*outsize && (*out)) { + size_t testsize = fread(*out, 1, *outsize, file); + if (testsize != *outsize) { + /* It could be a directory */ + free(*out); + *out = 0; + *outsize = 0; + } + } + + assert(!(*outsize) || out); /* If size is not zero, out must be allocated. */ + fclose(file); +} + +/* +Saves a file from a memory array, overwriting the file if it existed. +*/ +static void SaveFile(const char* filename, + const unsigned char* in, size_t insize) { + FILE* file = fopen(filename, "wb" ); + assert(file); + fwrite((char*)in, 1, insize, file); + fclose(file); +} + +/* +outfilename: filename to write output to, or 0 to write to stdout instead +*/ +static void CompressFile(const ZopfliOptions* options, + ZopfliFormat output_type, + const char* infilename, + const char* outfilename) { + unsigned char* in; + size_t insize; + unsigned char* out = 0; + size_t outsize = 0; + LoadFile(infilename, &in, &insize); + if (insize == 0) { + fprintf(stderr, "Invalid filename: %s\n", infilename); + return; + } + + ZopfliCompress(options, output_type, in, insize, &out, &outsize); + + if (outfilename) { + SaveFile(outfilename, out, outsize); + } else { + size_t i; + for (i = 0; i < outsize; i++) { + /* Works only if terminal does not convert newlines. */ + printf("%c", out[i]); + } + } + + free(out); + free(in); +} + +/* +Add two strings together. Size does not matter. Result must be freed. +*/ +static char* AddStrings(const char* str1, const char* str2) { + size_t len = strlen(str1) + strlen(str2); + char* result = (char*)malloc(len + 1); + if (!result) exit(-1); /* Allocation failed. */ + strcpy(result, str1); + strcat(result, str2); + return result; +} + +static char StringsEqual(const char* str1, const char* str2) { + return strcmp(str1, str2) == 0; +} + +int main(int argc, char* argv[]) { + ZopfliOptions options; + ZopfliFormat output_type = ZOPFLI_FORMAT_GZIP; + const char* filename = 0; + int output_to_stdout = 0; + int i; + + ZopfliInitOptions(&options); + + for (i = 1; i < argc; i++) { + const char* arg = argv[i]; + if (StringsEqual(arg, "-v")) options.verbose = 1; + else if (StringsEqual(arg, "-c")) output_to_stdout = 1; + else if (StringsEqual(arg, "--deflate")) { + output_type = ZOPFLI_FORMAT_DEFLATE; + } + else if (StringsEqual(arg, "--zlib")) output_type = ZOPFLI_FORMAT_ZLIB; + else if (StringsEqual(arg, "--gzip")) output_type = ZOPFLI_FORMAT_GZIP; + else if (StringsEqual(arg, "--splitlast")) options.blocksplittinglast = 1; + else if (arg[0] == '-' && arg[1] == '-' && arg[2] == 'i' + && arg[3] >= '0' && arg[3] <= '9') { + options.numiterations = atoi(arg + 3); + } + else if (StringsEqual(arg, "-h")) { + fprintf(stderr, + "Usage: zopfli [OPTION]... FILE\n" + " -h gives this help\n" + " -c write the result on standard output, instead of disk" + " filename + '.gz'\n" + " -v verbose mode\n" + " --i# perform # iterations (default 15). More gives" + " more compression but is slower." + " Examples: --i10, --i50, --i1000\n"); + fprintf(stderr, + " --gzip output to gzip format (default)\n" + " --zlib output to zlib format instead of gzip\n" + " --deflate output to deflate format instead of gzip\n" + " --splitlast do block splitting last instead of first\n"); + return 0; + } + } + + if (options.numiterations < 1) { + fprintf(stderr, "Error: must have 1 or more iterations"); + return 0; + } + + for (i = 1; i < argc; i++) { + if (argv[i][0] != '-') { + char* outfilename; + filename = argv[i]; + if (output_to_stdout) { + outfilename = 0; + } else if (output_type == ZOPFLI_FORMAT_GZIP) { + outfilename = AddStrings(filename, ".gz"); + } else if (output_type == ZOPFLI_FORMAT_ZLIB) { + outfilename = AddStrings(filename, ".zlib"); + } else { + assert(output_type == ZOPFLI_FORMAT_DEFLATE); + outfilename = AddStrings(filename, ".deflate"); + } + if (options.verbose && outfilename) { + fprintf(stderr, "Saving to: %s\n", outfilename); + } + CompressFile(&options, output_type, filename, outfilename); + free(outfilename); + } + } + + if (!filename) { + fprintf(stderr, + "Please provide filename\nFor help, type: %s -h\n", argv[0]); + } + + return 0; +} -- cgit v1.2.3