#include #include #include #include #include "zlib.h" unsigned int GZBUFSIZE = 115200; /* 40 FITS blocks */ int BUFFINCR = 28800; /* 10 FITS blocks */ /* prototype for the following functions */ int uncompress2mem(char *filename, FILE *diskfile, char **buffptr, size_t *buffsize, void *(*mem_realloc)(void *p, size_t newsize), size_t *filesize, int *status); int uncompress2mem_from_mem( char *inmemptr, size_t inmemsize, char **buffptr, size_t *buffsize, void *(*mem_realloc)(void *p, size_t newsize), size_t *filesize, int *status); int uncompress2file(char *filename, FILE *indiskfile, FILE *outdiskfile, int *status); int compress2mem_from_mem( char *inmemptr, size_t inmemsize, char **buffptr, size_t *buffsize, void *(*mem_realloc)(void *p, size_t newsize), size_t *filesize, int *status); int compress2file_from_mem( char *inmemptr, size_t inmemsize, FILE *outdiskfile, size_t *filesize, /* O - size of file, in bytes */ int *status); /*--------------------------------------------------------------------------*/ int uncompress2mem(char *filename, /* name of input file */ FILE *diskfile, /* I - file pointer */ char **buffptr, /* IO - memory pointer */ size_t *buffsize, /* IO - size of buffer, in bytes */ void *(*mem_realloc)(void *p, size_t newsize), /* function */ size_t *filesize, /* O - size of file, in bytes */ int *status) /* IO - error status */ /* Uncompress the disk file into memory. Fill whatever amount of memory has already been allocated, then realloc more memory, using the supplied input function, if necessary. */ { int err, len; char *filebuff; z_stream d_stream; /* decompression stream */ if (*status > 0) return(*status); /* Allocate memory to hold compressed bytes read from the file. */ filebuff = (char*)malloc(GZBUFSIZE); if (!filebuff) return(*status = 113); /* memory error */ d_stream.zalloc = (alloc_func)0; d_stream.zfree = (free_func)0; d_stream.opaque = (voidpf)0; d_stream.next_out = (unsigned char*) *buffptr; d_stream.avail_out = *buffsize; /* Initialize the decompression. The argument (15+16) tells the decompressor that we are to use the gzip algorithm */ err = inflateInit2(&d_stream, (15+16)); if (err != Z_OK) return(*status = 414); /* loop through the file, reading a buffer and uncompressing it */ for (;;) { len = fread(filebuff, 1, GZBUFSIZE, diskfile); if (ferror(diskfile)) { inflateEnd(&d_stream); free(filebuff); return(*status = 414); } if (len == 0) break; /* no more data */ d_stream.next_in = (unsigned char*)filebuff; d_stream.avail_in = len; for (;;) { /* uncompress as much of the input as will fit in the output */ err = inflate(&d_stream, Z_NO_FLUSH); if (err == Z_STREAM_END ) { /* We reached the end of the input */ break; } else if (err == Z_OK ) { if (!d_stream.avail_in) break; /* need more input */ /* need more space in output buffer */ if (mem_realloc) { *buffptr = mem_realloc(*buffptr,*buffsize + BUFFINCR); if (*buffptr == NULL){ inflateEnd(&d_stream); free(filebuff); return(*status = 414); /* memory allocation failed */ } d_stream.avail_out = BUFFINCR; d_stream.next_out = (unsigned char*) (*buffptr + *buffsize); *buffsize = *buffsize + BUFFINCR; } else { /* error: no realloc function available */ inflateEnd(&d_stream); free(filebuff); return(*status = 414); } } else { /* some other error */ inflateEnd(&d_stream); free(filebuff); return(*status = 414); } } if (feof(diskfile)) break; d_stream.next_out = (unsigned char*) (*buffptr + d_stream.total_out); d_stream.avail_out = *buffsize - d_stream.total_out; } /* Set the output file size to be the total output data */ *filesize = d_stream.total_out; free(filebuff); /* free temporary output data buffer */ err = inflateEnd(&d_stream); /* End the decompression */ if (err != Z_OK) return(*status = 414); return(*status); } /*--------------------------------------------------------------------------*/ int uncompress2mem_from_mem( char *inmemptr, /* I - memory pointer to compressed bytes */ size_t inmemsize, /* I - size of input compressed file */ char **buffptr, /* IO - memory pointer */ size_t *buffsize, /* IO - size of buffer, in bytes */ void *(*mem_realloc)(void *p, size_t newsize), /* function */ size_t *filesize, /* O - size of file, in bytes */ int *status) /* IO - error status */ /* Uncompress the file in memory into memory. Fill whatever amount of memory has already been allocated, then realloc more memory, using the supplied input function, if necessary. */ { int err; z_stream d_stream; /* decompression stream */ if (*status > 0) return(*status); d_stream.zalloc = (alloc_func)0; d_stream.zfree = (free_func)0; d_stream.opaque = (voidpf)0; /* Initialize the decompression. The argument (15+16) tells the decompressor that we are to use the gzip algorithm */ err = inflateInit2(&d_stream, (15+16)); if (err != Z_OK) return(*status = 414); d_stream.next_in = (unsigned char*)inmemptr; d_stream.avail_in = inmemsize; d_stream.next_out = (unsigned char*) *buffptr; d_stream.avail_out = *buffsize; for (;;) { /* uncompress as much of the input as will fit in the output */ err = inflate(&d_stream, Z_NO_FLUSH); if (err == Z_STREAM_END) { /* We reached the end of the input */ break; } else if (err == Z_OK ) { /* need more space in output buffer */ if (mem_realloc) { *buffptr = mem_realloc(*buffptr,*buffsize + BUFFINCR); if (*buffptr == NULL){ inflateEnd(&d_stream); return(*status = 414); /* memory allocation failed */ } d_stream.avail_out = BUFFINCR; d_stream.next_out = (unsigned char*) (*buffptr + *buffsize); *buffsize = *buffsize + BUFFINCR; } else { /* error: no realloc function available */ inflateEnd(&d_stream); return(*status = 414); } } else { /* some other error */ inflateEnd(&d_stream); return(*status = 414); } } /* Set the output file size to be the total output data */ if (filesize) *filesize = d_stream.total_out; /* End the decompression */ err = inflateEnd(&d_stream); if (err != Z_OK) return(*status = 414); return(*status); } /*--------------------------------------------------------------------------*/ int uncompress2file(char *filename, /* name of input file */ FILE *indiskfile, /* I - input file pointer */ FILE *outdiskfile, /* I - output file pointer */ int *status) /* IO - error status */ /* Uncompress the file into another file. */ { int err, len; unsigned long bytes_out = 0; char *infilebuff, *outfilebuff; z_stream d_stream; /* decompression stream */ if (*status > 0) return(*status); /* Allocate buffers to hold compressed and uncompressed */ infilebuff = (char*)malloc(GZBUFSIZE); if (!infilebuff) return(*status = 113); /* memory error */ outfilebuff = (char*)malloc(GZBUFSIZE); if (!outfilebuff) return(*status = 113); /* memory error */ d_stream.zalloc = (alloc_func)0; d_stream.zfree = (free_func)0; d_stream.opaque = (voidpf)0; d_stream.next_out = (unsigned char*) outfilebuff; d_stream.avail_out = GZBUFSIZE; /* Initialize the decompression. The argument (15+16) tells the decompressor that we are to use the gzip algorithm */ err = inflateInit2(&d_stream, (15+16)); if (err != Z_OK) return(*status = 414); /* loop through the file, reading a buffer and uncompressing it */ for (;;) { len = fread(infilebuff, 1, GZBUFSIZE, indiskfile); if (ferror(indiskfile)) { inflateEnd(&d_stream); free(infilebuff); free(outfilebuff); return(*status = 414); } if (len == 0) break; /* no more data */ d_stream.next_in = (unsigned char*)infilebuff; d_stream.avail_in = len; for (;;) { /* uncompress as much of the input as will fit in the output */ err = inflate(&d_stream, Z_NO_FLUSH); if (err == Z_STREAM_END ) { /* We reached the end of the input */ break; } else if (err == Z_OK ) { if (!d_stream.avail_in) break; /* need more input */ /* flush out the full output buffer */ if ((int)fwrite(outfilebuff, 1, GZBUFSIZE, outdiskfile) != GZBUFSIZE) { inflateEnd(&d_stream); free(infilebuff); free(outfilebuff); return(*status = 414); } bytes_out += GZBUFSIZE; d_stream.next_out = (unsigned char*) outfilebuff; d_stream.avail_out = GZBUFSIZE; } else { /* some other error */ inflateEnd(&d_stream); free(infilebuff); free(outfilebuff); return(*status = 414); } } if (feof(indiskfile)) break; } /* write out any remaining bytes in the buffer */ if (d_stream.total_out > bytes_out) { if ((int)fwrite(outfilebuff, 1, (d_stream.total_out - bytes_out), outdiskfile) != (d_stream.total_out - bytes_out)) { inflateEnd(&d_stream); free(infilebuff); free(outfilebuff); return(*status = 414); } } free(infilebuff); /* free temporary output data buffer */ free(outfilebuff); /* free temporary output data buffer */ err = inflateEnd(&d_stream); /* End the decompression */ if (err != Z_OK) return(*status = 414); return(*status); } /*--------------------------------------------------------------------------*/ int compress2mem_from_mem( char *inmemptr, /* I - memory pointer to uncompressed bytes */ size_t inmemsize, /* I - size of input uncompressed file */ char **buffptr, /* IO - memory pointer for compressed file */ size_t *buffsize, /* IO - size of buffer, in bytes */ void *(*mem_realloc)(void *p, size_t newsize), /* function */ size_t *filesize, /* O - size of file, in bytes */ int *status) /* IO - error status */ /* Compress the file into memory. Fill whatever amount of memory has already been allocated, then realloc more memory, using the supplied input function, if necessary. */ { int err; z_stream c_stream; /* compression stream */ if (*status > 0) return(*status); c_stream.zalloc = (alloc_func)0; c_stream.zfree = (free_func)0; c_stream.opaque = (voidpf)0; /* Initialize the compression. The argument (15+16) tells the compressor that we are to use the gzip algorythm. Also use Z_BEST_SPEED for maximum speed with very minor loss in compression factor. */ err = deflateInit2(&c_stream, Z_BEST_SPEED, Z_DEFLATED, (15+16), 8, Z_DEFAULT_STRATEGY); if (err != Z_OK) return(*status = 413); c_stream.next_in = (unsigned char*)inmemptr; c_stream.avail_in = inmemsize; c_stream.next_out = (unsigned char*) *buffptr; c_stream.avail_out = *buffsize; for (;;) { /* compress as much of the input as will fit in the output */ err = deflate(&c_stream, Z_FINISH); if (err == Z_STREAM_END) { /* We reached the end of the input */ break; } else if (err == Z_OK ) { /* need more space in output buffer */ if (mem_realloc) { *buffptr = mem_realloc(*buffptr,*buffsize + BUFFINCR); if (*buffptr == NULL){ deflateEnd(&c_stream); return(*status = 413); /* memory allocation failed */ } c_stream.avail_out = BUFFINCR; c_stream.next_out = (unsigned char*) (*buffptr + *buffsize); *buffsize = *buffsize + BUFFINCR; } else { /* error: no realloc function available */ deflateEnd(&c_stream); return(*status = 413); } } else { /* some other error */ deflateEnd(&c_stream); return(*status = 413); } } /* Set the output file size to be the total output data */ if (filesize) *filesize = c_stream.total_out; /* End the compression */ err = deflateEnd(&c_stream); if (err != Z_OK) return(*status = 413); return(*status); } /*--------------------------------------------------------------------------*/ int compress2file_from_mem( char *inmemptr, /* I - memory pointer to uncompressed bytes */ size_t inmemsize, /* I - size of input uncompressed file */ FILE *outdiskfile, size_t *filesize, /* O - size of file, in bytes */ int *status) /* Compress the memory file into disk file. */ { int err; unsigned long bytes_out = 0; char *outfilebuff; z_stream c_stream; /* compression stream */ if (*status > 0) return(*status); /* Allocate buffer to hold compressed bytes */ outfilebuff = (char*)malloc(GZBUFSIZE); if (!outfilebuff) return(*status = 113); /* memory error */ c_stream.zalloc = (alloc_func)0; c_stream.zfree = (free_func)0; c_stream.opaque = (voidpf)0; /* Initialize the compression. The argument (15+16) tells the compressor that we are to use the gzip algorythm. Also use Z_BEST_SPEED for maximum speed with very minor loss in compression factor. */ err = deflateInit2(&c_stream, Z_BEST_SPEED, Z_DEFLATED, (15+16), 8, Z_DEFAULT_STRATEGY); if (err != Z_OK) return(*status = 413); c_stream.next_in = (unsigned char*)inmemptr; c_stream.avail_in = inmemsize; c_stream.next_out = (unsigned char*) outfilebuff; c_stream.avail_out = GZBUFSIZE; for (;;) { /* compress as much of the input as will fit in the output */ err = deflate(&c_stream, Z_FINISH); if (err == Z_STREAM_END) { /* We reached the end of the input */ break; } else if (err == Z_OK ) { /* need more space in output buffer */ /* flush out the full output buffer */ if ((int)fwrite(outfilebuff, 1, GZBUFSIZE, outdiskfile) != GZBUFSIZE) { deflateEnd(&c_stream); free(outfilebuff); return(*status = 413); } bytes_out += GZBUFSIZE; c_stream.next_out = (unsigned char*) outfilebuff; c_stream.avail_out = GZBUFSIZE; } else { /* some other error */ deflateEnd(&c_stream); free(outfilebuff); return(*status = 413); } } /* write out any remaining bytes in the buffer */ if (c_stream.total_out > bytes_out) { if ((int)fwrite(outfilebuff, 1, (c_stream.total_out - bytes_out), outdiskfile) != (c_stream.total_out - bytes_out)) { deflateEnd(&c_stream); free(outfilebuff); return(*status = 413); } } free(outfilebuff); /* free temporary output data buffer */ /* Set the output file size to be the total output data */ if (filesize) *filesize = c_stream.total_out; /* End the compression */ err = deflateEnd(&c_stream); if (err != Z_OK) return(*status = 413); return(*status); }