home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fish 'n' More 2
/
fishmore-publicdomainlibraryvol.ii1991xetec.iso
/
disks
/
disk405.lzh
/
GIFMachine
/
Sources
/
doimage.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-11-17
|
5KB
|
245 lines
/* Copyright 1990 by Christopher A. Wichura.
See file GIFMachine.doc for full description of rights.
*/
#include "GIFMachine.h"
extern struct GIFdescriptor gdesc;
EXTERNBITPLANE;
static struct ImageDesc idesc;
extern struct RGB GlobalColourTable[256];
static struct RGB LocalColourTable[256];
extern ULONG ImageNumber;
extern char *AbortMsg;
static UWORD Xpos, Ypos;
static BOOL interleave;
static UBYTE LeaveStep[5] = {1, 8, 8, 4, 2};
static UBYTE LeaveFirst[5] = {0, 0, 4, 2, 1};
/* some variables used by the decompressor */
static int ReadError;
static UBYTE CodeSize;
static int EOFCode;
static UBYTE ReadMask;
static int CompDataPointer;
static int CompDataCount;
static UBYTE CompData[256];
/* tables used by the decompressor */
static UWORD Prefix[4096];
static UBYTE Suffix[4096];
static UBYTE OutCode[1025];
BOOL DoImage(BPTR fh)
{
register int index;
register int colours;
int Code;
MyPrintf("...Image #%ld encountered.\n", ImageNumber++);
if (FRead(fh, (char *)&idesc, 1, 9) != 9) {
PutStr("......Error reading image descriptor.\n");
return TRUE;
}
FlipWord(&idesc.id_Left);
FlipWord(&idesc.id_Top);
FlipWord(&idesc.id_Width);
FlipWord(&idesc.id_Height);
interleave = idesc.id_Info & 1L << 6;
if (interleave)
interleave = 1;
MyPrintf("......Xpos from %ld to %ld, Ypos from %ld to %ld, %sinterlaced.\n",
idesc.id_Left, idesc.id_Left + idesc.id_Width - 1,
idesc.id_Top, idesc.id_Top + idesc.id_Height - 1,
interleave ? "" : "not ");
if (idesc.id_Info & 1L << 7) {
colours = 1L << ((idesc.id_Info & 7) + 1);
MyPrintf("......Local colour map contains %ld entries.\n", colours);
for (index = 0; index < colours; index++) {
if (FRead(fh, &LocalColourTable[index], 1, 3) != 3) {
MyPrintf("......Error reading local colour #%ld.\n",
index);
return TRUE;
}
}
} else {
colours = 1L << ((gdesc.gd_ColInfo & 7) + 1);
CopyMem((char *)GlobalColourTable, (char *)LocalColourTable,
sizeof(LocalColourTable));
}
Xpos = Ypos = 0;
/* now we are ready to read the image in so do it! */
{
int MaxCode, ClearCode, CurCode,
OldCode, InCode, FreeCode;
int OutCount;
int FirstFree;
UBYTE InitCodeSize, FinChar, BitMask;
MyPrintf("......Decompressing line number %5ld", Ypos);
/* get the codesize and do general setup for decompression */
if ((CodeSize = FGetC(fh)) == -1) {
PutStr("\n......I/O Error during decompression.\n");
return TRUE;
}
ClearCode = 1L << CodeSize;
EOFCode = ClearCode + 1;
FreeCode = FirstFree = ClearCode + 2;
CodeSize++; /* per GIF spec */
InitCodeSize = CodeSize;
MaxCode = 1L << CodeSize;
ReadError = ReadMask = OutCount = 0;
CompDataPointer = CompDataCount = 0;
BitMask = colours - 1;
Code = ReadCode(fh);
while (Code != EOFCode) {
if (ReadError)
return TRUE;
if (SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
MyPrintf("\n%s", AbortMsg);
MyExit(ABORTEXITVAL);
}
if (Code == ClearCode) {
CodeSize = InitCodeSize;
MaxCode = 1L << CodeSize;
FreeCode = FirstFree;
FinChar = CurCode = OldCode = Code = ReadCode(fh);
AddPixel(FinChar);
} else {
CurCode = InCode = Code;
if (CurCode >= FreeCode) {
CurCode = OldCode;
OutCode[OutCount++] = FinChar;
}
while (CurCode > BitMask) {
if (OutCount > 1024) {
PutStr("\n......Corrupt GIF file (OutCount)\n");
return TRUE;
}
OutCode[OutCount++] = Suffix[CurCode];
CurCode = Prefix[CurCode];
}
FinChar = CurCode;
AddPixel(FinChar);
for (index = OutCount - 1; index >= 0; index--)
AddPixel(OutCode[index]);
OutCount = 0;
Prefix[FreeCode] = OldCode;
Suffix[FreeCode] = FinChar;
OldCode = InCode;
if (++FreeCode >= MaxCode) {
if (CodeSize < 12) {
CodeSize++;
MaxCode <<= 1;
}
}
}
Code = ReadCode(fh);
}
}
if ((Code = FGetC(fh)) == -1)
return TRUE;
/* done decompressing. Erase decompressing message and exit */
PutStr("\x9B" "22D\x9BKed.\n");
if (Code != 0) {
PutStr("......Warning: Unaligned packet.\n");
UnGetC(fh, Code);
}
return FALSE;
}
static UBYTE ByteBuf;
int ReadCode(BPTR fh)
{
register int temp;
register int DstMasked;
register int DstMask;
register LONG size;
temp = 0;
DstMasked = 1L << CodeSize;
for (DstMask = 1; DstMask != DstMasked; DstMask <<= 1) {
if (!ReadMask) {
if (CompDataPointer == CompDataCount) {
if ((size = FGetC(fh)) == -1) {
PutStr("\n......I/O Error during decompression.\n");
ReadError = 1;
return EOFCode;
}
if (FRead(fh, (char *)CompData, 1, size) != size) {
PutStr("\n......I/O Error during decompression.\n");
ReadError = 1;
return EOFCode;
}
CompDataCount = size;
CompDataPointer = 0;
}
ReadMask = 1;
ByteBuf = CompData[CompDataPointer++];
}
if (ByteBuf & ReadMask)
temp |= DstMask;
ReadMask <<= 1;
}
return temp;
}
void AddPixel(UBYTE index)
{
register UWORD XStore;
register UWORD YStore;
XStore = Xpos + idesc.id_Left;
YStore = Ypos + idesc.id_Top;
BitPlane[YStore][XStore] = LocalColourTable[index];
if (++Xpos == idesc.id_Width) {
Xpos = 0;
Ypos += LeaveStep[interleave];
if (Ypos >= idesc.id_Height)
Ypos = LeaveFirst[++interleave];
MyPrintf("\x9B" "5D%5ld", Ypos + idesc.id_Top);
}
}