diff --git a/ack_lib/ACKGIF.C b/ack_lib/ACKGIF.C index 737b798..bd7b1cb 100644 --- a/ack_lib/ACKGIF.C +++ b/ack_lib/ACKGIF.C @@ -1,22 +1,292 @@ -// This source file contains the functions needed to read in GIF files. -// (c) 1995 ACK Software (Lary Myers) -#include +/***************************************************************************** + ACKGIF.C + +#include + + Routine to load a 256 color .GIF file into a memory buffer. *Only* 256 + color images are supported here! Sorry, no routines to SAVE .GIFs... + Memory required is allocated on the fly. + + Mark Morley + morley@camosun.bc.ca + + Modified for use in the ACK environment by Lary Myers + +*****************************************************************************/ + +#include +#include +#include +#include #include "ack3d.h" #include "ackeng.h" #include "ackext.h" +#define MAX_CODES 4096 -//ħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħ -// Read a GIF format file and return a buffer containing the uncompressed -// image. -//ħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħħ -#pragma argsused -unsigned char *AckReadgif (char *picname) +extern unsigned char colordat[]; // Palette buffer in AckReadiff module + + +static FILE* fp; +static short curr_size; +static short clear; +static short ending; +static short newcodes; +static short top_slot; +static short slot; +static short navail_bytes = 0; +static short nbits_left = 0; +static unsigned char b1; +static unsigned char byte_buff[257]; +static unsigned char* pbytes; +static unsigned char* stack; +static unsigned char* suffix; +static unsigned short* prefix; + +static unsigned long code_mask[13] = { -// This is a stub routine used only as a place holder for the actual -// GIF read routine. It was omitted based on current patent issues. -return(NULL); -} -// **** End of Source **** + 0L, + 0x0001L, 0x0003L, + 0x0007L, 0x000FL, + 0x001FL, 0x003FL, + 0x007FL, 0x00FFL, + 0x01FFL, 0x03FFL, + 0x07FFL, 0x0FFFL +}; +//============================================================================= +// +//============================================================================= +static short get_next_code(void) +{ + short i; + static unsigned long ret; + +if (!nbits_left) + { + if (navail_bytes <= 0) + { + pbytes = byte_buff; + navail_bytes = getc(fp); + + if (navail_bytes) + { + for (i = 0; i < navail_bytes; ++i ) + *(byte_buff + i) = getc( fp ); + } + } + b1 = *pbytes++; + nbits_left = 8; + --navail_bytes; + } + +ret = b1 >> (8 - nbits_left); +while (curr_size > nbits_left) + { + if (navail_bytes <= 0) + { + pbytes = byte_buff; + navail_bytes = getc(fp); + if (navail_bytes) + { + for( i = 0; i < navail_bytes; ++i ) + *(byte_buff + i) = getc( fp ); + } + } + b1 = *pbytes++; + ret |= b1 << nbits_left; + nbits_left += 8; + --navail_bytes; + } + +nbits_left -= curr_size; + +return((short)(ret & *(code_mask + curr_size))); +} + + +//============================================================================= +// +//============================================================================= +unsigned char *AckReadgif(char *picname) +{ + unsigned char *sp; + unsigned char *buffer,*OrgBuffer; + short code, fc, oc; + short i; + unsigned char size; + short c; + unsigned short wt,ht; + int bSize; + unsigned char buf[1028]; + unsigned char red; + unsigned char grn; + unsigned char blu; + + +if (!rsHandle) + { + fp = fopen(picname,"rb"); + if( !fp ) + { + ErrorCode = ERR_BADFILE; + return(NULL); + } + } +else + { + fp = fdopen(rsHandle,"rb"); + if (fp == NULL) + { + ErrorCode = ERR_BADPICNAME; + return(0L); + } + + fseek(fp,rbaTable[(ULONG)picname],SEEK_SET); + } + +fread(buf,1,6,fp); +if( strncmp( buf, "GIF", 3 ) ) + { + if (!rsHandle) + fclose(fp); + + ErrorCode = ERR_INVALIDFORM; + return(NULL); + } + +fread(buf,1,7,fp); +for (i = 0; i < 768;) + { + red = getc(fp); + grn = getc(fp); + blu = getc(fp); + colordat[i++] = red >> 2; + colordat[i++] = grn >> 2; + colordat[i++] = blu >> 2; + } + +fread(buf,1,5,fp); +fread(buf,1,2,fp); +wt = (*(short *)buf); +fread(buf,1,2,fp); +ht = (*(short *)buf); +//wt = getw(fp); +//ht = getw(fp); +bSize = (ht * wt) + (sizeof(short) * 2); +buffer = (UCHAR *)AckMalloc(bSize); +if (buffer == NULL) + { + if (!rsHandle) + fclose(fp); + + ErrorCode = ERR_NOMEMORY; + return(NULL); + } + +OrgBuffer = buffer; + +(*(short *)buffer) = wt; +buffer += sizeof(short); +(*(short *)buffer) = ht; +buffer += sizeof(short); + +fread(buf,1,1,fp); +size = getc(fp); + +if (size < 2 || 9 < size) + { + if (!rsHandle) + fclose(fp); + AckFree(OrgBuffer); + ErrorCode = ERR_INVALIDFORM; + return(NULL); + } + +stack = (unsigned char *) AckMalloc(MAX_CODES + 1); +suffix = (unsigned char *) AckMalloc(MAX_CODES + 1); +prefix = (unsigned short *) AckMalloc(sizeof(short) * (MAX_CODES + 1)); + +if (stack == NULL || suffix == NULL || prefix == NULL) + { + if (!rsHandle) + fclose(fp); + AckFree(OrgBuffer); + ErrorCode = ERR_NOMEMORY; + return(NULL); + } + +curr_size = size + 1; +top_slot = 1 << curr_size; +clear = 1 << size; +ending = clear + 1; +slot = newcodes = ending + 1; +navail_bytes = nbits_left = 0; +oc = fc = 0; +sp = stack; + +while ( (c = get_next_code()) != ending ) + { + if (c == clear) + { + curr_size = size + 1; + slot = newcodes; + top_slot = 1 << curr_size; + while ( (c = get_next_code()) == clear ); + + if( c == ending ) + break; + + if( c >= slot ) + c = 0; + + oc = fc = c; + *buffer++ = c; + } + else + { + code = c; + if (code >= slot) + { + code = oc; + *sp++ = fc; + } + + while (code >= newcodes) + { + *sp++ = *(suffix + code); + code = *(prefix + code); + } + + *sp++ = code; + if (slot < top_slot) + { + *(suffix + slot) = fc = code; + *(prefix + slot++) = oc; + oc = c; + } + + if (slot >= top_slot && curr_size < 12) + { + top_slot <<= 1; + ++curr_size; + } + + while (sp > stack) + { + --sp; + *buffer++ = *sp; + } + } + } + +AckFree(stack); +AckFree(suffix); +AckFree(prefix); + +if (!rsHandle) + fclose(fp); + +return(OrgBuffer); +}