Biomedical Image Analysis Library
The Biomedical Image Analysis Library is a poweful tool for developers, physicians, researchers, engineers, and so on.
gzwrite.c
Go to the documentation of this file.
1 /* gzwrite.c -- zlib functions for writing gzip files
2  * Copyright (C) 2004, 2005, 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 /* Local functions */
10 local int gz_comp OF((gz_statep, int));
12 
13 /* Initialize state for writing a gzip file. Mark initialization by setting
14  state->size to non-zero. Return -1 on failure or 0 on success. */
17 {
18  int ret;
19  z_streamp strm = &(state->strm);
20 
21  /* allocate input buffer */
22  state->in = (unsigned char *)malloc(state->want);
23  if (state->in == NULL) {
24  gz_error(state, Z_MEM_ERROR, "out of memory");
25  return -1;
26  }
27 
28  /* only need output buffer and deflate state if compressing */
29  if (!state->direct) {
30  /* allocate output buffer */
31  state->out = (unsigned char *)malloc(state->want);
32  if (state->out == NULL) {
33  free(state->in);
34  gz_error(state, Z_MEM_ERROR, "out of memory");
35  return -1;
36  }
37 
38  /* allocate deflate memory, set up for gzip compression */
39  strm->zalloc = Z_NULL;
40  strm->zfree = Z_NULL;
41  strm->opaque = Z_NULL;
42  ret = deflateInit2(strm, state->level, Z_DEFLATED,
43  MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy);
44  if (ret != Z_OK) {
45  free(state->out);
46  free(state->in);
47  gz_error(state, Z_MEM_ERROR, "out of memory");
48  return -1;
49  }
50  }
51 
52  /* mark state as initialized */
53  state->size = state->want;
54 
55  /* initialize write buffer if compressing */
56  if (!state->direct) {
57  strm->avail_out = state->size;
58  strm->next_out = state->out;
59  state->x.next = strm->next_out;
60  }
61  return 0;
62 }
63 
64 /* Compress whatever is at avail_in and next_in and write to the output file.
65  Return -1 if there is an error writing to the output file, otherwise 0.
66  flush is assumed to be a valid deflate() flush value. If flush is Z_FINISH,
67  then the deflate() state is reset to start a new gzip stream. If gz->direct
68  is true, then simply write to the output file without compressing, and
69  ignore flush. */
70 local int gz_comp(state, flush)
72  int flush;
73 {
74  int ret, got;
75  unsigned have;
76  z_streamp strm = &(state->strm);
77 
78  /* allocate memory if this is the first time through */
79  if (state->size == 0 && gz_init(state) == -1)
80  return -1;
81 
82  /* write directly if requested */
83  if (state->direct) {
84  got = write(state->fd, strm->next_in, strm->avail_in);
85  if (got < 0 || (unsigned)got != strm->avail_in) {
86  gz_error(state, Z_ERRNO, zstrerror());
87  return -1;
88  }
89  strm->avail_in = 0;
90  return 0;
91  }
92 
93  /* run deflate() on provided input until it produces no more output */
94  ret = Z_OK;
95  do {
96  /* write out current buffer contents if full, or if flushing, but if
97  doing Z_FINISH then don't write until we get to Z_STREAM_END */
98  if (strm->avail_out == 0 || (flush != Z_NO_FLUSH &&
99  (flush != Z_FINISH || ret == Z_STREAM_END))) {
100  have = (unsigned)(strm->next_out - state->x.next);
101  if (have && ((got = write(state->fd, state->x.next, have)) < 0 ||
102  (unsigned)got != have)) {
103  gz_error(state, Z_ERRNO, zstrerror());
104  return -1;
105  }
106  if (strm->avail_out == 0) {
107  strm->avail_out = state->size;
108  strm->next_out = state->out;
109  }
110  state->x.next = strm->next_out;
111  }
112 
113  /* compress */
114  have = strm->avail_out;
115  ret = deflate(strm, flush);
116  if (ret == Z_STREAM_ERROR) {
117  gz_error(state, Z_STREAM_ERROR,
118  "internal error: deflate stream corrupt");
119  return -1;
120  }
121  have -= strm->avail_out;
122  } while (have);
123 
124  /* if that completed a deflate stream, allow another to start */
125  if (flush == Z_FINISH)
126  deflateReset(strm);
127 
128  /* all done, no errors */
129  return 0;
130 }
131 
132 /* Compress len zeros to output. Return -1 on error, 0 on success. */
133 local int gz_zero(state, len)
135  z_off64_t len;
136 {
137  int first;
138  unsigned n;
139  z_streamp strm = &(state->strm);
140 
141  /* consume whatever's left in the input buffer */
142  if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
143  return -1;
144 
145  /* compress len zeros (len guaranteed > 0) */
146  first = 1;
147  while (len) {
148  n = GT_OFF(state->size) || (z_off64_t)state->size > len ?
149  (unsigned)len : state->size;
150  if (first) {
151  memset(state->in, 0, n);
152  first = 0;
153  }
154  strm->avail_in = n;
155  strm->next_in = state->in;
156  state->x.pos += n;
157  if (gz_comp(state, Z_NO_FLUSH) == -1)
158  return -1;
159  len -= n;
160  }
161  return 0;
162 }
163 
164 /* -- see zlib.h -- */
165 int ZEXPORT gzwrite(file, buf, len)
166  gzFile file;
167  voidpc buf;
168  unsigned len;
169 {
170  unsigned put = len;
172  z_streamp strm;
173 
174  /* get internal structure */
175  if (file == NULL)
176  return 0;
177  state = (gz_statep)file;
178  strm = &(state->strm);
179 
180  /* check that we're writing and that there's no error */
181  if (state->mode != GZ_WRITE || state->err != Z_OK)
182  return 0;
183 
184  /* since an int is returned, make sure len fits in one, otherwise return
185  with an error (this avoids the flaw in the interface) */
186  if ((int)len < 0) {
187  gz_error(state, Z_DATA_ERROR, "requested length does not fit in int");
188  return 0;
189  }
190 
191  /* if len is zero, avoid unnecessary operations */
192  if (len == 0)
193  return 0;
194 
195  /* allocate memory if this is the first time through */
196  if (state->size == 0 && gz_init(state) == -1)
197  return 0;
198 
199  /* check for seek request */
200  if (state->seek) {
201  state->seek = 0;
202  if (gz_zero(state, state->skip) == -1)
203  return 0;
204  }
205 
206  /* for small len, copy to input buffer, otherwise compress directly */
207  if (len < state->size) {
208  /* copy to input buffer, compress when full */
209  do {
210  unsigned have, copy;
211 
212  if (strm->avail_in == 0)
213  strm->next_in = state->in;
214  have = (unsigned)((strm->next_in + strm->avail_in) - state->in);
215  copy = state->size - have;
216  if (copy > len)
217  copy = len;
218  memcpy(state->in + have, buf, copy);
219  strm->avail_in += copy;
220  state->x.pos += copy;
221  buf = (const char *)buf + copy;
222  len -= copy;
223  if (len && gz_comp(state, Z_NO_FLUSH) == -1)
224  return 0;
225  } while (len);
226  }
227  else {
228  /* consume whatever's left in the input buffer */
229  if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
230  return 0;
231 
232  /* directly compress user buffer to file */
233  strm->avail_in = len;
234  strm->next_in = (z_const Bytef *)buf;
235  state->x.pos += len;
236  if (gz_comp(state, Z_NO_FLUSH) == -1)
237  return 0;
238  }
239 
240  /* input was all buffered or compressed (put will fit in int) */
241  return (int)put;
242 }
243 
244 /* -- see zlib.h -- */
246  gzFile file;
247  int c;
248 {
249  unsigned have;
250  unsigned char buf[1];
252  z_streamp strm;
253 
254  /* get internal structure */
255  if (file == NULL)
256  return -1;
257  state = (gz_statep)file;
258  strm = &(state->strm);
259 
260  /* check that we're writing and that there's no error */
261  if (state->mode != GZ_WRITE || state->err != Z_OK)
262  return -1;
263 
264  /* check for seek request */
265  if (state->seek) {
266  state->seek = 0;
267  if (gz_zero(state, state->skip) == -1)
268  return -1;
269  }
270 
271  /* try writing to input buffer for speed (state->size == 0 if buffer not
272  initialized) */
273  if (state->size) {
274  if (strm->avail_in == 0)
275  strm->next_in = state->in;
276  have = (unsigned)((strm->next_in + strm->avail_in) - state->in);
277  if (have < state->size) {
278  state->in[have] = c;
279  strm->avail_in++;
280  state->x.pos++;
281  return c & 0xff;
282  }
283  }
284 
285  /* no room in buffer or not initialized, use gz_write() */
286  buf[0] = c;
287  if (gzwrite(file, buf, 1) != 1)
288  return -1;
289  return c & 0xff;
290 }
291 
292 /* -- see zlib.h -- */
293 int ZEXPORT gzputs(file, str)
294  gzFile file;
295  const char *str;
296 {
297  int ret;
298  unsigned len;
299 
300  /* write string */
301  len = (unsigned)strlen(str);
302  ret = gzwrite(file, str, len);
303  return ret == 0 && len != 0 ? -1 : ret;
304 }
305 
306 #if defined(STDC) || defined(Z_HAVE_STDARG_H)
307 #include <stdarg.h>
308 
309 /* -- see zlib.h -- */
310 int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va)
311 {
312  int size, len;
314  z_streamp strm;
315 
316  /* get internal structure */
317  if (file == NULL)
318  return -1;
319  state = (gz_statep)file;
320  strm = &(state->strm);
321 
322  /* check that we're writing and that there's no error */
323  if (state->mode != GZ_WRITE || state->err != Z_OK)
324  return 0;
325 
326  /* make sure we have some buffer space */
327  if (state->size == 0 && gz_init(state) == -1)
328  return 0;
329 
330  /* check for seek request */
331  if (state->seek) {
332  state->seek = 0;
333  if (gz_zero(state, state->skip) == -1)
334  return 0;
335  }
336 
337  /* consume whatever's left in the input buffer */
338  if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
339  return 0;
340 
341  /* do the printf() into the input buffer, put length in len */
342  size = (int)(state->size);
343  state->in[size - 1] = 0;
344 #ifdef NO_vsnprintf
345 # ifdef HAS_vsprintf_void
346  (void)vsprintf((char *)(state->in), format, va);
347  for (len = 0; len < size; len++)
348  if (state->in[len] == 0) break;
349 # else
350  len = vsprintf((char *)(state->in), format, va);
351 # endif
352 #else
353 # ifdef HAS_vsnprintf_void
354  (void)vsnprintf((char *)(state->in), size, format, va);
355  len = strlen((char *)(state->in));
356 # else
357  len = vsnprintf((char *)(state->in), size, format, va);
358 # endif
359 #endif
360 
361  /* check that printf() results fit in buffer */
362  if (len <= 0 || len >= (int)size || state->in[size - 1] != 0)
363  return 0;
364 
365  /* update buffer and position, defer compression until needed */
366  strm->avail_in = (unsigned)len;
367  strm->next_in = state->in;
368  state->x.pos += len;
369  return len;
370 }
371 
372 int ZEXPORTVA gzprintf(gzFile file, const char *format, ...)
373 {
374  va_list va;
375  int ret;
376 
377  va_start(va, format);
378  ret = gzvprintf(file, format, va);
379  va_end(va);
380  return ret;
381 }
382 
383 #else /* !STDC && !Z_HAVE_STDARG_H */
384 
385 /* -- see zlib.h -- */
386 int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
387  a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
388  gzFile file;
389  const char *format;
390  int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
391  a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
392 {
393  int size, len;
395  z_streamp strm;
396 
397  /* get internal structure */
398  if (file == NULL)
399  return -1;
400  state = (gz_statep)file;
401  strm = &(state->strm);
402 
403  /* check that can really pass pointer in ints */
404  if (sizeof(int) != sizeof(void *))
405  return 0;
406 
407  /* check that we're writing and that there's no error */
408  if (state->mode != GZ_WRITE || state->err != Z_OK)
409  return 0;
410 
411  /* make sure we have some buffer space */
412  if (state->size == 0 && gz_init(state) == -1)
413  return 0;
414 
415  /* check for seek request */
416  if (state->seek) {
417  state->seek = 0;
418  if (gz_zero(state, state->skip) == -1)
419  return 0;
420  }
421 
422  /* consume whatever's left in the input buffer */
423  if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
424  return 0;
425 
426  /* do the printf() into the input buffer, put length in len */
427  size = (int)(state->size);
428  state->in[size - 1] = 0;
429 #ifdef NO_snprintf
430 # ifdef HAS_sprintf_void
431  sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8,
432  a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
433  for (len = 0; len < size; len++)
434  if (state->in[len] == 0) break;
435 # else
436  len = sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8,
437  a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
438 # endif
439 #else
440 # ifdef HAS_snprintf_void
441  snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, a7, a8,
442  a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
443  len = strlen((char *)(state->in));
444 # else
445  len = snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6,
446  a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18,
447  a19, a20);
448 # endif
449 #endif
450 
451  /* check that printf() results fit in buffer */
452  if (len <= 0 || len >= (int)size || state->in[size - 1] != 0)
453  return 0;
454 
455  /* update buffer and position, defer compression until needed */
456  strm->avail_in = (unsigned)len;
457  strm->next_in = state->in;
458  state->x.pos += len;
459  return len;
460 }
461 
462 #endif
463 
464 /* -- see zlib.h -- */
465 int ZEXPORT gzflush(file, flush)
466  gzFile file;
467  int flush;
468 {
470 
471  /* get internal structure */
472  if (file == NULL)
473  return -1;
474  state = (gz_statep)file;
475 
476  /* check that we're writing and that there's no error */
477  if (state->mode != GZ_WRITE || state->err != Z_OK)
478  return Z_STREAM_ERROR;
479 
480  /* check flush parameter */
481  if (flush < 0 || flush > Z_FINISH)
482  return Z_STREAM_ERROR;
483 
484  /* check for seek request */
485  if (state->seek) {
486  state->seek = 0;
487  if (gz_zero(state, state->skip) == -1)
488  return -1;
489  }
490 
491  /* compress remaining data with requested flush */
492  gz_comp(state, flush);
493  return state->err;
494 }
495 
496 /* -- see zlib.h -- */
497 int ZEXPORT gzsetparams(file, level, strategy)
498  gzFile file;
499  int level;
500  int strategy;
501 {
503  z_streamp strm;
504 
505  /* get internal structure */
506  if (file == NULL)
507  return Z_STREAM_ERROR;
508  state = (gz_statep)file;
509  strm = &(state->strm);
510 
511  /* check that we're writing and that there's no error */
512  if (state->mode != GZ_WRITE || state->err != Z_OK)
513  return Z_STREAM_ERROR;
514 
515  /* if no change is requested, then do nothing */
516  if (level == state->level && strategy == state->strategy)
517  return Z_OK;
518 
519  /* check for seek request */
520  if (state->seek) {
521  state->seek = 0;
522  if (gz_zero(state, state->skip) == -1)
523  return -1;
524  }
525 
526  /* change compression parameters for subsequent input */
527  if (state->size) {
528  /* flush previous input with previous parameters before changing */
529  if (strm->avail_in && gz_comp(state, Z_PARTIAL_FLUSH) == -1)
530  return state->err;
531  deflateParams(strm, level, strategy);
532  }
533  state->level = level;
534  state->strategy = strategy;
535  return Z_OK;
536 }
537 
538 /* -- see zlib.h -- */
540  gzFile file;
541 {
542  int ret = Z_OK;
544 
545  /* get internal structure */
546  if (file == NULL)
547  return Z_STREAM_ERROR;
548  state = (gz_statep)file;
549 
550  /* check that we're writing */
551  if (state->mode != GZ_WRITE)
552  return Z_STREAM_ERROR;
553 
554  /* check for seek request */
555  if (state->seek) {
556  state->seek = 0;
557  if (gz_zero(state, state->skip) == -1)
558  ret = state->err;
559  }
560 
561  /* flush, free memory, and close file */
562  if (gz_comp(state, Z_FINISH) == -1)
563  ret = state->err;
564  if (state->size) {
565  if (!state->direct) {
566  (void)deflateEnd(&(state->strm));
567  free(state->out);
568  }
569  free(state->in);
570  }
571  gz_error(state, Z_OK, NULL);
572  free(state->path);
573  if (close(state->fd) == -1)
574  ret = Z_ERRNO;
575  free(state);
576  return ret;
577 }
#define OF(args)
Definition: zconf.h:269
void gz_error()
voidpf opaque
Definition: zlib.h:99
int err
Definition: gzguts.h:189
#define deflateInit2(strm, level, method, windowBits, memLevel, strategy)
Definition: zlib.h:1651
int gzflush(gzFile file, int flush)
Definition: gzwrite.c:465
#define Z_NO_FLUSH
Definition: zlib.h:164
int deflateEnd(z_streamp strm)
Definition: deflate.c:979
Definition: blast.c:37
free_func zfree
Definition: zlib.h:98
#define Z_PARTIAL_FLUSH
Definition: zlib.h:165
#define GT_OFF(x)
Definition: gzguts.h:209
int gzputc(gzFile file, int c)
Definition: gzwrite.c:245
#define Z_ERRNO
Definition: zlib.h:176
static int gz_comp()
#define z_off64_t
Definition: zconf.h:490
int mode
Definition: gzguts.h:169
static int gz_zero()
int gzprintf(gzFile file, char *format, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10, int a11, int a12, int a13, int a14, int a15, int a16, int a17, int a18, int a19, int a20)
Definition: gzwrite.c:386
Byte * voidpc
Definition: zconf.h:389
unsigned char * in
Definition: gzguts.h:174
void free()
#define Z_STREAM_ERROR
Definition: zlib.h:177
unsigned have
Definition: zlib.h:1671
alloc_func zalloc
Definition: zlib.h:97
#define z_const
Definition: zconf.h:224
int fd
Definition: gzguts.h:170
static size_t size
Definition: enough.c:173
static int gz_init()
long skip
Definition: gzguts.h:186
z_stream strm
Definition: gzguts.h:192
Bytef * next_in
Definition: zlib.h:86
int level
Definition: gzguts.h:183
#define Z_FINISH
Definition: zlib.h:168
char * path
Definition: gzguts.h:171
int write(ozstream &zs, const T *x, Items items)
Definition: zstream.h:264
int gzsetparams(gzFile file, int level, int strategy)
Definition: gzwrite.c:497
int gzclose_w(gzFile file)
Definition: gzwrite.c:539
#define zstrerror()
Definition: gzguts.h:125
#define Z_DEFLATED
Definition: zlib.h:205
#define Z_DATA_ERROR
Definition: zlib.h:178
#define GZ_WRITE
Definition: gzguts.h:153
int deflateReset(z_streamp strm)
Definition: deflate.c:427
Definition: zlib.h:85
#define Z_STREAM_END
Definition: zlib.h:174
unsigned char * out
Definition: gzguts.h:175
#define local
Definition: adler32.c:10
int gzputs(gzFile file, char *str)
Definition: gzwrite.c:293
#define Z_MEM_ERROR
Definition: zlib.h:179
struct gzFile_s x
Definition: gzguts.h:164
uInt avail_out
Definition: zlib.h:91
#define DEF_MEM_LEVEL
Definition: zip.h:83
Byte Bytef
Definition: zconf.h:377
gz_state * gz_statep
Definition: gzguts.h:194
#define Z_OK
Definition: zlib.h:173
int deflateParams(z_streamp strm, int level, int strategy)
Definition: deflate.c:490
Bytef * next_out
Definition: zlib.h:90
#define Z_NULL
Definition: zlib.h:208
#define const
Definition: zconf.h:217
uInt avail_in
Definition: zlib.h:87
int seek
Definition: gzguts.h:187
int gzwrite(gzFile file, voidpc buf, unsigned len)
Definition: gzwrite.c:165
int direct
Definition: gzguts.h:176
unsigned size
Definition: gzguts.h:172
Definition: gzappend.c:170
#define MAX_WBITS
Definition: zconf.h:247
#define ZEXPORT
Definition: zconf.h:357
long pos
Definition: zlib.h:1673
int deflate(z_streamp strm, int flush)
Definition: deflate.c:665
voidp malloc()
#define ZEXPORTVA
Definition: zconf.h:360
int strategy
Definition: gzguts.h:184