mirror of
https://bitbucket.org/cosmicvoids/vide_public.git
synced 2025-07-04 15:21:11 +00:00
504 lines
17 KiB
C
504 lines
17 KiB
C
#include <stdio.h>
|
|
#include <errno.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#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);
|
|
}
|