Gered
e2176a10f0
despite the book itself stating that this code was not included due to the old GIF patent back in the 90's, it was actually included on the cd under /ACK/DOS/WATCOM/ACK_LIB. oops!
293 lines
5.6 KiB
C
293 lines
5.6 KiB
C
/*****************************************************************************
|
|
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
|
|
|
|
*****************************************************************************/
|
|
|
|
#include <stdio.h>
|
|
#include <conio.h>
|
|
#include <bios.h>
|
|
#include <fcntl.h>
|
|
#include "ack3d.h"
|
|
#include "ackeng.h"
|
|
#include "ackext.h"
|
|
|
|
#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
|
|
};
|
|
|
|
//=============================================================================
|
|
//
|
|
//=============================================================================
|
|
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);
|
|
}
|