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]
gzlib.c
Go to the documentation of this file.
1 /* gzlib.c -- zlib functions common to reading and writing gzip files
2  * Copyright (C) 2004, 2010, 2011, 2012, 2013 Mark Adler
3  * For conditions of distribution and use, see copyright notice in zlib.h
4  */
5 
6 #include "gzguts.h"
7 
8 #if defined(_WIN32) && !defined(__BORLANDC__)
9 # define LSEEK _lseeki64
10 #else
11 #if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
12 # define LSEEK lseek64
13 #else
14 # define LSEEK lseek
15 #endif
16 #endif
17 
18 /* Local functions */
19 local void gz_reset OF((gz_statep));
20 local gzFile gz_open OF((const void *, int, const char *));
21 
22 #if defined UNDER_CE
23 
24 /* Map the Windows error number in ERROR to a locale-dependent error message
25  string and return a pointer to it. Typically, the values for ERROR come
26  from GetLastError.
27 
28  The string pointed to shall not be modified by the application, but may be
29  overwritten by a subsequent call to gz_strwinerror
30 
31  The gz_strwinerror function does not change the current setting of
32  GetLastError. */
33 char ZLIB_INTERNAL *gz_strwinerror (error)
34  DWORD error;
35 {
36  static char buf[1024];
37 
38  wchar_t *msgbuf;
39  DWORD lasterr = GetLastError();
40  DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
41  | FORMAT_MESSAGE_ALLOCATE_BUFFER,
42  NULL,
43  error,
44  0, /* Default language */
45  (LPVOID)&msgbuf,
46  0,
47  NULL);
48  if (chars != 0) {
49  /* If there is an \r\n appended, zap it. */
50  if (chars >= 2
51  && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') {
52  chars -= 2;
53  msgbuf[chars] = 0;
54  }
55 
56  if (chars > sizeof (buf) - 1) {
57  chars = sizeof (buf) - 1;
58  msgbuf[chars] = 0;
59  }
60 
61  wcstombs(buf, msgbuf, chars + 1);
62  LocalFree(msgbuf);
63  }
64  else {
65  sprintf(buf, "unknown win32 error (%ld)", error);
66  }
67 
68  SetLastError(lasterr);
69  return buf;
70 }
71 
72 #endif /* UNDER_CE */
73 
74 /* Reset gzip file state */
75 local void gz_reset(state)
76  gz_statep state;
77 {
78  state->x.have = 0; /* no output data available */
79  if (state->mode == GZ_READ) { /* for reading ... */
80  state->eof = 0; /* not at end of file */
81  state->past = 0; /* have not read past end yet */
82  state->how = LOOK; /* look for gzip header */
83  }
84  state->seek = 0; /* no seek request pending */
85  gz_error(state, Z_OK, NULL); /* clear error */
86  state->x.pos = 0; /* no uncompressed data yet */
87  state->strm.avail_in = 0; /* no input data yet */
88 }
89 
90 /* Open a gzip file either by name or file descriptor. */
92  const void *path;
93  int fd;
94  const char *mode;
95 {
96  gz_statep state;
97  size_t len;
98  int oflag;
99 #ifdef O_CLOEXEC
100  int cloexec = 0;
101 #endif
102 #ifdef O_EXCL
103  int exclusive = 0;
104 #endif
105 
106  /* check input */
107  if (path == NULL)
108  return NULL;
109 
110  /* allocate gzFile structure to return */
111  state = (gz_statep)malloc(sizeof(gz_state));
112  if (state == NULL)
113  return NULL;
114  state->size = 0; /* no buffers allocated yet */
115  state->want = GZBUFSIZE; /* requested buffer size */
116  state->msg = NULL; /* no error message yet */
117 
118  /* interpret mode */
119  state->mode = GZ_NONE;
120  state->level = Z_DEFAULT_COMPRESSION;
121  state->strategy = Z_DEFAULT_STRATEGY;
122  state->direct = 0;
123  while (*mode) {
124  if (*mode >= '0' && *mode <= '9')
125  state->level = *mode - '0';
126  else
127  switch (*mode) {
128  case 'r':
129  state->mode = GZ_READ;
130  break;
131 #ifndef NO_GZCOMPRESS
132  case 'w':
133  state->mode = GZ_WRITE;
134  break;
135  case 'a':
136  state->mode = GZ_APPEND;
137  break;
138 #endif
139  case '+': /* can't read and write at the same time */
140  free(state);
141  return NULL;
142  case 'b': /* ignore -- will request binary anyway */
143  break;
144 #ifdef O_CLOEXEC
145  case 'e':
146  cloexec = 1;
147  break;
148 #endif
149 #ifdef O_EXCL
150  case 'x':
151  exclusive = 1;
152  break;
153 #endif
154  case 'f':
155  state->strategy = Z_FILTERED;
156  break;
157  case 'h':
158  state->strategy = Z_HUFFMAN_ONLY;
159  break;
160  case 'R':
161  state->strategy = Z_RLE;
162  break;
163  case 'F':
164  state->strategy = Z_FIXED;
165  break;
166  case 'T':
167  state->direct = 1;
168  break;
169  default: /* could consider as an error, but just ignore */
170  ;
171  }
172  mode++;
173  }
174 
175  /* must provide an "r", "w", or "a" */
176  if (state->mode == GZ_NONE) {
177  free(state);
178  return NULL;
179  }
180 
181  /* can't force transparent read */
182  if (state->mode == GZ_READ) {
183  if (state->direct) {
184  free(state);
185  return NULL;
186  }
187  state->direct = 1; /* for empty file */
188  }
189 
190  /* save the path name for error messages */
191 #ifdef _WIN32
192  if (fd == -2) {
193  len = wcstombs(NULL, path, 0);
194  if (len == (size_t)-1)
195  len = 0;
196  }
197  else
198 #endif
199  len = strlen((const char *)path);
200  state->path = (char *)malloc(len + 1);
201  if (state->path == NULL) {
202  free(state);
203  return NULL;
204  }
205 #ifdef _WIN32
206  if (fd == -2)
207  if (len)
208  wcstombs(state->path, path, len + 1);
209  else
210  *(state->path) = 0;
211  else
212 #endif
213 #if !defined(NO_snprintf) && !defined(NO_vsnprintf)
214  snprintf(state->path, len + 1, "%s", (const char *)path);
215 #else
216  strcpy(state->path, path);
217 #endif
218 
219  /* compute the flags for open() */
220  oflag =
221 #ifdef O_LARGEFILE
222  O_LARGEFILE |
223 #endif
224 #ifdef O_BINARY
225  O_BINARY |
226 #endif
227 #ifdef O_CLOEXEC
228  (cloexec ? O_CLOEXEC : 0) |
229 #endif
230  (state->mode == GZ_READ ?
231  O_RDONLY :
232  (O_WRONLY | O_CREAT |
233 #ifdef O_EXCL
234  (exclusive ? O_EXCL : 0) |
235 #endif
236  (state->mode == GZ_WRITE ?
237  O_TRUNC :
238  O_APPEND)));
239 
240  /* open the file with the appropriate flags (or just use fd) */
241  state->fd = fd > -1 ? fd : (
242 #ifdef _WIN32
243  fd == -2 ? _wopen(path, oflag, 0666) :
244 #endif
245  open((const char *)path, oflag, 0666));
246  if (state->fd == -1) {
247  free(state->path);
248  free(state);
249  return NULL;
250  }
251  if (state->mode == GZ_APPEND)
252  state->mode = GZ_WRITE; /* simplify later checks */
253 
254  /* save the current position for rewinding (only if reading) */
255  if (state->mode == GZ_READ) {
256  state->start = LSEEK(state->fd, 0, SEEK_CUR);
257  if (state->start == -1) state->start = 0;
258  }
259 
260  /* initialize stream */
261  gz_reset(state);
262 
263  /* return stream */
264  return (gzFile)state;
265 }
266 
267 /* -- see zlib.h -- */
268 gzFile ZEXPORT gzopen(path, mode)
269  const char *path;
270  const char *mode;
271 {
272  return gz_open(path, -1, mode);
273 }
274 
275 /* -- see zlib.h -- */
277  const char *path;
278  const char *mode;
279 {
280  return gz_open(path, -1, mode);
281 }
282 
283 /* -- see zlib.h -- */
285  int fd;
286  const char *mode;
287 {
288  char *path; /* identifier for error messages */
289  gzFile gz;
290 
291  if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL)
292  return NULL;
293 #if !defined(NO_snprintf) && !defined(NO_vsnprintf)
294  snprintf(path, 7 + 3 * sizeof(int), "<fd:%d>", fd); /* for debugging */
295 #else
296  sprintf(path, "<fd:%d>", fd); /* for debugging */
297 #endif
298  gz = gz_open(path, fd, mode);
299  free(path);
300  return gz;
301 }
302 
303 /* -- see zlib.h -- */
304 #ifdef _WIN32
305 gzFile ZEXPORT gzopen_w(path, mode)
306  const wchar_t *path;
307  const char *mode;
308 {
309  return gz_open(path, -2, mode);
310 }
311 #endif
312 
313 /* -- see zlib.h -- */
315  gzFile file;
316  unsigned size;
317 {
318  gz_statep state;
319 
320  /* get internal structure and check integrity */
321  if (file == NULL)
322  return -1;
323  state = (gz_statep)file;
324  if (state->mode != GZ_READ && state->mode != GZ_WRITE)
325  return -1;
326 
327  /* make sure we haven't already allocated memory */
328  if (state->size != 0)
329  return -1;
330 
331  /* check and set requested size */
332  if (size < 2)
333  size = 2; /* need two bytes to check magic header */
334  state->want = size;
335  return 0;
336 }
337 
338 /* -- see zlib.h -- */
339 int ZEXPORT gzrewind(file)
340  gzFile file;
341 {
342  gz_statep state;
343 
344  /* get internal structure */
345  if (file == NULL)
346  return -1;
347  state = (gz_statep)file;
348 
349  /* check that we're reading and that there's no error */
350  if (state->mode != GZ_READ ||
351  (state->err != Z_OK && state->err != Z_BUF_ERROR))
352  return -1;
353 
354  /* back up and start over */
355  if (LSEEK(state->fd, state->start, SEEK_SET) == -1)
356  return -1;
357  gz_reset(state);
358  return 0;
359 }
360 
361 /* -- see zlib.h -- */
363  gzFile file;
365  int whence;
366 {
367  unsigned n;
368  z_off64_t ret;
369  gz_statep state;
370 
371  /* get internal structure and check integrity */
372  if (file == NULL)
373  return -1;
374  state = (gz_statep)file;
375  if (state->mode != GZ_READ && state->mode != GZ_WRITE)
376  return -1;
377 
378  /* check that there's no error */
379  if (state->err != Z_OK && state->err != Z_BUF_ERROR)
380  return -1;
381 
382  /* can only seek from start or relative to current position */
383  if (whence != SEEK_SET && whence != SEEK_CUR)
384  return -1;
385 
386  /* normalize offset to a SEEK_CUR specification */
387  if (whence == SEEK_SET)
388  offset -= state->x.pos;
389  else if (state->seek)
390  offset += state->skip;
391  state->seek = 0;
392 
393  /* if within raw area while reading, just go there */
394  if (state->mode == GZ_READ && state->how == COPY &&
395  state->x.pos + offset >= 0) {
396  ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR);
397  if (ret == -1)
398  return -1;
399  state->x.have = 0;
400  state->eof = 0;
401  state->past = 0;
402  state->seek = 0;
403  gz_error(state, Z_OK, NULL);
404  state->strm.avail_in = 0;
405  state->x.pos += offset;
406  return state->x.pos;
407  }
408 
409  /* calculate skip amount, rewinding if needed for back seek when reading */
410  if (offset < 0) {
411  if (state->mode != GZ_READ) /* writing -- can't go backwards */
412  return -1;
413  offset += state->x.pos;
414  if (offset < 0) /* before start of file! */
415  return -1;
416  if (gzrewind(file) == -1) /* rewind, then skip to offset */
417  return -1;
418  }
419 
420  /* if reading, skip what's in output buffer (one less gzgetc() check) */
421  if (state->mode == GZ_READ) {
422  n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ?
423  (unsigned)offset : state->x.have;
424  state->x.have -= n;
425  state->x.next += n;
426  state->x.pos += n;
427  offset -= n;
428  }
429 
430  /* request skip (if not zero) */
431  if (offset) {
432  state->seek = 1;
433  state->skip = offset;
434  }
435  return state->x.pos + offset;
436 }
437 
438 /* -- see zlib.h -- */
439 z_off_t ZEXPORT gzseek(file, offset, whence)
440  gzFile file;
441  z_off_t offset;
442  int whence;
443 {
444  z_off64_t ret;
445 
446  ret = gzseek64(file, (z_off64_t)offset, whence);
447  return ret == (z_off_t)ret ? (z_off_t)ret : -1;
448 }
449 
450 /* -- see zlib.h -- */
452  gzFile file;
453 {
454  gz_statep state;
455 
456  /* get internal structure and check integrity */
457  if (file == NULL)
458  return -1;
459  state = (gz_statep)file;
460  if (state->mode != GZ_READ && state->mode != GZ_WRITE)
461  return -1;
462 
463  /* return position */
464  return state->x.pos + (state->seek ? state->skip : 0);
465 }
466 
467 /* -- see zlib.h -- */
469  gzFile file;
470 {
471  z_off64_t ret;
472 
473  ret = gztell64(file);
474  return ret == (z_off_t)ret ? (z_off_t)ret : -1;
475 }
476 
477 /* -- see zlib.h -- */
479  gzFile file;
480 {
482  gz_statep state;
483 
484  /* get internal structure and check integrity */
485  if (file == NULL)
486  return -1;
487  state = (gz_statep)file;
488  if (state->mode != GZ_READ && state->mode != GZ_WRITE)
489  return -1;
490 
491  /* compute and return effective offset in file */
492  offset = LSEEK(state->fd, 0, SEEK_CUR);
493  if (offset == -1)
494  return -1;
495  if (state->mode == GZ_READ) /* reading */
496  offset -= state->strm.avail_in; /* don't count buffered input */
497  return offset;
498 }
499 
500 /* -- see zlib.h -- */
502  gzFile file;
503 {
504  z_off64_t ret;
505 
506  ret = gzoffset64(file);
507  return ret == (z_off_t)ret ? (z_off_t)ret : -1;
508 }
509 
510 /* -- see zlib.h -- */
511 int ZEXPORT gzeof(file)
512  gzFile file;
513 {
514  gz_statep state;
515 
516  /* get internal structure and check integrity */
517  if (file == NULL)
518  return 0;
519  state = (gz_statep)file;
520  if (state->mode != GZ_READ && state->mode != GZ_WRITE)
521  return 0;
522 
523  /* return end-of-file state */
524  return state->mode == GZ_READ ? state->past : 0;
525 }
526 
527 /* -- see zlib.h -- */
528 const char * ZEXPORT gzerror(file, errnum)
529  gzFile file;
530  int *errnum;
531 {
532  gz_statep state;
533 
534  /* get internal structure and check integrity */
535  if (file == NULL)
536  return NULL;
537  state = (gz_statep)file;
538  if (state->mode != GZ_READ && state->mode != GZ_WRITE)
539  return NULL;
540 
541  /* return error information */
542  if (errnum != NULL)
543  *errnum = state->err;
544  return state->err == Z_MEM_ERROR ? "out of memory" :
545  (state->msg == NULL ? "" : state->msg);
546 }
547 
548 /* -- see zlib.h -- */
549 void ZEXPORT gzclearerr(file)
550  gzFile file;
551 {
552  gz_statep state;
553 
554  /* get internal structure and check integrity */
555  if (file == NULL)
556  return;
557  state = (gz_statep)file;
558  if (state->mode != GZ_READ && state->mode != GZ_WRITE)
559  return;
560 
561  /* clear error and end-of-file */
562  if (state->mode == GZ_READ) {
563  state->eof = 0;
564  state->past = 0;
565  }
566  gz_error(state, Z_OK, NULL);
567 }
568 
569 /* Create an error message in allocated memory and set state->err and
570  state->msg accordingly. Free any previous error message already there. Do
571  not try to free or allocate space if the error is Z_MEM_ERROR (out of
572  memory). Simply save the error message as a static string. If there is an
573  allocation failure constructing the error message, then convert the error to
574  out of memory. */
575 void ZLIB_INTERNAL gz_error(state, err, msg)
576  gz_statep state;
577  int err;
578  const char *msg;
579 {
580  /* free previously allocated message and clear */
581  if (state->msg != NULL) {
582  if (state->err != Z_MEM_ERROR)
583  free(state->msg);
584  state->msg = NULL;
585  }
586 
587  /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */
588  if (err != Z_OK && err != Z_BUF_ERROR)
589  state->x.have = 0;
590 
591  /* set error code, and if no message, then done */
592  state->err = err;
593  if (msg == NULL)
594  return;
595 
596  /* for an out of memory error, return literal string when requested */
597  if (err == Z_MEM_ERROR)
598  return;
599 
600  /* construct error message with path */
601  if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) ==
602  NULL) {
603  state->err = Z_MEM_ERROR;
604  return;
605  }
606 #if !defined(NO_snprintf) && !defined(NO_vsnprintf)
607  snprintf(state->msg, strlen(state->path) + strlen(msg) + 3,
608  "%s%s%s", state->path, ": ", msg);
609 #else
610  strcpy(state->msg, state->path);
611  strcat(state->msg, ": ");
612  strcat(state->msg, msg);
613 #endif
614  return;
615 }
616 
617 #ifndef INT_MAX
618 /* portably return maximum value for an int (when limits.h presumed not
619  available) -- we need to do this to cover cases where 2's complement not
620  used, since C standard permits 1's complement and sign-bit representations,
621  otherwise we could just use ((unsigned)-1) >> 1 */
623 {
624  unsigned p, q;
625 
626  p = 1;
627  do {
628  q = p;
629  p <<= 1;
630  p++;
631  } while (p > q);
632  return q >> 1;
633 }
634 #endif
GLfloat GLfloat p
#define GZ_NONE
Definition: gzguts.h:150
#define NULL
Definition: ftobjs.h:61
GLdouble GLdouble GLdouble GLdouble q
#define Z_RLE
Definition: zlib.h:194
int ZEXPORT gzeof(gzFile file)
Definition: gzlib.c:511
#define GT_OFF(x)
Definition: gzguts.h:208
z_off64_t ZEXPORT gzoffset64(gzFile file)
Definition: gzlib.c:478
#define GZ_APPEND
Definition: gzguts.h:153
#define GZ_READ
Definition: gzguts.h:151
char * malloc()
local gzFile gz_open(void *path, int fd, const char *mode) const
Definition: gzlib.c:91
#define Z_DEFAULT_COMPRESSION
Definition: zlib.h:148
z_off_t ZEXPORT gztell(gzFile file)
Definition: gzlib.c:468
#define ZLIB_INTERNAL
Definition: compress.c:8
#define ZEXPORT(x)
Definition: zconf.h:202
z_off64_t pos
Definition: zlib.h:1673
#define Z_BUF_ERROR
Definition: zlib.h:139
GLenum GLuint GLenum GLsizei const GLchar * buf
#define SEEK_CUR
Definition: zconf.h:250
int ZEXPORT gzrewind(gzFile file)
Definition: gzlib.c:339
z_off64_t ZEXPORT gztell64(gzFile file)
Definition: gzlib.c:451
#define Z_OK
Definition: zlib.h:132
z_off_t ZEXPORT gzseek(gzFile file, z_off_t offset, int whence)
Definition: gzlib.c:439
#define z_off_t
Definition: zconf.h:254
GLsizei const GLchar ** path
GLenum GLsizei len
GLenum mode
void ZLIB_INTERNAL gz_error(gz_statep state, int err, const char *msg)
Definition: gzlib.c:575
#define Z_MEM_ERROR
Definition: zlib.h:138
#define z_off64_t
Definition: zconf.h:490
FT_Error error
Definition: cffdrivr.c:411
int ZEXPORT gzbuffer(gzFile file, unsigned size)
Definition: gzlib.c:314
#define GZ_WRITE
Definition: gzguts.h:152
#define LSEEK
Definition: gzlib.c:14
GLdouble n
gzFile ZEXPORT gzdopen(int fd, const char *mode)
Definition: gzlib.c:284
#define Z_DEFAULT_STRATEGY
Definition: zlib.h:153
int free()
#define Z_FIXED
Definition: zlib.h:195
GLintptr offset
z_off_t ZEXPORT gzoffset(gzFile file)
Definition: gzlib.c:501
#define Z_FILTERED
Definition: zlib.h:151
#define local
Definition: zutil.h:30
const char *ZEXPORT gzerror(gzFile file, int *errnum)
Definition: gzlib.c:528
#define LOOK
Definition: gzguts.h:156
local void gz_reset(gz_statep state)
Definition: gzlib.c:75
#define GZBUFSIZE
Definition: gzguts.h:147
void ZEXPORT gzclearerr(gzFile file)
Definition: gzlib.c:549
gzFile ZEXPORT gzopen64(char *path, const char *mode) const
Definition: gzlib.c:276
int open(const char *name, int flags, int mode)
Definition: tif_acorn.c:285
#define Z_HUFFMAN_ONLY
Definition: zlib.h:152
gzFile ZEXPORT gzopen(char *path, const char *mode) const
Definition: gzlib.c:268
#define COPY
Definition: gzguts.h:157
gz_state FAR * gz_statep
Definition: gzguts.h:193
unsigned ZLIB_INTERNAL gz_intmax()
Definition: gzlib.c:622
z_off64_t ZEXPORT gzseek64(gzFile file, z_off64_t offset, int whence)
Definition: gzlib.c:362
GLsizeiptr size
#define SEEK_SET
Definition: zconf.h:249
local void gz_reset OF((gz_statep))
png_const_charp msg
Definition: PngFile.c:23