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:
parent
317d65c9ce
commit
e2176a10f0
298
ack_lib/ACKGIF.C
298
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 <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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue