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.