Visualization Library 2.0.0-b5

A lightweight C++ OpenGL middleware for 2D/3D graphics

VL     Star     Watch     Fork     Issue

[Download] [Tutorials] [All Classes] [Grouped Classes]
minigzip.c
Go to the documentation of this file.
1 /* minigzip.c -- simulate gzip using the zlib compression library
2  * Copyright (C) 1995-2006, 2010, 2011 Jean-loup Gailly.
3  * For conditions of distribution and use, see copyright notice in zlib.h
4  */
5 
6 /*
7  * minigzip is a minimal implementation of the gzip utility. This is
8  * only an example of using zlib and isn't meant to replace the
9  * full-featured gzip. No attempt is made to deal with file systems
10  * limiting names to 14 or 8+3 characters, etc... Error checking is
11  * very limited. So use minigzip only for testing; use gzip for the
12  * real thing. On MSDOS, use only on file names without extension
13  * or in pipe mode.
14  */
15 
16 /* @(#) $Id$ */
17 
18 #include "zlib.h"
19 #include <stdio.h>
20 
21 #ifdef STDC
22 # include <string.h>
23 # include <stdlib.h>
24 #endif
25 
26 #ifdef USE_MMAP
27 # include <sys/types.h>
28 # include <sys/mman.h>
29 # include <sys/stat.h>
30 #endif
31 
32 #if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
33 # include <fcntl.h>
34 # include <io.h>
35 # ifdef UNDER_CE
36 # include <stdlib.h>
37 # endif
38 # define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
39 #else
40 # define SET_BINARY_MODE(file)
41 #endif
42 
43 #ifdef _MSC_VER
44 # define snprintf _snprintf
45 #endif
46 
47 #ifdef VMS
48 # define unlink delete
49 # define GZ_SUFFIX "-gz"
50 #endif
51 #ifdef RISCOS
52 # define unlink remove
53 # define GZ_SUFFIX "-gz"
54 # define fileno(file) file->__file
55 #endif
56 #if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
57 # include <unix.h> /* for fileno */
58 #endif
59 
60 #if !defined(Z_HAVE_UNISTD_H) && !defined(_LARGEFILE64_SOURCE)
61 #ifndef WIN32 /* unlink already in stdio.h for WIN32 */
62  extern int unlink OF((const char *));
63 #endif
64 #endif
65 
66 #if defined(UNDER_CE)
67 # include <windows.h>
68 # define perror(s) pwinerror(s)
69 
70 /* Map the Windows error number in ERROR to a locale-dependent error
71  message string and return a pointer to it. Typically, the values
72  for ERROR come from GetLastError.
73 
74  The string pointed to shall not be modified by the application,
75  but may be overwritten by a subsequent call to strwinerror
76 
77  The strwinerror function does not change the current setting
78  of GetLastError. */
79 
80 static char *strwinerror (error)
81  DWORD error;
82 {
83  static char buf[1024];
84 
85  wchar_t *msgbuf;
86  DWORD lasterr = GetLastError();
87  DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
88  | FORMAT_MESSAGE_ALLOCATE_BUFFER,
89  NULL,
90  error,
91  0, /* Default language */
92  (LPVOID)&msgbuf,
93  0,
94  NULL);
95  if (chars != 0) {
96  /* If there is an \r\n appended, zap it. */
97  if (chars >= 2
98  && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') {
99  chars -= 2;
100  msgbuf[chars] = 0;
101  }
102 
103  if (chars > sizeof (buf) - 1) {
104  chars = sizeof (buf) - 1;
105  msgbuf[chars] = 0;
106  }
107 
108  wcstombs(buf, msgbuf, chars + 1);
109  LocalFree(msgbuf);
110  }
111  else {
112  sprintf(buf, "unknown win32 error (%ld)", error);
113  }
114 
115  SetLastError(lasterr);
116  return buf;
117 }
118 
119 static void pwinerror (s)
120  const char *s;
121 {
122  if (s && *s)
123  fprintf(stderr, "%s: %s\n", s, strwinerror(GetLastError ()));
124  else
125  fprintf(stderr, "%s\n", strwinerror(GetLastError ()));
126 }
127 
128 #endif /* UNDER_CE */
129 
130 #ifndef GZ_SUFFIX
131 # define GZ_SUFFIX ".gz"
132 #endif
133 #define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1)
134 
135 #define BUFLEN 16384
136 #define MAX_NAME_LEN 1024
137 
138 #ifdef MAXSEG_64K
139 # define local static
140  /* Needed for systems with limitation on stack size. */
141 #else
142 # define local
143 #endif
144 
145 #ifdef Z_SOLO
146 /* for Z_SOLO, create simplified gz* functions using deflate and inflate */
147 
148 #if defined(Z_HAVE_UNISTD_H) || defined(Z_LARGE)
149 # include <unistd.h> /* for unlink() */
150 #endif
151 
152 void *myalloc OF((void *, unsigned, unsigned));
153 void myfree OF((void *, void *));
154 
155 void *myalloc(q, n, m)
156  void *q;
157  unsigned n, m;
158 {
159  q = Z_NULL;
160  return calloc(n, m);
161 }
162 
163 void myfree(q, p)
164  void *q, *p;
165 {
166  q = Z_NULL;
167  free(p);
168 }
169 
170 typedef struct gzFile_s {
171  FILE *file;
172  int write;
173  int err;
174  char *msg;
175  z_stream strm;
176 } *gzFile;
177 
178 gzFile gzopen OF((const char *, const char *));
179 gzFile gzdopen OF((int, const char *));
180 gzFile gz_open OF((const char *, int, const char *));
181 
183 const char *path;
184 const char *mode;
185 {
186  return gz_open(path, -1, mode);
187 }
188 
189 gzFile gzdopen(fd, mode)
190 int fd;
191 const char *mode;
192 {
193  return gz_open(NULL, fd, mode);
194 }
195 
196 gzFile gz_open(path, fd, mode)
197  const char *path;
198  int fd;
199  const char *mode;
200 {
201  gzFile gz;
202  int ret;
203 
204  gz = malloc(sizeof(struct gzFile_s));
205  if (gz == NULL)
206  return NULL;
207  gz->write = strchr(mode, 'w') != NULL;
208  gz->strm.zalloc = myalloc;
209  gz->strm.zfree = myfree;
210  gz->strm.opaque = Z_NULL;
211  if (gz->write)
212  ret = deflateInit2(&(gz->strm), -1, 8, 15 + 16, 8, 0);
213  else {
214  gz->strm.next_in = 0;
215  gz->strm.avail_in = Z_NULL;
216  ret = inflateInit2(&(gz->strm), 15 + 16);
217  }
218  if (ret != Z_OK) {
219  free(gz);
220  return NULL;
221  }
222  gz->file = path == NULL ? fdopen(fd, gz->write ? "wb" : "rb") :
223  fopen(path, gz->write ? "wb" : "rb");
224  if (gz->file == NULL) {
225  gz->write ? deflateEnd(&(gz->strm)) : inflateEnd(&(gz->strm));
226  free(gz);
227  return NULL;
228  }
229  gz->err = 0;
230  gz->msg = "";
231  return gz;
232 }
233 
234 int gzwrite OF((gzFile, const void *, unsigned));
235 
236 int gzwrite(gz, buf, len)
237  gzFile gz;
238  const void *buf;
239  unsigned len;
240 {
241  z_stream *strm;
242  unsigned char out[BUFLEN];
243 
244  if (gz == NULL || !gz->write)
245  return 0;
246  strm = &(gz->strm);
247  strm->next_in = (void *)buf;
248  strm->avail_in = len;
249  do {
250  strm->next_out = out;
251  strm->avail_out = BUFLEN;
252  (void)deflate(strm, Z_NO_FLUSH);
253  fwrite(out, 1, BUFLEN - strm->avail_out, gz->file);
254  } while (strm->avail_out == 0);
255  return len;
256 }
257 
258 int gzread OF((gzFile, void *, unsigned));
259 
260 int gzread(gz, buf, len)
261  gzFile gz;
262  void *buf;
263  unsigned len;
264 {
265  int ret;
266  unsigned got;
267  unsigned char in[1];
268  z_stream *strm;
269 
270  if (gz == NULL || gz->write)
271  return 0;
272  if (gz->err)
273  return 0;
274  strm = &(gz->strm);
275  strm->next_out = (void *)buf;
276  strm->avail_out = len;
277  do {
278  got = fread(in, 1, 1, gz->file);
279  if (got == 0)
280  break;
281  strm->next_in = in;
282  strm->avail_in = 1;
283  ret = inflate(strm, Z_NO_FLUSH);
284  if (ret == Z_DATA_ERROR) {
285  gz->err = Z_DATA_ERROR;
286  gz->msg = strm->msg;
287  return 0;
288  }
289  if (ret == Z_STREAM_END)
290  inflateReset(strm);
291  } while (strm->avail_out);
292  return len - strm->avail_out;
293 }
294 
295 int gzclose OF((gzFile));
296 
297 int gzclose(gz)
298  gzFile gz;
299 {
300  z_stream *strm;
301  unsigned char out[BUFLEN];
302 
303  if (gz == NULL)
304  return Z_STREAM_ERROR;
305  strm = &(gz->strm);
306  if (gz->write) {
307  strm->next_in = Z_NULL;
308  strm->avail_in = 0;
309  do {
310  strm->next_out = out;
311  strm->avail_out = BUFLEN;
312  (void)deflate(strm, Z_FINISH);
313  fwrite(out, 1, BUFLEN - strm->avail_out, gz->file);
314  } while (strm->avail_out == 0);
315  deflateEnd(strm);
316  }
317  else
318  inflateEnd(strm);
319  fclose(gz->file);
320  free(gz);
321  return Z_OK;
322 }
323 
324 const char *gzerror OF((gzFile, int *));
325 
326 const char *gzerror(gz, err)
327  gzFile gz;
328  int *err;
329 {
330  *err = gz->err;
331  return gz->msg;
332 }
333 
334 #endif
335 
336 char *prog;
337 
338 void error OF((const char *msg));
339 void gz_compress OF((FILE *in, gzFile out));
340 #ifdef USE_MMAP
341 int gz_compress_mmap OF((FILE *in, gzFile out));
342 #endif
343 void gz_uncompress OF((gzFile in, FILE *out));
344 void file_compress OF((char *file, char *mode));
345 void file_uncompress OF((char *file));
346 int main OF((int argc, char *argv[]));
347 
348 /* ===========================================================================
349  * Display error message and exit
350  */
351 void error(msg)
352  const char *msg;
353 {
354  fprintf(stderr, "%s: %s\n", prog, msg);
355  exit(1);
356 }
357 
358 /* ===========================================================================
359  * Compress input to output then close both files.
360  */
361 
362 void gz_compress(in, out)
363  FILE *in;
364  gzFile out;
365 {
366  local char buf[BUFLEN];
367  int len;
368  int err;
369 
370 #ifdef USE_MMAP
371  /* Try first compressing with mmap. If mmap fails (minigzip used in a
372  * pipe), use the normal fread loop.
373  */
374  if (gz_compress_mmap(in, out) == Z_OK) return;
375 #endif
376  for (;;) {
377  len = (int)fread(buf, 1, sizeof(buf), in);
378  if (ferror(in)) {
379  perror("fread");
380  exit(1);
381  }
382  if (len == 0) break;
383 
384  if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err));
385  }
386  fclose(in);
387  if (gzclose(out) != Z_OK) error("failed gzclose");
388 }
389 
390 #ifdef USE_MMAP /* MMAP version, Miguel Albrecht <malbrech@eso.org> */
391 
392 /* Try compressing the input file at once using mmap. Return Z_OK if
393  * if success, Z_ERRNO otherwise.
394  */
395 int gz_compress_mmap(in, out)
396  FILE *in;
397  gzFile out;
398 {
399  int len;
400  int err;
401  int ifd = fileno(in);
402  caddr_t buf; /* mmap'ed buffer for the entire input file */
403  off_t buf_len; /* length of the input file */
404  struct stat sb;
405 
406  /* Determine the size of the file, needed for mmap: */
407  if (fstat(ifd, &sb) < 0) return Z_ERRNO;
408  buf_len = sb.st_size;
409  if (buf_len <= 0) return Z_ERRNO;
410 
411  /* Now do the actual mmap: */
412  buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0);
413  if (buf == (caddr_t)(-1)) return Z_ERRNO;
414 
415  /* Compress the whole file at once: */
416  len = gzwrite(out, (char *)buf, (unsigned)buf_len);
417 
418  if (len != (int)buf_len) error(gzerror(out, &err));
419 
420  munmap(buf, buf_len);
421  fclose(in);
422  if (gzclose(out) != Z_OK) error("failed gzclose");
423  return Z_OK;
424 }
425 #endif /* USE_MMAP */
426 
427 /* ===========================================================================
428  * Uncompress input to output then close both files.
429  */
430 void gz_uncompress(in, out)
431  gzFile in;
432  FILE *out;
433 {
434  local char buf[BUFLEN];
435  int len;
436  int err;
437 
438  for (;;) {
439  len = gzread(in, buf, sizeof(buf));
440  if (len < 0) error (gzerror(in, &err));
441  if (len == 0) break;
442 
443  if ((int)fwrite(buf, 1, (unsigned)len, out) != len) {
444  error("failed fwrite");
445  }
446  }
447  if (fclose(out)) error("failed fclose");
448 
449  if (gzclose(in) != Z_OK) error("failed gzclose");
450 }
451 
452 
453 /* ===========================================================================
454  * Compress the given file: create a corresponding .gz file and remove the
455  * original.
456  */
457 void file_compress(file, mode)
458  char *file;
459  char *mode;
460 {
461  local char outfile[MAX_NAME_LEN];
462  FILE *in;
463  gzFile out;
464 
465  if (strlen(file) + strlen(GZ_SUFFIX) >= sizeof(outfile)) {
466  fprintf(stderr, "%s: filename too long\n", prog);
467  exit(1);
468  }
469 
470 #if !defined(NO_snprintf) && !defined(NO_vsnprintf)
471  snprintf(outfile, sizeof(outfile), "%s%s", file, GZ_SUFFIX);
472 #else
473  strcpy(outfile, file);
474  strcat(outfile, GZ_SUFFIX);
475 #endif
476 
477  in = fopen(file, "rb");
478  if (in == NULL) {
479  perror(file);
480  exit(1);
481  }
482  out = gzopen(outfile, mode);
483  if (out == NULL) {
484  fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile);
485  exit(1);
486  }
487  gz_compress(in, out);
488 
489  unlink(file);
490 }
491 
492 
493 /* ===========================================================================
494  * Uncompress the given file and remove the original.
495  */
496 void file_uncompress(file)
497  char *file;
498 {
499  local char buf[MAX_NAME_LEN];
500  char *infile, *outfile;
501  FILE *out;
502  gzFile in;
503  size_t len = strlen(file);
504 
505  if (len + strlen(GZ_SUFFIX) >= sizeof(buf)) {
506  fprintf(stderr, "%s: filename too long\n", prog);
507  exit(1);
508  }
509 
510 #if !defined(NO_snprintf) && !defined(NO_vsnprintf)
511  snprintf(buf, sizeof(buf), "%s", file);
512 #else
513  strcpy(buf, file);
514 #endif
515 
516  if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) {
517  infile = file;
518  outfile = buf;
519  outfile[len-3] = '\0';
520  } else {
521  outfile = file;
522  infile = buf;
523 #if !defined(NO_snprintf) && !defined(NO_vsnprintf)
524  snprintf(buf + len, sizeof(buf) - len, "%s", GZ_SUFFIX);
525 #else
526  strcat(infile, GZ_SUFFIX);
527 #endif
528  }
529  in = gzopen(infile, "rb");
530  if (in == NULL) {
531  fprintf(stderr, "%s: can't gzopen %s\n", prog, infile);
532  exit(1);
533  }
534  out = fopen(outfile, "wb");
535  if (out == NULL) {
536  perror(file);
537  exit(1);
538  }
539 
540  gz_uncompress(in, out);
541 
542  unlink(infile);
543 }
544 
545 
546 /* ===========================================================================
547  * Usage: minigzip [-c] [-d] [-f] [-h] [-r] [-1 to -9] [files...]
548  * -c : write to standard output
549  * -d : decompress
550  * -f : compress with Z_FILTERED
551  * -h : compress with Z_HUFFMAN_ONLY
552  * -r : compress with Z_RLE
553  * -1 to -9 : compression level
554  */
555 
556 int main(argc, argv)
557  int argc;
558  char *argv[];
559 {
560  int copyout = 0;
561  int uncompr = 0;
562  gzFile file;
563  char *bname, outmode[20];
564 
565 #if !defined(NO_snprintf) && !defined(NO_vsnprintf)
566  snprintf(outmode, sizeof(outmode), "%s", "wb6 ");
567 #else
568  strcpy(outmode, "wb6 ");
569 #endif
570 
571  prog = argv[0];
572  bname = strrchr(argv[0], '/');
573  if (bname)
574  bname++;
575  else
576  bname = argv[0];
577  argc--, argv++;
578 
579  if (!strcmp(bname, "gunzip"))
580  uncompr = 1;
581  else if (!strcmp(bname, "zcat"))
582  copyout = uncompr = 1;
583 
584  while (argc > 0) {
585  if (strcmp(*argv, "-c") == 0)
586  copyout = 1;
587  else if (strcmp(*argv, "-d") == 0)
588  uncompr = 1;
589  else if (strcmp(*argv, "-f") == 0)
590  outmode[3] = 'f';
591  else if (strcmp(*argv, "-h") == 0)
592  outmode[3] = 'h';
593  else if (strcmp(*argv, "-r") == 0)
594  outmode[3] = 'R';
595  else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' &&
596  (*argv)[2] == 0)
597  outmode[2] = (*argv)[1];
598  else
599  break;
600  argc--, argv++;
601  }
602  if (outmode[3] == ' ')
603  outmode[3] = 0;
604  if (argc == 0) {
605  SET_BINARY_MODE(stdin);
606  SET_BINARY_MODE(stdout);
607  if (uncompr) {
608  file = gzdopen(fileno(stdin), "rb");
609  if (file == NULL) error("can't gzdopen stdin");
610  gz_uncompress(file, stdout);
611  } else {
612  file = gzdopen(fileno(stdout), outmode);
613  if (file == NULL) error("can't gzdopen stdout");
614  gz_compress(stdin, file);
615  }
616  } else {
617  if (copyout) {
618  SET_BINARY_MODE(stdout);
619  }
620  do {
621  if (uncompr) {
622  if (copyout) {
623  file = gzopen(*argv, "rb");
624  if (file == NULL)
625  fprintf(stderr, "%s: can't gzopen %s\n", prog, *argv);
626  else
627  gz_uncompress(file, stdout);
628  } else {
629  file_uncompress(*argv);
630  }
631  } else {
632  if (copyout) {
633  FILE * in = fopen(*argv, "rb");
634 
635  if (in == NULL) {
636  perror(*argv);
637  } else {
638  file = gzdopen(fileno(stdout), outmode);
639  if (file == NULL) error("can't gzdopen stdout");
640 
641  gz_compress(in, file);
642  }
643 
644  } else {
645  file_compress(*argv, outmode);
646  }
647  }
648  } while (argv++, --argc);
649  }
650  return 0;
651 }
#define local
Definition: minigzip.c:142
#define Z_STREAM_ERROR
Definition: zlib.h:136
GLfloat GLfloat p
Bytef * next_in
Definition: zlib.h:69
int write(int fd, const char *buf, int nbytes)
Definition: tif_acorn.c:325
#define NULL
Definition: ftobjs.h:61
GLdouble GLdouble GLdouble GLdouble q
uInt avail_in
Definition: zlib.h:70
char * malloc()
#define Z_NO_FLUSH
Definition: zlib.h:125
local gzFile gz_open(void *path, int fd, const char *mode) const
Definition: gzlib.c:91
int main(int argc, argv)
Definition: minigzip.c:556
int ZEXPORT gzclose(gzFile file)
Definition: gzclose.c:11
char * msg
Definition: zlib.h:77
int ZEXPORT inflateReset(z_streamp strm)
Definition: dummy_inflate.c:8
int unlink OF((const char *))
typedef void(APIENTRY *GLDEBUGPROCARB)(GLenum source
int ZEXPORT deflateEnd(z_streamp strm)
Definition: deflate.c:979
void error(char *msg) const
Definition: minigzip.c:351
int ZEXPORT gzwrite(gzFile file, voidpc buf, unsigned len)
Definition: gzwrite.c:165
#define inflateInit2(strm, windowBits)
Definition: zlib.h:822
GLenum GLuint GLenum GLsizei const GLchar * buf
#define Z_FINISH
Definition: zlib.h:129
#define Z_OK
Definition: zlib.h:132
char * prog
Definition: minigzip.c:336
#define MAX_NAME_LEN
Definition: minigzip.c:136
void file_compress(char *file, char *mode)
Definition: minigzip.c:457
GLsizei const GLchar ** path
FILE * outfile
Definition: jpeglib.h:910
GLenum GLsizei len
GLenum mode
#define SET_BINARY_MODE(file)
Definition: minigzip.c:40
local int out(void *out_desc, unsigned char *buf, unsigned len)
Definition: gun.c:131
int ZEXPORT inflate(z_streamp strm, int flush)
Definition: dummy_inflate.c:3
#define Z_NULL
Definition: zlib.h:164
GLdouble n
gzFile ZEXPORT gzdopen(int fd, const char *mode)
Definition: gzlib.c:284
void file_uncompress(char *file)
Definition: minigzip.c:496
int free()
#define GZ_SUFFIX
Definition: minigzip.c:131
const GLfloat * m
int ZEXPORT deflate(z_streamp strm, int flush)
Definition: deflate.c:665
typedef int
Definition: png.h:978
const char *ZEXPORT gzerror(gzFile file, int *errnum)
Definition: gzlib.c:528
#define deflateInit2(strm, level, method, windowBits, memLevel, strategy)
Definition: zlib.h:819
FILE * infile
Definition: cdjpeg.h:141
GLuint in
struct gzFile_s * gzFile
Definition: zlib.h:1224
GLdouble s
uInt avail_out
Definition: zlib.h:74
void gz_compress(FILE *in, gzFile out)
Definition: minigzip.c:362
void gz_uncompress(gzFile in, FILE *out)
Definition: minigzip.c:430
gzFile ZEXPORT gzopen(char *path, const char *mode) const
Definition: gzlib.c:268
#define BUFLEN
Definition: minigzip.c:135
#define Z_DATA_ERROR
Definition: zlib.h:137
int ZEXPORT gzread(gzFile file, voidp buf, unsigned len)
Definition: gzread.c:288
Bytef * next_out
Definition: zlib.h:73
int ZEXPORT inflateEnd(z_streamp strm)
Definition: dummy_inflate.c:12
#define SUFFIX_LEN
Definition: minigzip.c:133
png_const_charp msg
Definition: PngFile.c:23
#define Z_ERRNO
Definition: zlib.h:135
#define Z_STREAM_END
Definition: zlib.h:133