4
/*****************************************************************************/
6
/* This file, compress.c, contains the code required to compress and */
7
/* uncompress data using the GZIP_1 compression format. */
9
/* Copyright (C) 2004 Association of Universities for Research in Astronomy */
12
/* Redistribution and use in source and binary forms, with or without */
13
/* modification, are permitted provided that the following conditions are */
16
/* 1. Redistributions of source code must retain the above copyright */
17
/* notice, this list of conditions and the following disclaimer. */
19
/* 2. Redistributions in binary form must reproduce the above */
20
/* copyright notice, this list of conditions and the following */
21
/* disclaimer in the documentation and/or other materials provided */
22
/* with the distribution. */
24
/* 3. The name of AURA and its representatives may not be used to */
25
/* endorse or promote products derived from this software without */
26
/* specific prior written permission. */
28
/* THIS SOFTWARE IS PROVIDED BY AURA ``AS IS'' AND ANY EXPRESS OR IMPLIED */
29
/* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */
30
/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */
31
/* DISCLAIMED. IN NO EVENT SHALL AURA BE LIABLE FOR ANY DIRECT, INDIRECT, */
32
/* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, */
33
/* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS */
34
/* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND */
35
/* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR */
36
/* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE */
37
/* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH */
40
/* This file was copied and heavily modified from the FITSIO software that */
41
/* was written by William Pence at the High Energy Astrophysic Science */
42
/* Archive Research Center (HEASARC) at the NASA Goddard Space Flight Center.*/
43
/* That software contained the following copyright and warranty notices: */
45
/* Copyright (Unpublished--all rights reserved under the copyright laws of */
46
/* the United States), U.S. Government as represented by the Administrator */
47
/* of the National Aeronautics and Space Administration. No copyright is */
48
/* claimed in the United States under Title 17, U.S. Code. */
50
/* Permission to freely use, copy, modify, and distribute this software */
51
/* and its documentation without fee is hereby granted, provided that this */
52
/* copyright notice and disclaimer of warranty appears in all copies. */
56
/* THE SOFTWARE IS PROVIDED 'AS IS' WITHOUT ANY WARRANTY OF ANY KIND, */
57
/* EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, */
58
/* ANY WARRANTY THAT THE SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY */
59
/* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR */
60
/* PURPOSE, AND FREEDOM FROM INFRINGEMENT, AND ANY WARRANTY THAT THE */
61
/* DOCUMENTATION WILL CONFORM TO THE SOFTWARE, OR ANY WARRANTY THAT THE */
62
/* SOFTWARE WILL BE ERROR FREE. IN NO EVENT SHALL NASA BE LIABLE FOR ANY */
63
/* DAMAGES, INCLUDING, BUT NOT LIMITED TO, DIRECT, INDIRECT, SPECIAL OR */
64
/* CONSEQUENTIAL DAMAGES, ARISING OUT OF, RESULTING FROM, OR IN ANY WAY */
65
/* CONNECTED WITH THIS SOFTWARE, WHETHER OR NOT BASED UPON WARRANTY, */
66
/* CONTRACT, TORT , OR OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY */
67
/* PERSONS OR PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED */
68
/* FROM, OR AROSE OUT OF THE RESULTS OF, OR USE OF, THE SOFTWARE OR */
69
/* SERVICES PROVIDED HEREUNDER." */
71
/* This code calls routines from and links to the ZLIB compression library */
72
/* that was written by Jean-loup Gailly and Mark Adler. This package is */
73
/* normally destributed with Python 2.5. That software containes the */
74
/* following copyright and warranty notices: */
76
/* Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler */
78
/* This software is provided 'as-is', without any express or implied */
79
/* warranty. In no event will the authors be held liable for any damages */
80
/* arising from the use of this software. */
82
/* Permission is granted to anyone to use this software for any purpose, */
83
/* including commercial applications, and to alter it and redistribute it */
84
/* freely, subject to the following restrictions: */
86
/* 1. The origin of this software must not be misrepresented; you must not */
87
/* claim that you wrote the original software. If you use this software */
88
/* in a product, an acknowledgment in the product documentation would be */
89
/* appreciated but is not required. */
90
/* 2. Altered source versions must be plainly marked as such, and must not */
91
/* be misrepresented as being the original software. */
92
/* 3. This notice may not be removed or altered from any source */
95
/* Jean-loup Gailly Mark Adler */
96
/* jloup@gzip.org madler@alumni.caltech.edu */
99
/* The data format used by the zlib library is described by RFCs (Request */
100
/* for Comments) 1950 to 1952 in the files */
101
/* http://www.ietf.org/rfc/rfc1950.txt (zlib format), */
102
/* rfc1951.txt (deflate format) and rfc1952.txt (gzip format). */
104
/*****************************************************************************/
111
int _pyfits_uncompress2mem_from_mem(
116
void *(*mem_realloc)(void *p, size_t newsize),
120
int _pyfits_compress2mem_from_mem(
125
void *(*mem_realloc)(void *p, size_t newsize),
129
/*--------------------------------------------------------------------------*/
130
int _pyfits_uncompress2mem_from_mem(
131
char *inmemptr, /* I - memory pointer to compressed bytes */
132
size_t inmemsize, /* I - size of input compressed file */
133
char **buffptr, /* IO - memory pointer */
134
size_t *buffsize, /* IO - size of buffer, in bytes */
135
void *(*mem_realloc)(void *p, size_t newsize), /* function */
136
size_t *filesize, /* O - size of file, in bytes */
137
int *status) /* IO - error status */
140
Uncompress the file into memory. Fill whatever amount of memory has
141
already been allocated, then realloc more memory, using the supplied
142
input function, if necessary.
148
z_stream d_stream; /* decompression stream */
149
uLong bytes_out_so_far = 0; /* Keeps track of the number of bytes put in
150
the output buffer so far */
156
/* Allocate memory as a temporary buffer in which to uncompress. */
157
uncomprLen = *buffsize;
158
uncompr = (Byte*)malloc(*buffsize);
160
d_stream.zalloc = (alloc_func)0;
161
d_stream.zfree = (free_func)0;
162
d_stream.opaque = (voidpf)0;
164
d_stream.next_in = (unsigned char*)inmemptr;
165
d_stream.avail_in = inmemsize;
167
/* Initialize the decompression. The argument (15+16) tells the
168
decompressor that we are to use the gzip algorithm */
169
err = inflateInit2(&d_stream, (15+16));
173
/* free temporary output data buffer */
175
return(*status = 414);
180
/* Output to the temporary buffer. This will overwrite the
181
previous data each time. */
182
d_stream.next_out = uncompr;
183
d_stream.avail_out = uncomprLen;
185
err = inflate(&d_stream, Z_NO_FLUSH);
187
if (err != Z_OK && err != Z_STREAM_END)
189
/* free temporary output data buffer */
191
return(*status = 414);
194
if (d_stream.total_out > *buffsize)
196
/* OK, we need more memory for the output so reallocate it */
197
*buffsize = d_stream.total_out;
198
*buffptr = mem_realloc(*buffptr,*buffsize);
200
if (*buffptr == NULL)
202
/* free temporary output data buffer */
204
return(*status = 414);
208
/* copy from the temporary buffer into the output memory buffer */
209
memcpy((char *) *buffptr + bytes_out_so_far, (char *) uncompr,
210
d_stream.total_out-bytes_out_so_far);
211
bytes_out_so_far = d_stream.total_out;
213
if (err == Z_STREAM_END) break; /* We reached the end of the input */
216
/* Set the output file size to be the total output data */
217
*filesize = d_stream.total_out;
219
/* End the decompression */
220
err = inflateEnd(&d_stream);
222
/* free temporary output data buffer */
227
return(*status = 414);
232
/*--------------------------------------------------------------------------*/
233
int _pyfits_compress2mem_from_mem(
234
char *inmemptr, /* I - memory pointer to uncompressed bytes */
235
size_t inmemsize, /* I - size of input uncompressed file */
236
char **buffptr, /* IO - memory pointer for compressed file */
237
size_t *buffsize, /* IO - size of buffer, in bytes */
238
void *(*mem_realloc)(void *p, size_t newsize), /* function */
239
size_t *filesize, /* O - size of file, in bytes */
240
int *status) /* IO - error status */
243
Compress the file into memory. Fill whatever amount of memory has
244
already been allocated, then realloc more memory, using the supplied
245
input function, if necessary.
252
z_stream c_stream; /* compression stream */
254
uLong bytes_out_so_far = 0; /* Keeps track of the number of bytes put in
255
the output buffer so far */
260
/* Allocate memory as a temporary buffer in which to compress. */
261
comprLen = *buffsize;
262
compr = (Byte*)malloc(*buffsize);
264
c_stream.zalloc = (alloc_func)0;
265
c_stream.zfree = (free_func)0;
266
c_stream.opaque = (voidpf)0;
268
/* Initialize the compression. The argument (15+16) tells the
269
compressor that we are to use the gzip algorythm */
270
err = deflateInit2(&c_stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED,
271
(15+16), 8, Z_DEFAULT_STRATEGY);
275
return(*status = 413);
278
c_stream.next_in = (unsigned char*)inmemptr;
279
c_stream.avail_in = inmemsize;
283
/* Output to the temporary buffer. This will overwrite the
284
previous data each time. */
285
c_stream.next_out = compr;
286
c_stream.avail_out = comprLen;
288
err = deflate(&c_stream, Z_FINISH);
290
if (err != Z_OK && err != Z_STREAM_END)
292
/* free temporary output data buffer */
294
return(*status = 413);
297
if (c_stream.total_out > *buffsize)
299
/* OK, we need more memory for the output so reallocate it */
300
*buffsize = c_stream.total_out;
301
*buffptr = mem_realloc(*buffptr,*buffsize);
303
if (*buffptr == NULL)
305
/* free temporary output data buffer */
307
return(*status = 413);
311
/* copy from the temporary buffer into the output memory buffer */
312
memcpy((char *) *buffptr + bytes_out_so_far, (char *) compr,
313
c_stream.total_out-bytes_out_so_far);
314
bytes_out_so_far = c_stream.total_out;
316
if (err == Z_STREAM_END) break; /* We reached the end of the input */
319
/* Set the output file size to be the total output data */
320
*filesize = c_stream.total_out;
322
/* End the compression */
323
err = deflateEnd(&c_stream);
325
/* free temporary output data buffer */
330
return(*status = 413);