2019-11-02 17:21:58 -04:00
|
|
|
/*****************************************************************************
|
|
|
|
ACKGIF.C
|
|
|
|
|
|
|
|
|
|
|
|
#include <malloc.h>
|
|
|
|
|
|
|
|
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
|
2019-11-02 13:17:24 -04:00
|
|
|
|
2019-11-02 17:21:58 -04:00
|
|
|
*****************************************************************************/
|
|
|
|
|
|
|
|
#include <stdio.h>
|
2019-11-03 13:05:01 -05:00
|
|
|
#include <string.h>
|
2019-11-02 17:21:58 -04:00
|
|
|
#include <conio.h>
|
|
|
|
#include <bios.h>
|
|
|
|
#include <fcntl.h>
|
2019-11-02 13:17:24 -04:00
|
|
|
#include "ack3d.h"
|
|
|
|
#include "ackeng.h"
|
|
|
|
#include "ackext.h"
|
|
|
|
|
2019-11-02 17:21:58 -04:00
|
|
|
#define MAX_CODES 4096
|
|
|
|
|
|
|
|
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] =
|
|
|
|
{
|
|
|
|
0L,
|
|
|
|
0x0001L, 0x0003L,
|
|
|
|
0x0007L, 0x000FL,
|
|
|
|
0x001FL, 0x003FL,
|
|
|
|
0x007FL, 0x00FFL,
|
|
|
|
0x01FFL, 0x03FFL,
|
|
|
|
0x07FFL, 0x0FFFL
|
|
|
|
};
|
2019-11-02 13:17:24 -04:00
|
|
|
|
2019-11-02 17:21:58 -04:00
|
|
|
//=============================================================================
|
|
|
|
//
|
|
|
|
//=============================================================================
|
|
|
|
static short get_next_code(void)
|
2019-11-02 13:17:24 -04:00
|
|
|
{
|
2019-11-02 17:21:58 -04:00
|
|
|
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)));
|
2019-11-02 13:17:24 -04:00
|
|
|
}
|
|
|
|
|
2019-11-02 17:21:58 -04:00
|
|
|
|
|
|
|
//=============================================================================
|
|
|
|
//
|
|
|
|
//=============================================================================
|
|
|
|
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);
|
2019-11-03 13:05:01 -05:00
|
|
|
if( strncmp( (char*)buf, "GIF", 3 ) )
|
2019-11-02 17:21:58 -04:00
|
|
|
{
|
|
|
|
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);
|
|
|
|
}
|