1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2
3 /*
4 * GThumb
5 *
6 * Copyright (C) 2009 The Free Software Foundation, Inc.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include <config.h>
23 #include <string.h>
24 #include <zlib.h>
25 #include "zlib-utils.h"
26
27
28 #define BUFFER_SIZE (16 * 1024)
29
30
31 gboolean
zlib_decompress_buffer(void * zipped_buffer,gsize zipped_size,void ** buffer,gsize * size)32 zlib_decompress_buffer (void *zipped_buffer,
33 gsize zipped_size,
34 void **buffer,
35 gsize *size)
36 {
37 z_stream strm;
38 int ret;
39 guint n;
40 gsize count;
41 guchar *local_buffer = NULL;
42 guchar tmp_buffer[BUFFER_SIZE];
43
44 strm.zalloc = Z_NULL;
45 strm.zfree = Z_NULL;
46 strm.opaque = Z_NULL;
47 strm.avail_in = 0;
48 strm.next_in = Z_NULL;
49 ret = inflateInit2 (&strm, 16+15);
50 if (ret != Z_OK)
51 return FALSE;
52
53 count = 0;
54 strm.avail_in = zipped_size;
55 strm.next_in = zipped_buffer;
56 do {
57 do {
58 strm.avail_out = BUFFER_SIZE;
59 strm.next_out = tmp_buffer;
60 ret = inflate (&strm, Z_NO_FLUSH);
61
62 switch (ret) {
63 case Z_NEED_DICT:
64 case Z_DATA_ERROR:
65 case Z_MEM_ERROR:
66 g_free (local_buffer);
67 inflateEnd (&strm);
68 return FALSE;
69 }
70
71 n = BUFFER_SIZE - strm.avail_out;
72 local_buffer = g_realloc (local_buffer, count + n + 1);
73 memcpy (local_buffer + count, tmp_buffer, n);
74 count += n;
75 }
76 while (strm.avail_out == 0);
77 }
78 while (ret != Z_STREAM_END);
79
80 inflateEnd (&strm);
81
82 *buffer = local_buffer;
83 *size = count;
84
85 return ret == Z_STREAM_END;
86 }
87