home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Elite Hackers Toolkit
/
TheEliteHackersToolkitVolume1_1998.rar
/
HACKERS.BIN
/
hackers
/
snow_tar.gz
/
snow.tar
/
snow
/
compress.c
next >
Wrap
C/C++ Source or Header
|
1996-12-28
|
4KB
|
272 lines
/*
* Compression routines for the SNOW steganography program.
* Uses simple Huffman coding.
*
* Written by Matthew Kwan - December 1996
*/
#include "snow.h"
/*
* The Huffman codes.
*/
static const char *huffcodes[256] = {
#include "huffcode.h"
};
/*
* Local variables used for compression.
*/
static int compress_bit_count;
static int compress_value;
static int compress_bits_in;
static int compress_bits_out;
/*
* Initialize the compression routines.
*/
void
compress_init (void)
{
compress_bit_count = 0;
compress_value = 0;
compress_bits_in = 0;
compress_bits_out = 0;
encrypt_init ();
}
/*
* Compress a single bit.
*/
BOOL
compress_bit (
int bit,
FILE *inf,
FILE *outf
) {
if (!compress_flag)
return (encrypt_bit (bit, inf, outf));
compress_bits_in++;
compress_value = (compress_value << 1) | bit;
if (++compress_bit_count == 8) {
const char *s;
for (s = huffcodes[compress_value]; *s != '\0'; s++) {
int bit;
if (*s == '1')
bit = 1;
else if (*s == '0')
bit = 0;
else {
fprintf (stderr, "Illegal Huffman character '%c'\n", *s);
return (FALSE);
}
if (!encrypt_bit (bit, inf, outf))
return (FALSE);
compress_bits_out++;
}
compress_value = 0;
compress_bit_count = 0;
}
return (TRUE);
}
/*
* Flush the contents of the compression routines.
*/
BOOL
compress_flush (
FILE *inf,
FILE *outf
) {
if (compress_bit_count != 0 && !quiet_flag)
fprintf (stderr, "Warning: residual of %d bits not compressed\n",
compress_bit_count);
if (compress_bits_out > 0 && !quiet_flag) {
double cpc = (double) (compress_bits_in - compress_bits_out)
/ (double) compress_bits_in * 100.0;
if (cpc < 0.0)
fprintf (stderr,
"Compression enlarged data by %.2f%% - recommend not using compression\n",
-cpc);
else
fprintf (stderr, "Compressed by %.2f%%\n", cpc);
}
return (encrypt_flush (inf, outf));
}
/*
* Local variables used for output.
*/
static int output_bit_count;
static int output_value;
/*
* Initialize the output variables.
*/
static void
output_init (void)
{
output_bit_count = 0;
output_value = 0;
}
/*
* Output a single bit.
*/
static BOOL
output_bit (
int bit,
FILE *outf
) {
output_value = (output_value << 1) | bit;
if (++output_bit_count == 8) {
if (fputc (output_value, outf) == EOF) {
perror ("Output file");
return (FALSE);
}
output_value = 0;
output_bit_count = 0;
}
return (TRUE);
}
/*
* Flush the contents of the output routines.
*/
static BOOL
output_flush (
FILE *outf
) {
if (output_bit_count > 2 && !quiet_flag)
fprintf (stderr, "Warning: residual of %d bits not output\n",
output_bit_count);
return (TRUE);
}
/*
* Local variables used for uncompression.
*/
static int uncompress_bit_count;
static char uncompress_value[256];
/*
* Initialize the uncompression routines.
*/
void
uncompress_init (void)
{
uncompress_bit_count = 0;
output_init ();
}
/*
* Find the Huffman code string that matches.
*/
static int
huffcode_find (
const char *str
) {
int i;
for (i=0; i<256; i++)
if (strcmp (str, huffcodes[i]) == 0)
return (i);
return (-1);
}
/*
* Uncompress a single bit.
*/
BOOL
uncompress_bit (
int bit,
FILE *outf
) {
int code;
if (!compress_flag)
return (output_bit (bit, outf));
uncompress_value[uncompress_bit_count++] = bit ? '1' : '0';
uncompress_value[uncompress_bit_count] = '\0';
if ((code = huffcode_find (uncompress_value)) >= 0) {
int i;
for (i=0; i<8; i++) {
int b = ((code & (128 >> i)) != 0) ? 1 : 0;
if (!output_bit (b, outf))
return (FALSE);
}
uncompress_bit_count = 0;
}
if (uncompress_bit_count >= 255) {
fprintf (stderr, "Error: Huffman uncompress buffer overflow\n");
return (FALSE);
}
return (TRUE);
}
/*
* Flush the contents of the uncompression routines.
*/
BOOL
uncompress_flush (
FILE *outf
) {
if (uncompress_bit_count > 2 && !quiet_flag)
fprintf (stderr, "Warning: residual of %d bits not uncompressed\n",
uncompress_bit_count);
return (output_flush (outf));
}