annotate src/zlib-1.2.7/contrib/puff/pufftest.c @ 4:e13257ea84a4

Add bzip2, zlib, liblo, portaudio sources
author Chris Cannam
date Wed, 20 Mar 2013 13:59:52 +0000
parents
children
rev   line source
Chris@4 1 /*
Chris@4 2 * pufftest.c
Chris@4 3 * Copyright (C) 2002-2010 Mark Adler
Chris@4 4 * For conditions of distribution and use, see copyright notice in puff.h
Chris@4 5 * version 2.2, 25 Apr 2010
Chris@4 6 */
Chris@4 7
Chris@4 8 /* Example of how to use puff().
Chris@4 9
Chris@4 10 Usage: puff [-w] [-f] [-nnn] file
Chris@4 11 ... | puff [-w] [-f] [-nnn]
Chris@4 12
Chris@4 13 where file is the input file with deflate data, nnn is the number of bytes
Chris@4 14 of input to skip before inflating (e.g. to skip a zlib or gzip header), and
Chris@4 15 -w is used to write the decompressed data to stdout. -f is for coverage
Chris@4 16 testing, and causes pufftest to fail with not enough output space (-f does
Chris@4 17 a write like -w, so -w is not required). */
Chris@4 18
Chris@4 19 #include <stdio.h>
Chris@4 20 #include <stdlib.h>
Chris@4 21 #include "puff.h"
Chris@4 22
Chris@4 23 #if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
Chris@4 24 # include <fcntl.h>
Chris@4 25 # include <io.h>
Chris@4 26 # define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
Chris@4 27 #else
Chris@4 28 # define SET_BINARY_MODE(file)
Chris@4 29 #endif
Chris@4 30
Chris@4 31 #define local static
Chris@4 32
Chris@4 33 /* Return size times approximately the cube root of 2, keeping the result as 1,
Chris@4 34 3, or 5 times a power of 2 -- the result is always > size, until the result
Chris@4 35 is the maximum value of an unsigned long, where it remains. This is useful
Chris@4 36 to keep reallocations less than ~33% over the actual data. */
Chris@4 37 local size_t bythirds(size_t size)
Chris@4 38 {
Chris@4 39 int n;
Chris@4 40 size_t m;
Chris@4 41
Chris@4 42 m = size;
Chris@4 43 for (n = 0; m; n++)
Chris@4 44 m >>= 1;
Chris@4 45 if (n < 3)
Chris@4 46 return size + 1;
Chris@4 47 n -= 3;
Chris@4 48 m = size >> n;
Chris@4 49 m += m == 6 ? 2 : 1;
Chris@4 50 m <<= n;
Chris@4 51 return m > size ? m : (size_t)(-1);
Chris@4 52 }
Chris@4 53
Chris@4 54 /* Read the input file *name, or stdin if name is NULL, into allocated memory.
Chris@4 55 Reallocate to larger buffers until the entire file is read in. Return a
Chris@4 56 pointer to the allocated data, or NULL if there was a memory allocation
Chris@4 57 failure. *len is the number of bytes of data read from the input file (even
Chris@4 58 if load() returns NULL). If the input file was empty or could not be opened
Chris@4 59 or read, *len is zero. */
Chris@4 60 local void *load(const char *name, size_t *len)
Chris@4 61 {
Chris@4 62 size_t size;
Chris@4 63 void *buf, *swap;
Chris@4 64 FILE *in;
Chris@4 65
Chris@4 66 *len = 0;
Chris@4 67 buf = malloc(size = 4096);
Chris@4 68 if (buf == NULL)
Chris@4 69 return NULL;
Chris@4 70 in = name == NULL ? stdin : fopen(name, "rb");
Chris@4 71 if (in != NULL) {
Chris@4 72 for (;;) {
Chris@4 73 *len += fread((char *)buf + *len, 1, size - *len, in);
Chris@4 74 if (*len < size) break;
Chris@4 75 size = bythirds(size);
Chris@4 76 if (size == *len || (swap = realloc(buf, size)) == NULL) {
Chris@4 77 free(buf);
Chris@4 78 buf = NULL;
Chris@4 79 break;
Chris@4 80 }
Chris@4 81 buf = swap;
Chris@4 82 }
Chris@4 83 fclose(in);
Chris@4 84 }
Chris@4 85 return buf;
Chris@4 86 }
Chris@4 87
Chris@4 88 int main(int argc, char **argv)
Chris@4 89 {
Chris@4 90 int ret, put = 0, fail = 0;
Chris@4 91 unsigned skip = 0;
Chris@4 92 char *arg, *name = NULL;
Chris@4 93 unsigned char *source = NULL, *dest;
Chris@4 94 size_t len = 0;
Chris@4 95 unsigned long sourcelen, destlen;
Chris@4 96
Chris@4 97 /* process arguments */
Chris@4 98 while (arg = *++argv, --argc)
Chris@4 99 if (arg[0] == '-') {
Chris@4 100 if (arg[1] == 'w' && arg[2] == 0)
Chris@4 101 put = 1;
Chris@4 102 else if (arg[1] == 'f' && arg[2] == 0)
Chris@4 103 fail = 1, put = 1;
Chris@4 104 else if (arg[1] >= '0' && arg[1] <= '9')
Chris@4 105 skip = (unsigned)atoi(arg + 1);
Chris@4 106 else {
Chris@4 107 fprintf(stderr, "invalid option %s\n", arg);
Chris@4 108 return 3;
Chris@4 109 }
Chris@4 110 }
Chris@4 111 else if (name != NULL) {
Chris@4 112 fprintf(stderr, "only one file name allowed\n");
Chris@4 113 return 3;
Chris@4 114 }
Chris@4 115 else
Chris@4 116 name = arg;
Chris@4 117 source = load(name, &len);
Chris@4 118 if (source == NULL) {
Chris@4 119 fprintf(stderr, "memory allocation failure\n");
Chris@4 120 return 4;
Chris@4 121 }
Chris@4 122 if (len == 0) {
Chris@4 123 fprintf(stderr, "could not read %s, or it was empty\n",
Chris@4 124 name == NULL ? "<stdin>" : name);
Chris@4 125 free(source);
Chris@4 126 return 3;
Chris@4 127 }
Chris@4 128 if (skip >= len) {
Chris@4 129 fprintf(stderr, "skip request of %d leaves no input\n", skip);
Chris@4 130 free(source);
Chris@4 131 return 3;
Chris@4 132 }
Chris@4 133
Chris@4 134 /* test inflate data with offset skip */
Chris@4 135 len -= skip;
Chris@4 136 sourcelen = (unsigned long)len;
Chris@4 137 ret = puff(NIL, &destlen, source + skip, &sourcelen);
Chris@4 138 if (ret)
Chris@4 139 fprintf(stderr, "puff() failed with return code %d\n", ret);
Chris@4 140 else {
Chris@4 141 fprintf(stderr, "puff() succeeded uncompressing %lu bytes\n", destlen);
Chris@4 142 if (sourcelen < len) fprintf(stderr, "%lu compressed bytes unused\n",
Chris@4 143 len - sourcelen);
Chris@4 144 }
Chris@4 145
Chris@4 146 /* if requested, inflate again and write decompressd data to stdout */
Chris@4 147 if (put && ret == 0) {
Chris@4 148 if (fail)
Chris@4 149 destlen >>= 1;
Chris@4 150 dest = malloc(destlen);
Chris@4 151 if (dest == NULL) {
Chris@4 152 fprintf(stderr, "memory allocation failure\n");
Chris@4 153 free(source);
Chris@4 154 return 4;
Chris@4 155 }
Chris@4 156 puff(dest, &destlen, source + skip, &sourcelen);
Chris@4 157 SET_BINARY_MODE(stdout);
Chris@4 158 fwrite(dest, 1, destlen, stdout);
Chris@4 159 free(dest);
Chris@4 160 }
Chris@4 161
Chris@4 162 /* clean up */
Chris@4 163 free(source);
Chris@4 164 return ret;
Chris@4 165 }