This is lzwenc.c in view mode; [Download] [Up]
/*
* LZWEncodeImage() - description
*
* RCS:
* $Revision: 2.3 $
* $Date: 1996/05/03 02:21:34 $
*
* Security:
* Unclassified
*
* Description:
* Taken from ImageMagick 3.3
*
* Input Parameters:
* type identifier description
*
* text
*
* Output Parameters:
* type identifier description
*
* text
*
* Return Values:
* value description
*
* Side Effects:
* text
*
* Limitations and Comments:
* text
*
* Development History:
* when who why
*/
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% L Z W E n c o d e I m a g e %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Function LZWEncodeImage compresses an image via LZW-coding.
%
% The format of the LZWEncodeImage routine is:
%
% status=LZWEncodeImage(image,data_size)
%
% A description of each parameter follows:
%
% o status: Function LZWEncodeImage returns True if all the pixels are
% compressed without error, otherwise False.
%
% o image: The address of a structure of type Image.
%
%
*/
#include "combine.h"
#include "defines.h"
unsigned int LZWEncodeImage(image,data_size)
Image
*image;
unsigned int
data_size;
{
#define MaxCode(number_bits) ((1 << (number_bits))-1)
#define MaxHashTable 5003
#define MaxLZWBits 12
#define MaxLZWTable (1 << MaxLZWBits)
#define LZWOutputCode(code) \
{ \
/* \
Emit a code. \
*/ \
if (bits > 0) \
datum|=((long) code << bits); \
else \
datum=(long) code; \
bits+=number_bits; \
while (bits >= 8) \
{ \
/* \
Add a character to current packet. \
*/ \
packet[byte_count++]=(unsigned char) (datum & 0xff); \
if (byte_count >= 254) \
{ \
(void) fputc(byte_count,image->fp); \
(void) fwrite((char *) packet,1,byte_count,image->fp); \
byte_count=0; \
} \
datum>>=8; \
bits-=8; \
} \
if (free_code > max_code) \
{ \
number_bits++; \
if (number_bits == MaxLZWBits) \
max_code=MaxLZWTable; \
else \
max_code=MaxCode(number_bits); \
} \
}
int
bits,
byte_count,
next_pixel,
number_bits;
long
datum;
register int
displacement,
i,
j;
register Runlength
*p;
short
clear_code,
end_of_information_code,
free_code,
*hash_code,
*hash_prefix,
index,
max_code,
waiting_code;
unsigned char
*packet,
*hash_suffix;
/*
Uncompress image.
*/
if (!UncompressImage(image))
return(False);
/*
Allocate encoder tables.
*/
packet=(unsigned char *) malloc(256*sizeof(unsigned char));
hash_code=(short *) malloc(MaxHashTable*sizeof(short));
hash_prefix=(short *) malloc(MaxHashTable*sizeof(short));
hash_suffix=(unsigned char *) malloc(MaxHashTable*sizeof(unsigned char));
if ((packet == (unsigned char *) NULL) || (hash_code == (short *) NULL) ||
(hash_prefix == (short *) NULL) ||
(hash_suffix == (unsigned char *) NULL))
return(False);
/*
Initialize LZW encoder.
*/
number_bits=data_size;
max_code=MaxCode(number_bits);
clear_code=((short) 1 << (data_size-1));
end_of_information_code=clear_code+1;
free_code=clear_code+2;
byte_count=0;
datum=0;
bits=0;
for (i=0; i < MaxHashTable; i++)
hash_code[i]=0;
LZWOutputCode(clear_code);
/*
Encode pixels.
*/
p=image->pixels;
waiting_code=p->index;
for (i=1; i < (image->columns*image->rows); i++)
{
/*
Probe hash table.
*/
p++;
index=p->index & 0xff;
j=(int) ((int) index << (MaxLZWBits-8))+waiting_code;
if (j >= MaxHashTable)
j-=MaxHashTable;
if (hash_code[j] > 0)
{
if ((hash_prefix[j] == waiting_code) && (hash_suffix[j] == index))
{
waiting_code=hash_code[j];
continue;
}
if (j == 0)
displacement=1;
else
displacement=MaxHashTable-j;
next_pixel=False;
for ( ; ; )
{
j-=displacement;
if (j < 0)
j+=MaxHashTable;
if (hash_code[j] == 0)
break;
if ((hash_prefix[j] == waiting_code) && (hash_suffix[j] == index))
{
waiting_code=hash_code[j];
next_pixel=True;
break;
}
}
if (next_pixel == True)
continue;
}
LZWOutputCode(waiting_code);
if (free_code < MaxLZWTable)
{
hash_code[j]=free_code++;
hash_prefix[j]=waiting_code;
hash_suffix[j]=index;
}
else
{
/*
Fill the hash table with empty entries.
*/
for (j=0; j < MaxHashTable; j++)
hash_code[j]=0;
/*
Reset compressor and issue a clear code.
*/
free_code=clear_code+2;
LZWOutputCode(clear_code);
number_bits=data_size;
max_code=MaxCode(number_bits);
}
waiting_code=index;
}
/*
Flush out the buffered code.
*/
LZWOutputCode(waiting_code);
LZWOutputCode(end_of_information_code);
if (bits > 0)
{
/*
Add a character to current packet.
*/
packet[byte_count++]=(unsigned char) (datum & 0xff);
if (byte_count >= 254)
{
(void) fputc(byte_count,image->fp);
(void) fwrite((char *) packet,1,byte_count,image->fp);
byte_count=0;
}
}
/*
Flush accumulated data.
*/
if (byte_count > 0)
{
(void) fputc(byte_count,image->fp);
(void) fwrite((char *) packet,1,byte_count,image->fp);
}
/*
Free encoder memory.
*/
(void) free((char *) hash_suffix);
(void) free((char *) hash_prefix);
(void) free((char *) hash_code);
(void) free((char *) packet);
if (i < image->packets)
return(False);
return(True);
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.