add implemented ackgif.c

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!
This commit is contained in:
Gered 2019-11-02 17:21:58 -04:00
parent 317d65c9ce
commit e2176a10f0

View file

@ -1,22 +1,292 @@
// This source file contains the functions needed to read in GIF files.
// (c) 1995 ACK Software (Lary Myers)
#include <stdio.h>
/*****************************************************************************
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
//±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
// 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);
}