Path: news.larc.nasa.gov!amiga-request
From: amiga-request@ab20.larc.nasa.gov (Amiga Sources/Binaries Moderator)
Subject: v91i165: GIFMachine 2.137 - convert GIF images into IFF SHAMs, Part01/03
Reply-To: caw@miroc.chi.il.us (Christopher A. Wichura)
Newsgroups: comp.sources.amiga
Message-ID: <comp.sources.amiga.v91i165@ab20.larc.nasa.gov>
Date: 31 Aug 91 10:10:12 GMT
Approved: tadguy@uunet.UU.NET (Tad Guy)
X-Mail-Submissions-To: amiga@uunet.uu.net
X-Post-Discussions-To: comp.sys.amiga.misc

Submitted-by: caw@miroc.chi.il.us (Christopher A. Wichura)
Posting-number: Volume 91, Issue 165
Archive-name: graphics/gifmachine2137/part01

[ includes uuencoded executable, object modules, etc  ...tad ]

This is an update to GIFMachine, as previously found on the Fred Fish disks
and released via comp.binaries.amiga.  Full source is included.  The user
must be running KickStart 37.mumble to use this.

GIFMachine is a program that converts pictures stored in the CompuServe GIF
(Graphics Interchange Format) format into IFF SHAM format.  There are very
few programs that do this, and most have many problems.

#!/bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 1 (of 3)."
# Contents:  ReadMeFirst Sources Sources/24to12.c Sources/arg_help.o.uu
#   Sources/arg_help.uu Sources/doflip.c Sources/doimage.c
#   Sources/extensions.c Sources/giftosham.c Sources/largearrays.c
#   Sources/lmkfile.uu Sources/mymem.c Sources/myprintf.c
#   Sources/rgbdiff.c Sources/startup.a Sources/stripborder.c
#   Sources/version.o.uu Sources/warncli.c Sources/xcomp.c
# Wrapped by tadguy@ab20 on Wed Aug 28 21:46:32 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'ReadMeFirst' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ReadMeFirst'\"
else
echo shar: Extracting \"'ReadMeFirst'\" \(2214 characters\)
sed "s/^X//" >'ReadMeFirst' <<'END_OF_FILE'
XThis is version 2.104, an update to version 2.96.  It fixes a bug in the
XStripBorder() routine which could cause the system to crash (it actually
Xappears to be more a bug in SAS 5.10's conditional code creation).
X
XI also reduced the amount of static memory declared by 1k.  Also moved some
Xof the declarations in giftosham.c to largearrays.c to avoid the `too much
Xglobal data' warning.
X
X---------------------------------------------------------------------------
X2/24/91:  Version 2.116
X
XThis fixes a couple problems with the iff writer:
X
X	1)  If the image had an odd width and was not XCOMPed or
X	    NOBORDERed, a corrupted iff file would be written.
X
X	2)  If the image was greater vertically than the size of one's
X	    screen (i.e., required scrolling down), was of odd height,
X	    and was interlaced, Mostra v1.02 would glitch when one
X	    scrolled all the way down to the bottom of the image.
X	    This has been fixed by writing an extra blank scan line
X	    to images of odd height.
X
X
XI also moved the help text into a seperate file which is then BLinked in.
XMakes it easier to edit, and doesn't cause the compiler to throw ten
Xthousand coniption fits (i.e., crash) when it gets to be more than 512
Xchars long.
X
X---------------------------------------------------------------------------
X8/26/91:  Version 2.137
X
XA couple of changes have been made:
X
X	1)  C= changed the calling format for the SetVBuf() command
X	    between KickStart V36 and V37.  Since V37 is starting to
X	    become available, a new version which uses the new
X	    calling format was definately needed.
X
X	2)  A new option, NOCOUNT, has been added so that will suppress
X	    the printing of line numbers during various operations.
X	    This can speed the conversion process up a tad.
X
X	3)  Escape codes for ANSI cursor movements have been recoded as
X	    \x1B[ instead of \x9B.  This allows GIFMachine output to
X	    appear correctly on terminals that don't know about the
X	    \x9B shorthand.
X
X	4)  The UpCVersion program I use for bumping revision numbers
X	    has been updated to insert a 2.0 $VERS: string into the
X	    version object file.  This allows one to use the 2.0
X	    c:version command to determine GIFMachine's revision.
END_OF_FILE
if test 2214 -ne `wc -c <'ReadMeFirst'`; then
    echo shar: \"'ReadMeFirst'\" unpacked with wrong size!
fi
# end of 'ReadMeFirst'
fi
if test ! -d 'Sources' ; then
    echo shar: Creating directory \"'Sources'\"
    mkdir 'Sources'
fi
if test -f 'Sources/24to12.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Sources/24to12.c'\"
else
echo shar: Extracting \"'Sources/24to12.c'\" \(4354 characters\)
sed "s/^X//" >'Sources/24to12.c' <<'END_OF_FILE'
X/* Copyright 1990 by Christopher A. Wichura.
X   See file GIFMachine.doc for full description of rights.
X*/
X
X#include "GIFMachine.h"
X
Xextern struct GIFdescriptor gdesc;
XEXTERNBITPLANE;
X
Xextern BOOL DisplayCounts;
X
X/* since both MasterColourTable and the PaletteBuf are the same size and
X   type we will define MCT to be the PaletteBuf to cut down on static
X   memory declarations */
X#define MasterColourTable PaletteBuf
X
Xextern UBYTE MasterColourTable[MAXCOLOURS];
Xstatic UWORD TotalColours;
X
Xextern BYTE *CurrentLineErr[3];
Xextern BYTE *LastLineErr[3];
X
Xextern char *AbortMsg;
X
X#define MAXERR 2
X
Xvoid ReduceTo12(void)
X{
X	register UWORD x;
X	register UWORD y;
X
X	PutStr("...Reducing palette to 12 bits.\n......");
X	if (DisplayCounts)
X		PutStr("Line ");
X	else
X		PutStr("Working");
X	Flush(Output());
X
X	TotalColours = 0;
X	memset((char *)MasterColourTable, 0, sizeof(MasterColourTable));
X
X	for (y = 0; y < gdesc.gd_Height; y++) {
X		if (DisplayCounts)
X			MyPrintf("%5ld", y);
X
X		if (SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
X			MyPrintf("\n%s", AbortMsg);
X			MyExit(ABORTEXITVAL);
X		}
X
X		for (x = 0; x < gdesc.gd_Width; x++)
X			PutValue(x, y, AddColour(&BitPlane[y][x]));
X
X		if (DisplayCounts)
X			PutStr("\x1B[5D");
X	}
X
X	MyPrintf("\x1B[%ldD%ld total unique colours used.\n", (DisplayCounts ? 5 : 7), TotalColours);
X}
X
Xvoid DitherTo12(void)
X{
X	register UWORD x;
X	register UWORD y;
X	register int RedErr;
X	register int GreenErr;
X	register int BlueErr;
X	BYTE **cerr, **lerr, **terr;
X	struct RGB rgb;
X
X	PutStr("...Dithering palette to 12 bits.\n......Setup");
X	Flush(Output());
X
X	TotalColours = 0;
X	memset((char *)MasterColourTable, 0, sizeof(MasterColourTable));
X
X	cerr = (BYTE **)&CurrentLineErr[0];
X	lerr = (BYTE **)&LastLineErr[0];
X
X	/* the top, left and right borders will be used unmodified */
X
X	for (x = 0; x < gdesc.gd_Width; x++)
X		PutValue(x, 0, AddColour(&BitPlane[0][x]));
X
X	for (y = 1; y < gdesc.gd_Height; y++) {
X		PutValue(0, y, AddColour(&BitPlane[y][0]));
X		PutValue(gdesc.gd_Width - 1, y, AddColour(&BitPlane[y][gdesc.gd_Width - 1]));
X	}
X
X	/* since the error tables are alloced with MEMF_CLEAR we won't bother
X	   to clear them here.  instead, we just hit the main loop */
X
X	if (DisplayCounts)
X		PutStr("\x1B[5DLine ");
X	else
X		PutStr("\x1B[5DWorking");
X	Flush(Output());
X
X	for (y = 1; y < gdesc.gd_Height; y++) {
X		if (DisplayCounts)
X			MyPrintf("%5ld", y);
X
X		if (SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
X			MyPrintf("\n%s", AbortMsg);
X			MyExit(ABORTEXITVAL);
X		}
X
X		for (x = 1; x < (gdesc.gd_Width - 1); x++) {
X			rgb = BitPlane[y][x];
X
X			RedErr   = cerr[0][x - 1] + 7*lerr[0][x - 1] + 5*lerr[0][x] + 3*lerr[0][x + 1];
X			GreenErr = cerr[1][x - 1] + 7*lerr[1][x - 1] + 5*lerr[1][x] + 3*lerr[1][x + 1];
X			BlueErr  = cerr[2][x - 1] + 7*lerr[2][x - 1] + 5*lerr[2][x] + 3*lerr[2][x + 1];
X
X			RedErr   >>= 4;
X			GreenErr >>= 4;
X			BlueErr  >>= 4;
X
X	/* now we add the errors into the colour we want.  if this would push
X	   us over 255 (and thus out of range) we subtract the error out so
X	   that we still see some dithering instead of washing out the area. */
X
X			if (rgb.rgb_Red + RedErr > 255)
X				rgb.rgb_Red -= RedErr;
X			else
X				rgb.rgb_Red += RedErr;
X
X			if (rgb.rgb_Green + GreenErr > 255)
X				rgb.rgb_Green -= GreenErr;
X			else
X				rgb.rgb_Green += GreenErr;
X
X			if (rgb.rgb_Blue + BlueErr > 255)
X				rgb.rgb_Blue -= BlueErr;
X			else
X				rgb.rgb_Blue += BlueErr;
X
X			PutValue(x, y, AddColour(&rgb));
X
X			RedErr   = (int)rgb.rgb_Red   - (int)(rgb.rgb_Red   & 0xF0);
X			GreenErr = (int)rgb.rgb_Green - (int)(rgb.rgb_Green & 0xF0);
X			BlueErr  = (int)rgb.rgb_Blue  - (int)(rgb.rgb_Blue  & 0xF0);
X
X			if (RedErr > MAXERR)
X				RedErr = (RedErr * 3) >> 2;
X
X			if (GreenErr > MAXERR)
X				GreenErr = (GreenErr * 3) >> 2;
X
X			if (BlueErr > MAXERR)
X				BlueErr = (BlueErr * 3) >> 2;
X
X			cerr[0][x] = RedErr;
X			cerr[1][x] = GreenErr;
X			cerr[2][x] = BlueErr;
X		}
X
X			terr = lerr;
X			lerr = cerr;
X			cerr = terr;
X
X		if (DisplayCounts)
X			PutStr("\x1B[5D");
X	}
X
X	MyPrintf("\x1B[%ldD%ld total unique colours used.\n", (DisplayCounts ? 5 : 7), TotalColours);
X}
X
XUWORD AddColour(struct RGB *rgb)
X{
X	register UWORD colour;
X
X	colour = ((rgb->rgb_Red << 4) & 0xF00) |
X		 (rgb->rgb_Green & 0xF0) |
X		 (rgb->rgb_Blue >> 4);
X
X	if (!MasterColourTable[colour]) {
X		MasterColourTable[colour] = 1;
X		TotalColours++;
X	}
X
X	return colour;
X}
END_OF_FILE
if test 4354 -ne `wc -c <'Sources/24to12.c'`; then
    echo shar: \"'Sources/24to12.c'\" unpacked with wrong size!
fi
# end of 'Sources/24to12.c'
fi
if test -f 'Sources/arg_help.o.uu' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Sources/arg_help.o.uu'\"
else
echo shar: Extracting \"'Sources/arg_help.o.uu'\" \(863 characters\)
sed "s/^X//" >'Sources/arg_help.o.uu' <<'END_OF_FILE'
Xbegin 666 arg_help.o
XM```#YP````-A<F=?:&5L<"YO``````/H`````71E>'0```/I````@25S('8E]
XM<PI#;W!Y<FEG:'0@J2`Q.3DP+#$Y.3$@8GD@&ULT.S,S.S0R;4-H<FES=&]PR
XM:&5R($$N(%=I8VAU<F$;6S`[,S,[-#!M("@;6S,R;6-A=QM;,S-M0!M;,S)MP
XM;6ER;V,N8VAI+FEL+G5S&ULS,VTI"AM;,S)M06QL(')I9VAT<R!R97-E<G9E_
XM9"X*"AM;,S-M57-A9V4Z("`@("`E<R`\&ULS,6U'249F:6QE<RAS*1M;,S)MN
XM/B!;&ULS,VU43R`;6S,Q;41I<F5C=&]R>2!\($9I;&4;6S,R;5T@6QM;,S-MF
XM04Q,&ULS,FU="B`@("`@("`@("`@("`@("`@("`@("!;&ULS,VU.3T)/4D1%U
XM4B`;6S,R;3P;6S,Q;4QI;F4@5&AR97-H&ULS,FT^72!;&ULS,VU80T]-4!M;W
XM,S)M72!;&ULS,VU$251(15(;6S,R;5T*("`@("`@("`@("`@("`@("`@("`@"
XM(%L;6S,S;5A&3$E0&ULS,FU=(%L;6S,S;5E&3$E0&ULS,FU=(%L;6S,S;41%F
XM15`;6S,R;5T@6QM;,S-M3D]#3U5.5!M;,S)M70H@("`@("`@("`@("`@("`@3
XM("`@("`@6QM;,S-M0E5&4TE:12`;6S,R;3P;6S,Q;5-I>F4@:6X@2T)Y=&5SK
XM&ULS,FT^70H;6S,Q;0```````^\!```#7V%R9U]H96QP````````````````+
X#``/RU
X``
Xend
Xsize 588
END_OF_FILE
if test 863 -ne `wc -c <'Sources/arg_help.o.uu'`; then
    echo shar: \"'Sources/arg_help.o.uu'\" unpacked with wrong size!
fi
# end of 'Sources/arg_help.o.uu'
fi
if test -f 'Sources/arg_help.uu' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Sources/arg_help.uu'\"
else
echo shar: Extracting \"'Sources/arg_help.uu'\" \(759 characters\)
sed "s/^X//" >'Sources/arg_help.uu' <<'END_OF_FILE'
Xbegin 666 arg_help.txt
XM)7,@=B5S"D-O<'ER:6=H=""I(#$Y.3`L,3DY,2!B>2`;6S0[,S,[-#)M0VAR6
XM:7-T;W!H97(@02X@5VEC:'5R81M;,#LS,SLT,&T@*!M;,S)M8V%W&ULS,VU`7
XM&ULS,FUM:7)O8RYC:&DN:6PN=7,;6S,S;2D*&ULS,FU!;&P@<FEG:'1S(')EB
XM<V5R=F5D+@H*&ULS,VU5<V%G93H@("`@("5S(#P;6S,Q;4=)1F9I;&5S*',I+
XM&ULS,FT^(%L;6S,S;51/(!M;,S%M1&ER96-T;W)Y('P@1FEL91M;,S)M72!;E
XM&ULS,VU!3$P;6S,R;5T*("`@("`@("`@("`@("`@("`@("`@(%L;6S,S;4Y/2
XM0D]21$52(!M;,S)M/!M;,S%M3&EN92!4:')E<V@;6S,R;3Y=(%L;6S,S;5A#!
XM3TU0&ULS,FU=(%L;6S,S;41)5$A%4AM;,S)M70H@("`@("`@("`@("`@("`@$
XM("`@("`@6QM;,S-M6$9,25`;6S,R;5T@6QM;,S-M649,25`;6S,R;5T@6QM;J
XM,S-M1$5%4!M;,S)M72!;&ULS,VU.3T-/54Y4&ULS,FU="B`@("`@("`@("`@/
XM("`@("`@("`@("!;&ULS,VU"549325I%(!M;,S)M/!M;,S%M4VEZ92!I;B!+$
X20GET97,;6S,R;3Y="AM;,S%M[
X``
Xend
Xsize 513
END_OF_FILE
if test 759 -ne `wc -c <'Sources/arg_help.uu'`; then
    echo shar: \"'Sources/arg_help.uu'\" unpacked with wrong size!
fi
# end of 'Sources/arg_help.uu'
fi
if test -f 'Sources/doflip.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Sources/doflip.c'\"
else
echo shar: Extracting \"'Sources/doflip.c'\" \(1672 characters\)
sed "s/^X//" >'Sources/doflip.c' <<'END_OF_FILE'
X/* Copyright 1990 by Christopher A. Wichura.
X   See file GIFMachine.doc for full description of rights.
X*/
X
X#include "GIFMachine.h"
X
Xextern struct GIFdescriptor gdesc;
XEXTERNBITPLANE;
X
Xextern char *AbortMsg;
X
Xextern BOOL DisplayCounts;
X
Xvoid DoXFlip(void)
X{
X	register UWORD x1;
X	register UWORD x2;
X	register UWORD y;
X	struct RGB TempColourStore;
X
X	MyPrintf("...Flipping image %s.\n......%s ", "horizontally", (DisplayCounts ? "Line" : "Working\x1B[1D"));
X
X        for (y = 0; y < gdesc.gd_Height; y++) {
X		if (DisplayCounts)
X			MyPrintf("%5ld", y);
X
X		for (x1 = 0, x2 = gdesc.gd_Width - 1; x1 < x2; x1++, x2--) {
X			TempColourStore = BitPlane[y][x1];
X			BitPlane[y][x1] = BitPlane[y][x2];
X			BitPlane[y][x2] = TempColourStore;
X		}
X
X		if (SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
X			MyPrintf("\n%s", AbortMsg);
X			MyExit(ABORTEXITVAL);
X		}
X
X		if (DisplayCounts)
X			PutStr("\x1B[5D");
X	}
X
X	MyPrintf("\x1B[%ldDFlipped.    \n", (DisplayCounts ? 5 : 7));
X}
X
Xvoid DoYFlip(void)
X{
X	register UWORD y1;
X	register UWORD y2;
X	register UWORD x;
X	struct RGB TempColourStore;
X
X	MyPrintf("...Flipping image %s.\n......%s ", "vertically", (DisplayCounts ? "Column" : "Working\x1B[1D"));
X
X        for (x = 0; x < gdesc.gd_Width; x++) {
X		if (DisplayCounts)
X			MyPrintf("%5ld", x);
X
X		for (y1 = 0, y2 = gdesc.gd_Height - 1; y1 < y2; y1++, y2--) {
X			TempColourStore = BitPlane[y1][x];
X			BitPlane[y1][x] = BitPlane[y2][x];
X			BitPlane[y2][x] = TempColourStore;
X		}
X
X		if (SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
X			MyPrintf("\n%s", AbortMsg);
X			MyExit(ABORTEXITVAL);
X		}
X
X		if (DisplayCounts)
X			PutStr("\x1B[5D");
X	}
X
X	MyPrintf("\x1B[%ldDFlipped.    \n", 7);
X}
END_OF_FILE
if test 1672 -ne `wc -c <'Sources/doflip.c'`; then
    echo shar: \"'Sources/doflip.c'\" unpacked with wrong size!
fi
# end of 'Sources/doflip.c'
fi
if test -f 'Sources/doimage.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Sources/doimage.c'\"
else
echo shar: Extracting \"'Sources/doimage.c'\" \(5510 characters\)
sed "s/^X//" >'Sources/doimage.c' <<'END_OF_FILE'
X/* Copyright 1990 by Christopher A. Wichura.
X   See file GIFMachine.doc for full description of rights.
X*/
X
X#include "GIFMachine.h"
X
Xextern struct GIFdescriptor gdesc;
XEXTERNBITPLANE;
X
Xstatic struct ImageDesc idesc;
Xextern struct RGB GlobalColourTable[256];
Xstatic struct RGB LocalColourTable[256];
Xextern ULONG ImageNumber;
X
Xextern char *AbortMsg;
X
Xstatic UWORD Xpos, Ypos;
Xstatic BOOL interleave;
X
Xstatic UBYTE LeaveStep[5]  = {1, 8, 8, 4, 2};
Xstatic UBYTE LeaveFirst[5] = {0, 0, 4, 2, 1};
X
X/* some variables used by the decompressor */
Xstatic int ReadError;
Xstatic UBYTE CodeSize;
Xstatic int EOFCode;
Xstatic UBYTE ReadMask;
Xstatic int CompDataPointer;
Xstatic int CompDataCount;
Xstatic UBYTE CompData[256];
X
X/* tables used by the decompressor */
Xstatic UWORD Prefix[4096];
Xstatic UBYTE Suffix[4096];
Xstatic UBYTE OutCode[1025];
X
Xextern BOOL DisplayCounts;
X
XBOOL DoImage(BPTR fh)
X{
X	register int index;
X	register int colours;
X	int Code;
X
X	MyPrintf("...Image #%ld encountered.\n", ImageNumber++);
X
X	if (FRead(fh, (char *)&idesc, 1, 9) != 9) {
X		PutStr("......Error reading image descriptor.\n");
X		return TRUE;
X	}
X
X	FlipWord(&idesc.id_Left);
X	FlipWord(&idesc.id_Top);
X	FlipWord(&idesc.id_Width);
X	FlipWord(&idesc.id_Height);
X
X	interleave = idesc.id_Info & 1L << 6;
X	if (interleave)
X		interleave = 1;
X
X	MyPrintf("......Xpos from %ld to %ld, Ypos from %ld to %ld, %sinterlaced.\n",
X		idesc.id_Left, idesc.id_Left + idesc.id_Width - 1,
X		idesc.id_Top, idesc.id_Top + idesc.id_Height - 1,
X		interleave ? "" : "not ");
X
X	if (idesc.id_Info & 1L << 7) {
X		colours = 1L << ((idesc.id_Info & 7) + 1);
X		MyPrintf("......Local colour map contains %ld entries.\n", colours);
X
X		for (index = 0; index < colours; index++) {
X			if (FRead(fh, &LocalColourTable[index], 1, 3) != 3) {
X				MyPrintf("......Error reading local colour #%ld.\n",
X					index);
X				return TRUE;
X			}
X		}
X	} else {
X		colours = 1L << ((gdesc.gd_ColInfo & 7) + 1);
X		CopyMem((char *)GlobalColourTable, (char *)LocalColourTable,
X			sizeof(LocalColourTable));
X	}
X
X	Xpos = Ypos = 0;
X
X	/* now we are ready to read the image in so do it! */
X
X	{
X		int MaxCode, ClearCode, CurCode,
X		    OldCode, InCode, FreeCode;
X		int OutCount;
X		int FirstFree;
X		UBYTE InitCodeSize, FinChar, BitMask;
X
X		if (DisplayCounts)
X			MyPrintf("......Decompressing line number %5ld", Ypos);
X		else
X			PutStr("......Decompressing");
X		Flush(Output());
X
X		/* get the codesize and do general setup for decompression */
X		if ((CodeSize = FGetC(fh)) == -1) {
X			PutStr("\n......I/O Error during decompression.\n");
X			return TRUE;
X		}
X
X		ClearCode = 1L << CodeSize;
X		EOFCode = ClearCode + 1;
X		FreeCode = FirstFree = ClearCode + 2;
X
X		CodeSize++;	/* per GIF spec */
X		InitCodeSize = CodeSize;
X		MaxCode = 1L << CodeSize;
X		ReadError = ReadMask = OutCount = 0;
X		CompDataPointer = CompDataCount = 0;
X
X		BitMask = colours - 1;
X
X		Code = ReadCode(fh);
X		while (Code != EOFCode) {
X			if (ReadError)
X				return TRUE;
X
X			if (SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
X				MyPrintf("\n%s", AbortMsg);
X				MyExit(ABORTEXITVAL);
X			}
X
X			if (Code == ClearCode) {
X				CodeSize = InitCodeSize;
X				MaxCode = 1L << CodeSize;
X				FreeCode = FirstFree;
X				FinChar = CurCode = OldCode = Code = ReadCode(fh);
X				AddPixel(FinChar);
X			} else {
X				CurCode = InCode = Code;
X
X				if (CurCode >= FreeCode) {
X					CurCode = OldCode;
X					OutCode[OutCount++] = FinChar;
X				}
X
X				while (CurCode > BitMask) {
X					if (OutCount > 1024) {
X						PutStr("\n......Corrupt GIF file (OutCount)\n");
X						return TRUE;
X					}
X
X					OutCode[OutCount++] = Suffix[CurCode];
X					CurCode = Prefix[CurCode];
X				}
X
X				FinChar = CurCode;
X				AddPixel(FinChar);
X
X				for (index = OutCount - 1; index >= 0; index--)
X					AddPixel(OutCode[index]);
X				OutCount = 0;
X
X				Prefix[FreeCode] = OldCode;
X				Suffix[FreeCode] = FinChar;
X				OldCode = InCode;
X
X				if (++FreeCode >= MaxCode) {
X					if (CodeSize < 12) {
X						CodeSize++;
X						MaxCode <<= 1;
X					}
X				}
X			}
X
X			Code = ReadCode(fh);
X		}
X	}
X
X	if ((Code = FGetC(fh)) == -1)
X		return TRUE;
X
X	/* done decompressing.  Erase decompressing message and exit */
X	MyPrintf("\x1B[%ldD\x1B[Ked.\n", (DisplayCounts ? 21 : 3));
X
X	if (Code != 0) {
X		PutStr("......Warning:  Unaligned packet.\n");
X		UnGetC(fh, Code);
X	}
X
X	return FALSE;
X}
X
Xstatic UBYTE ByteBuf;
X
Xint ReadCode(BPTR fh)
X{
X	register int temp;
X	register int DstMasked;
X	register int DstMask;
X	register LONG size;
X
X	temp = 0;
X	DstMasked = 1L << CodeSize;
X	for (DstMask = 1; DstMask != DstMasked; DstMask <<= 1) {
X		if (!ReadMask) {
X			if (CompDataPointer == CompDataCount) {
X				if ((size = FGetC(fh)) == -1) {
X					PutStr("\n......I/O Error during decompression.\n");
X					ReadError = 1;
X					return EOFCode;
X				}
X
X				if (FRead(fh, (char *)CompData, 1, size) != size) {
X					PutStr("\n......I/O Error during decompression.\n");
X					ReadError = 1;
X					return EOFCode;
X				}
X
X				CompDataCount = size;
X				CompDataPointer = 0;
X			}
X
X			ReadMask = 1;
X			ByteBuf = CompData[CompDataPointer++];
X		}
X
X		if (ByteBuf & ReadMask)
X			temp |= DstMask;
X
X		ReadMask <<= 1;
X	}
X
X	return temp;
X}
X
Xvoid AddPixel(UBYTE index)
X{
X	register UWORD XStore;
X	register UWORD YStore;
X
X	XStore = Xpos + idesc.id_Left;
X	YStore = Ypos + idesc.id_Top;
X
X	BitPlane[YStore][XStore] = LocalColourTable[index];
X
X	if (++Xpos == idesc.id_Width) {
X		Xpos = 0;
X		Ypos += LeaveStep[interleave];
X		if (Ypos >= idesc.id_Height)
X			Ypos = LeaveFirst[++interleave];
X
X		if (DisplayCounts)
X			MyPrintf("\x1B[5D%5ld", Ypos + idesc.id_Top);
X	}
X}
END_OF_FILE
if test 5510 -ne `wc -c <'Sources/doimage.c'`; then
    echo shar: \"'Sources/doimage.c'\" unpacked with wrong size!
fi
# end of 'Sources/doimage.c'
fi
if test -f 'Sources/extensions.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Sources/extensions.c'\"
else
echo shar: Extracting \"'Sources/extensions.c'\" \(2266 characters\)
sed "s/^X//" >'Sources/extensions.c' <<'END_OF_FILE'
X/* Copyright 1990 by Christopher A. Wichura.
X   See file GIFMachine.doc for full description of rights.
X*/
X
X#include "GIFMachine.h"
X
Xstruct MinList CommentList;
Xstatic UBYTE buf[256];
X
XBOOL DoExtension(BPTR fh)
X{
X	register LONG size;
X	register LONG cmdcode;
X	register char *Comment;
X	register char *OldComment;
X	register int CommentLength;
X	register int OldCommentLength;
X	register struct CommentNode *cn;
X
X	if ((cmdcode = FGetC(fh)) == -1) {
X		PutStr("...I/O error reading extension block function code\n");
X		return TRUE;
X	}
X
X	switch(cmdcode) {
X		case GIF_COMMENT_EXT:
X			PutStr("...Comment extension encountered.  Contents will be stored in an ANNO chunk.\n");
X
X			if (!(cn = (struct CommentNode *)MyAlloc(sizeof(struct CommentNode)))) {
X				PutStr("......Out of memory allocating comment block.\n");
X				return TRUE;
X			}
X
X			Comment = NULL;
X			CommentLength = 0;
X
X			for (;;) {
X				if ((size = FGetC(fh)) == -1) {
X					PutStr("......I/O Error reading comment block.\n");
X					return TRUE;
X				}
X
X				if (size) {
X					if (FRead(fh, buf, 1, size) != size) {
X						PutStr("......I/O Error reading comment block.\n");
X						return TRUE;
X					}
X
X					OldComment = Comment;
X					OldCommentLength = CommentLength;
X					CommentLength += size;
X
X					if (!(Comment = MyAlloc(CommentLength))) {
X						PutStr("......Out of memory allocating comment block.\n");
X						return TRUE;
X					}
X
X					if (OldCommentLength) {
X						CopyMem(OldComment, Comment, OldCommentLength);
X						MyFree(OldComment);
X					}
X
X					CopyMem(buf, &Comment[OldCommentLength], size);
X				} else {	/* end of comment so store it */
X					cn->cn_Comment = Comment;
X					cn->cn_CommentLength = CommentLength;
X					AddTail((struct List *)&CommentList, (struct Node *)cn);
X					return FALSE;
X				}
X			}
X			break;
X
X		default:
X			MyPrintf("...Extension block function code #%ld not know, skipping.\n",
X			 cmdcode);
X
X			/* we must skip over any data for the extension block */
X			for (;;) {
X				if ((size = FGetC(fh)) == -1) {
X					PutStr("...I/O Error skipping unknown extension block.\n");
X					return TRUE;
X				}
X
X				if (size == 0)
X					return FALSE;
X
X				if (FRead(fh, buf, 1, size) != size) {
X					PutStr("...I/O Error skipping unknown extension block.\n");
X					return TRUE;
X				}
X			}
X			break;
X	}
X}
END_OF_FILE
if test 2266 -ne `wc -c <'Sources/extensions.c'`; then
    echo shar: \"'Sources/extensions.c'\" unpacked with wrong size!
fi
# end of 'Sources/extensions.c'
fi
if test -f 'Sources/giftosham.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Sources/giftosham.c'\"
else
echo shar: Extracting \"'Sources/giftosham.c'\" \(5386 characters\)
sed "s/^X//" >'Sources/giftosham.c' <<'END_OF_FILE'
X/* Copyright 1990 by Christopher A. Wichura.
X   See file GIFMachine.doc for full description of rights.
X*/
X
X#include "GIFMachine.h"
X
Xextern struct GIFdescriptor gdesc;
XEXTERNBITPLANE;
X
Xextern char *AbortMsg;
X
Xextern BOOL DisplayCounts;
X
Xextern BOOL Laced;
X
XUWORD *SHAMmem;
X
Xstruct RGB Palette[16];
X
Xextern UBYTE PaletteBuf[MAXCOLOURS];
Xextern ULONG ColourBuf[MAXCOLOURS];
Xstatic ULONG ErrBuf[MAXCOLOURS];
X
X#define ISLACED (Laced && (y != gdesc.gd_Height - 1))
X
Xvoid GIFtoSHAM(void)
X{
X	register UWORD x;
X	register UWORD current;
X	register int index;
X	register int index2;
X	ULONG error;
X	UWORD y;
X	int Pal;
X	int ShamIndex;
X	int colours;
X
X	ULONG TotalErr, LineErr;
X
X	ULONG bestpal;
X	ULONG besterr;
X
X	UBYTE CurrentRed,  CurrentGreen,  CurrentBlue;
X	UBYTE PreviousRed, PreviousGreen, PreviousBlue;
X
X	MyPrintf("...Converting to SHAM format.\n......");
X	if (DisplayCounts)
X		PutStr("Line");
X	else
X		PutStr("Working");
X	Flush(Output());
X
X	ShamIndex = TotalErr = 0;
X
X	/* palette zero is always the background colour.  regardless of
X	   what the GIF specified for the background, we always use black.
X	   this is a kludge to get around a hardware `feature' that causes
X	   all overscanned screens to have a black background regardless
X	   of what the background was specified to be.
X	*/
X
X	Palette[0].rgb_Red = Palette[0].rgb_Green = Palette[0].rgb_Blue = 0;
X
X	for (y = 0; y < gdesc.gd_Height; y += (ISLACED ? 2 : 1)) {
X		if (DisplayCounts) {
X			if (ISLACED)
X				MyPrintf("s %5ld-%5ld", y, y + 1);
X			else
X				MyPrintf(" %5ld", y);
X		}
X
X		if (SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
X			MyPrintf("\n%s", AbortMsg);
X			MyExit(ABORTEXITVAL);
X		}
X
X		memset((char *)ColourBuf, 0, sizeof(ColourBuf));
X
X		for (colours = index2 = 0; index2 < (ISLACED ? 2 : 1); index2++)
X			for (x = 0; x < gdesc.gd_Width; x++) {
X				current = GetValue(x, y + index2);
X
X				if (ColourBuf[current]++ == 0)
X					colours++;
X			}
X
X		if (DisplayCounts)
X			MyPrintf(", %4ld unique colours", colours);
X
X		memset((char *)PaletteBuf, 0, sizeof(PaletteBuf));
X
X		for (index = 0; index < MAXCOLOURS; index++) {
X			if (ColourBuf[index] == 0)
X				continue;
X
X			ErrBuf[index] = RGBdiff(GetRed(index),
X						GetGreen(index),
X						GetBlue(index),
X						Palette[0].rgb_Red,
X						Palette[0].rgb_Green,
X						Palette[0].rgb_Blue);
X		}
X
X		for (Pal = 1; Pal < 16; Pal++) {
X			for (besterr = index = 0; index < MAXCOLOURS; index++) {
X				if (ColourBuf[index] == 0)
X					continue;
X
X				if (ErrBuf[index] * ColourBuf[index] >= besterr) {
X					bestpal = index;
X					besterr = ErrBuf[index] * ColourBuf[index];
X				}
X			}
X
X			Palette[Pal].rgb_Red   = GetRed(bestpal);
X			Palette[Pal].rgb_Green = GetGreen(bestpal);
X			Palette[Pal].rgb_Blue  = GetBlue(bestpal);
X
X			for (index = 0; index < MAXCOLOURS; index++) {
X				if (ColourBuf[index] == 0)
X					continue;
X
X				error = RGBdiff(GetRed(index),
X						GetGreen(index),
X						GetBlue(index),
X						Palette[Pal].rgb_Red,
X						Palette[Pal].rgb_Green,
X						Palette[Pal].rgb_Blue);
X
X				if (error < ErrBuf[index]) {
X					ErrBuf[index] = error;
X					PaletteBuf[index] = Pal;
X				}
X			}
X		}
X
X		for (index = 0; index < 16; index++)
X			SHAMmem[ShamIndex++] = (UWORD)(
X				Palette[index].rgb_Red   << 8 |
X				Palette[index].rgb_Green << 4 |
X				Palette[index].rgb_Blue);
X
X		for (index2 = 0; index2 < (ISLACED ? 2 : 1); index2++) {
X			PreviousRed   = Palette[0].rgb_Red;
X			PreviousGreen = Palette[0].rgb_Green;
X			PreviousBlue  = Palette[0].rgb_Blue;
X
X			for (LineErr = x = 0; x < gdesc.gd_Width; x++) {
X				current = GetValue(x, y + index2);
X
X				CurrentRed   = GetRed(current);
X				CurrentGreen = GetGreen(current);
X				CurrentBlue  = GetBlue(current);
X
X				besterr = ErrBuf[current];
X				bestpal = PaletteBuf[current];
X
X				error = RGBdiff(
X					CurrentRed,
X					CurrentGreen,
X					CurrentBlue,
X					CurrentRed,
X					PreviousGreen,
X					PreviousBlue);
X
X				if (error < besterr) {
X					besterr = error;
X					bestpal = 16;
X				}
X
X				error = RGBdiff(
X					CurrentRed,
X					CurrentGreen,
X					CurrentBlue,
X					PreviousRed,
X					CurrentGreen,
X					PreviousBlue);
X
X				if (error < besterr) {
X					besterr = error;
X					bestpal = 17;
X				}
X
X				error = RGBdiff(
X					CurrentRed,
X					CurrentGreen,
X					CurrentBlue,
X					PreviousRed,
X					PreviousGreen,
X					CurrentBlue);
X
X				if (error < besterr) {
X					besterr = error;
X					bestpal = 18;
X				}
X
X				if (bestpal < 16) {
X					PutValue(x, y + index2, bestpal);
X
X					PreviousRed   = Palette[bestpal].rgb_Red;
X					PreviousGreen = Palette[bestpal].rgb_Green;
X					PreviousBlue  = Palette[bestpal].rgb_Blue;
X				} else if (bestpal == 16) {
X					PutValue(x, y + index2, CurrentRed | 0x20);
X
X					PreviousRed = CurrentRed;
X				} else if (bestpal == 17) {
X					PutValue(x, y + index2, CurrentGreen | 0x30);
X
X					PreviousGreen = CurrentGreen;
X				} else {
X					PutValue(x, y + index2, CurrentBlue | 0x10);
X
X					PreviousBlue = CurrentBlue;
X				}
X
X				LineErr += besterr;
X			}
X
X			TotalErr += LineErr;
X		}
X
X		if (DisplayCounts)
X			MyPrintf("\x1B[%sD\x1B[K", (ISLACED ? "34" : "27"));
X	}
X
X	{
X		ULONG	ErrPerPixel;
X		char	TextBuf[10];
X
X		ErrPerPixel = ((TotalErr / gdesc.gd_Height) * 1000) / gdesc.gd_Width;
X		MySPrintf(TextBuf, "%ld.%03ld", ErrPerPixel / 1000, ErrPerPixel % 1000);
X
X		MyPrintf("\x1B[%ldDTotal colour error = %ld, Mean per line = %ld, Per pixel = %s.\n",
X			(DisplayCounts ? 4 : 7), TotalErr, TotalErr / gdesc.gd_Height, TextBuf);
X	}
X}
END_OF_FILE
if test 5386 -ne `wc -c <'Sources/giftosham.c'`; then
    echo shar: \"'Sources/giftosham.c'\" unpacked with wrong size!
fi
# end of 'Sources/giftosham.c'
fi
if test -f 'Sources/largearrays.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Sources/largearrays.c'\"
else
echo shar: Extracting \"'Sources/largearrays.c'\" \(192 characters\)
sed "s/^X//" >'Sources/largearrays.c' <<'END_OF_FILE'
X/* Copyright 1990 by Christopher A. Wichura.
X   See file GIFMachine.doc for full description of rights.
X*/
X
X#include "GIFMachine.h"
X
XUBYTE PaletteBuf[MAXCOLOURS];
XULONG ColourBuf[MAXCOLOURS];
END_OF_FILE
if test 192 -ne `wc -c <'Sources/largearrays.c'`; then
    echo shar: \"'Sources/largearrays.c'\" unpacked with wrong size!
fi
# end of 'Sources/largearrays.c'
fi
if test -f 'Sources/lmkfile.uu' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Sources/lmkfile.uu'\"
else
echo shar: Extracting \"'Sources/lmkfile.uu'\" \(1456 characters\)
sed "s/^X//" >'Sources/lmkfile.uu' <<'END_OF_FILE'
Xbegin 666 lmkfile
XM(R!L;6MF:6QE(&9O<B!'249-86-H:6YE"B,@J2`Q.3DP(&)Y($-H<FES=&]P)
XM:&5R($$N(%=I8VAU<F$@*&-A=T!M:7)O8RYC:&DN:6PN=7,I"@I#4%4@/2`MH
XM;3`*1$5"54<@/2`M9#(*0T9,04=3(#T@)"A$14)51RD@)"A#4%4I("UV("UC1
XM<R`M<G(@+69I9"`M3PH*3D0@/2!.3T1%0E5'"DQ&3$%'4R`]("0H3D0I(%--N
XM04Q,0T]$12!334%,3$1!5$$*"DA$4B`]($=)1DUA8VAI;F4N:`H*3T)*4R`]6
XM('-T87)T=7`N;R!M86EN+F\@;7EM96TN;R!W87)N8VQI+F\@9&]I;6%G92YO4
XM(&5X=&5N<VEO;G,N;R!W<FET96EF9BYO(#(T=&\Q,BYO('-T<FEP8F]R9&5RC
XM+F\@>&-O;7`N;R!D;V9L:7`N;R!R9V)D:69F+F\@9VEF=&]S:&%M+F\@;7EP"
XM<FEN=&8N;R!L87)G96%R<F%Y<RYO(&%R9U]H96QP+F\*3$E"4R`]($Q)0CI,G
XM0U(N;&EB($Q)0CID96)U9RYL:6(@3$E".F%M:6=A,BXP+FQI8@H*+F,N;SH*"
XM"4Q#("0H0T9,04=3*2`D*@H*+F$N;SH*"4%332`M:4E.0TQ51$4Z("0J"@HN=
XM='AT+F\Z"@E46%1T;T]"2B`D*BYT>'0@)"HN;R!?)"H@0T]$10H*1TE&36%C2
XM:&EN93H@)"A/0DI3*0H)57!#5F5R<VEO;B!'249-86-H:6YE('9E<G-I;VXNA
XM;PH)0DQI;FL@/%=)5$@@/"`H1TE&36%C:&EN92YL;FLI"D923TT@)"A/0DI3-
XM*2!V97)S:6]N+F\*5$\@1TE&36%C:&EN90I,24(@)"A,24)3*0HD*$Q&3$%'@
XM4RD*/`H*;6%I;BYO.B!M86EN+F,@)"A(1%(I"@ID;VEM86=E+F\Z(&1O:6UA&
XM9V4N8R`D*$A$4BD*"F5X=&5N<VEO;G,N;SH@97AT96YS:6]N<RYC("0H2$126
XM*0H*=W)I=&5I9F8N;SH@=W)I=&5I9F8N8R`D*$A$4BD*"G-T<FEP8F]R9&5R\
XM+F\Z('-T<FEP8F]R9&5R+F,@)"A(1%(I"@IX8V]M<"YO.B!X8V]M<"YC("0H!
XM2$12*0H*9&]F;&EP+F\Z(&1O9FQI<"YC("0H2$12*0H*9VEF=&]S:&%M+F\Z_
XM(&=I9G1O<VAA;2YC("0H2$12*0H*<F=B9&EF9BYO.B!R9V)D:69F+F,@)"A(>
XM1%(I"@HR-'1O,3(N;SH@,C1T;S$R+F,@)"A(1%(I"@IL87)G96%R<F%Y<RYOT
X7.B!L87)G96%R<F%Y<RYC("0H2$12*0H@E
X``
Xend
Xsize 1013
END_OF_FILE
if test 1456 -ne `wc -c <'Sources/lmkfile.uu'`; then
    echo shar: \"'Sources/lmkfile.uu'\" unpacked with wrong size!
fi
# end of 'Sources/lmkfile.uu'
fi
if test -f 'Sources/mymem.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Sources/mymem.c'\"
else
echo shar: Extracting \"'Sources/mymem.c'\" \(1318 characters\)
sed "s/^X//" >'Sources/mymem.c' <<'END_OF_FILE'
X/* Copyright 1990 by Christopher A. Wichura.
X   See file GIFMachine.doc for full description of rights.
X*/
X
X#include <exec/types.h>
X#include <exec/lists.h>
X#include <exec/nodes.h>
X#include <exec/memory.h>
X
X#include <clib/alib_protos.h>
X
X#include <clib/exec_protos.h>
X#include <pragmas/exec_lib.h>
X
Xstruct MyMem {
X	struct MinNode mm_Node;
X	ULONG mm_Size;
X};
X
Xstruct MinList Mem[2];
XUWORD CurrentMem;
X
Xvoid InitMemory(void)
X{
X	NewList((struct List *)&Mem[0]);
X	NewList((struct List *)&Mem[1]);
X	CurrentMem = 0;
X}
X
Xchar *MyAlloc(ULONG size)
X{
X	register struct MyMem *theMemory;
X	register ULONG newsize;
X
X	newsize = size + sizeof(struct MyMem);
X
X	if (!(theMemory = (struct MyMem *)AllocMem(newsize, MEMF_PUBLIC|MEMF_CLEAR)))
X		return NULL;
X
X	AddTail((struct List *)&Mem[CurrentMem], (struct Node *)&theMemory->mm_Node);
X	theMemory->mm_Size = newsize;
X
X	return (char *)theMemory + sizeof(struct MyMem);
X}
X
Xvoid MyFree(char *MemPtr)
X{
X	register struct MyMem *theMemory;
X
X	theMemory = (struct MyMem *)(MemPtr - sizeof(struct MyMem));
X
X	Remove((struct Node *)&theMemory->mm_Node);
X	FreeMem((char *)theMemory, theMemory->mm_Size);
X}
X
Xvoid FreeAll(UWORD memlist)
X{
X	register struct MyMem *theMemory;
X
X	while (theMemory = (struct MyMem *)RemTail((struct List *)&Mem[memlist]))
X		FreeMem((char *)theMemory, theMemory->mm_Size);
X}
END_OF_FILE
if test 1318 -ne `wc -c <'Sources/mymem.c'`; then
    echo shar: \"'Sources/mymem.c'\" unpacked with wrong size!
fi
# end of 'Sources/mymem.c'
fi
if test -f 'Sources/myprintf.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Sources/myprintf.c'\"
else
echo shar: Extracting \"'Sources/myprintf.c'\" \(783 characters\)
sed "s/^X//" >'Sources/myprintf.c' <<'END_OF_FILE'
X#include <clib/dos_protos.h>
Xextern struct DosLibrary *DOSBase;
X#include <pragmas/dos_lib.h>
X
X#include <stdarg.h>
X
Xvoid RawDoFmt(char *, APTR, void(*)(), APTR);
X#pragma syscall RawDoFmt 20a ba9804
X
Xvoid __stdargs MyPrintf(char *fmt, ...)
X{
X	va_list args;
X
X	va_start(args, fmt);
X	VPrintf((UBYTE *)fmt, (LONG *)args);
X	Flush(Output());
X	va_end(args);
X}
X
Xstatic void __regargs MySPrintfSupp(char);
X
Xvoid __stdargs MySPrintf(char *buf, char *fmt, ...)
X{
X	va_list args;
X
X	va_start(args, fmt);
X	RawDoFmt(fmt, (APTR)args, MySPrintfSupp, (APTR)buf)
X	va_end(args);
X}
X
Xextern long __builtin_getreg(int);
Xextern void __builtin_putreg(int, char *);
X
Xstatic void __regargs MySPrintfSupp(char Char)
X{
X	char *ptr;
X
X	ptr = (char *)__builtin_getreg(11);
X	*ptr++ = Char;
X	__builtin_putreg(11, ptr);
X}
END_OF_FILE
if test 783 -ne `wc -c <'Sources/myprintf.c'`; then
    echo shar: \"'Sources/myprintf.c'\" unpacked with wrong size!
fi
# end of 'Sources/myprintf.c'
fi
if test -f 'Sources/rgbdiff.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Sources/rgbdiff.c'\"
else
echo shar: Extracting \"'Sources/rgbdiff.c'\" \(876 characters\)
sed "s/^X//" >'Sources/rgbdiff.c' <<'END_OF_FILE'
X/* Note:  this colour comparison routine was snitched from HamSharp.
X
X   This has the side effect of allowing one to compare colour errors gotten
X   with GIFMachine to those gotten with (S)HamSharp.
X*/
X
X#include "GIFMachine.h"
X
Xstatic UBYTE Diff[16][16];
Xstatic UBYTE Intensity[16][16][16];
X
Xextern struct Library *MathIeeeDoubBasBase;
X
Xvoid InitDiff(void)
X{
X	register int i;
X	register int j;
X	register int r;
X	register int g;
X	register int b;
X
X	for (i = 0; i < 16; i++)
X		for (j = 0; j < 16; j++)
X			Diff[i][j] = (i - j) * (i - j);
X
X	for (r = 0; r < 16; r++)
X		for (g = 0; g < 16; g++)
X			for (b = 0; b < 16; b++)
X				Intensity[r][g][b] = (int)(.299 * r + .587 * g + .114 * b);
X}
X
XULONG RGBdiff(UBYTE r1, UBYTE g1, UBYTE b1, UBYTE r2, UBYTE g2, UBYTE b2)
X{
X	return (ULONG)(Diff[Intensity[r1][g1][b1]][Intensity[r2][g2][b2]] +
X		Diff[r1][r2] + Diff[g1][g2] + Diff[b1][b2]);
X}
END_OF_FILE
if test 876 -ne `wc -c <'Sources/rgbdiff.c'`; then
    echo shar: \"'Sources/rgbdiff.c'\" unpacked with wrong size!
fi
# end of 'Sources/rgbdiff.c'
fi
if test -f 'Sources/startup.a' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Sources/startup.a'\"
else
echo shar: Extracting \"'Sources/startup.a'\" \(4359 characters\)
sed "s/^X//" >'Sources/startup.a' <<'END_OF_FILE'
X INCLUDE "exec/types.i"
X INCLUDE "exec/execbase.i"
X INCLUDE "exec/memory.i"
X INCLUDE "libraries/dosextens.i"
X
X XREF @main
X
X XREF _LVOOpenLibrary
X XREF _LVOOldOpenLibrary
X XREF _LVOCloseLibrary
X XREF _LVOSetSignal
X XREF _LVOForbid
X XREF _LVOWaitPort
X XREF _LVOGetMsg
X XREF _LVOReplyMsg
X XREF _LVOSetIoErr
X XREF _LVOAllocVec
X XREF _LVOFreeVec
X XREF _LVOOutput
X XREF _LVOWrite
X
X XREF _LinkerDB
X XREF __BSSBAS
X XREF __BSSLEN
X XREF _RESLEN
X XREF _RESBASE
X XREF _NEWDATAL
X
X XREF _AbsExecBase
X
XLIBCALL	MACRO
X	jsr _LVO\1(a6)
X	ENDM
X
X  SECTION StartCode,CODE
X
Xinit:
X	movem.l	d0/a0,-(sp)
X
X; first off we will check for our workbench message, if any.  we will store
X; the pointer to it in d7 temporarily until we actually copy the data
X; segment over.  otherwise we wouldn't be residentiable.
X
X	moveq	#0,d7		; clear out longword
X
X; get address of our task
X	move.l	_AbsExecBase.W,a6
X	move.l	ThisTask(a6),a3
X
X; clear any pending signals
X	moveq	#0,d0
X	move.l	#$00003000,d1
X	LIBCALL	SetSignal
X
X; check for workbench message
X	tst.l	pr_CLI(a3)
X	bne.s	FromCLI
X
X	lea	pr_MsgPort(a3),a0
X	LIBCALL	WaitPort
X	lea	pr_MsgPort(a3),a0
X	LIBCALL	GetMsg
X	move.l	d0,d7
X
XFromCLI:
X	lea	DOSlib(pc),a1
X	moveq	#37,d0
X	LIBCALL	OpenLibrary
X	tst.l	d0
X	bne.s	DoMain
X
X	lea	DOSlib(pc),a1
X	LIBCALL	OldOpenLibrary
X	tst.l	d0
X	beq.s	bomb
X
X	move.l	d0,a6
X	LIBCALL	Output
X	move.l	d0,d1
X	beq.s	bomb
X
X	lea	Msg1(pc),a0
X	move.l	a0,d2
X	moveq	#Msg1Len,d3
X	LIBCALL	Write
X
X	move.l	a6,a1
X	move.l	_AbsExecBase.W,a6
X	LIBCALL	CloseLibrary
X
Xbomb:	addq.l	#8,sp		; pop d0/a0 off stack
X
X	move.l	d7,d0		; check if we have a workbench startup
X	bsr	ReplyWB		; message and reply it if so
X
X	moveq	#0,d0
X	rts
X
XDoMain:
X	move.l	d0,-(sp)
X
X	lea	_LinkerDB,a4
X	sub.l	#_RESBASE,a4
X
X; get mem to hold data and bss stuff
X	move.l	#_RESLEN,d0
X	move.l	#MEMF_PUBLIC+MEMF_CLEAR,d1
X	LIBCALL	AllocVec
X	tst.l	d0
X	bne.s	gotmem
X
X; no mem available so bomb out
X	move.l	d7,d0		; check for wb startup message and reply
X	bsr	ReplyWB		; it if present
X
X	move.l	(sp)+,a6	; get dos base
X	addq.l	#8,sp		; pop d0/a0 off of stack
X
X	moveq	#ERROR_NO_FREE_STORE,d1
X	LIBCALL	SetIoErr
X
X	move.l	a6,a1
X	move.l	_AbsExecBase.W,a6
X	LIBCALL	CloseLibrary
X
X	moveq	#20,d0
X	rts
X
X; get ready to copy data over into freshly alloced data area
Xgotmem:	move.l	d0,a0
X	move.l	d0,a2
X
X	move.l	d0,a1
X	move.l	#_NEWDATAL,d0
Xcpy:	move.l	(a4)+,(a0)+
X	subq.l	#1,d0
X	bne.s	cpy
X
X; now do the relocs for resident data
X	move.l	(a4)+,d0
Xreloc:	beq.s	nreloc
X	move.l	a1,a0
X	add.l	(a4)+,a0
X	add.l	(a0),a2
X	move.l	a2,(a0)
X	move.l	a1,a2
X	subq.l	#1,d0
X	bra.s	reloc
X
Xnreloc:	move.l	a1,a4
X	add.l	#_RESBASE,a4
X
X; stash some important junk away
X	move.l	(sp)+,_DOSBase(a4)
X	move.l	d7,_WBenchMsg(a4)
X
X	move.l	_AbsExecBase.W,a6
X	move.l	a6,_SysBase(a4)
X
X; call our main program.  we call the main routine with the following
X; arguments:
X;
X;   d0 = length of command line
X;   a0 = pointer to command line
X;   a1 = pointer to workbench startup message (or NULL)
X
X	movem.l	(sp)+,d0/a0
X	movem.l	sp,__StackPtr(a4)
X
X	movea.l	d7,a1
X	jsr	@main
X	moveq	#0,d0
X	bra.s	Exit
X
X XDEF _XCEXIT
X_XCEXIT:
X	move.l	4(sp),d0
X XDEF @XCEXIT
X@XCEXIT:
X
XExit:	move.l	d0,d3			; save return code in safe place
X
X	move.l	_WBenchMsg(a4),d0	; check if we need to reply the
X	bsr	ReplyWB			; workbench startup message
X
X	move.l	_DOSBase(a4),a6
X	moveq	#0,d1
X	LIBCALL	SetIoErr
X
X	move.l	a6,a1
X	move.l	_AbsExecBase.W,a6
X	LIBCALL	CloseLibrary
X
X	movea.l	__StackPtr(a4),sp
X
X	move.l	a4,a1
X	sub.l	#_RESBASE,a1
X	LIBCALL	FreeVec
X
X	move.l	d3,d0			; restore return code
X	rts
X
X; this subroutine is called when we try to check if we need to reply
X; the workbench message.  This is done because we do this in more than
X; one place.
X
XReplyWB:
X	move.l	d0,d2
X	beq.s	1$
X
X	move.l	_AbsExecBase.W,a6
X	LIBCALL	Forbid
X	movea.l	d2,a1
X	LIBCALL	ReplyMsg
X
X1$	rts
X
X; ---- This is the data we need for the startup module.  we don't put it in
X;      a data segment, though, or it would end up being copied over when we
X;      clone the data hunk and this stuff isn't needed anywhere else...
X
XDOSlib	dc.b "dos.library",0
X
XMsg1	dc.b "You need KickStart 2.0 or greater.",13
XMsg1Len	EQU *-Msg1
X	ds.w 0
X
X; ---- This is the BBS segment that holds various startup junk for us.
X
X   SECTION __MERGED,BSS
X
X XDEF _DOSBase
X XDEF _SysBase
X XDEF _IntuitionBase
X XDEF _WBenchMsg
X XDEF __StackPtr
X
X_DOSBase	ds.b 4
X_SysBase	ds.b 4
X_IntuitionBase	ds.b 4
X_WBenchMsg	ds.b 4
X__StackPtr	ds.b 4
X
X   END
END_OF_FILE
if test 4359 -ne `wc -c <'Sources/startup.a'`; then
    echo shar: \"'Sources/startup.a'\" unpacked with wrong size!
fi
# end of 'Sources/startup.a'
fi
if test -f 'Sources/stripborder.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Sources/stripborder.c'\"
else
echo shar: Extracting \"'Sources/stripborder.c'\" \(3390 characters\)
sed "s/^X//" >'Sources/stripborder.c' <<'END_OF_FILE'
X/* Copyright 1990 by Christopher A. Wichura.
X   See file GIFMachine.doc for full description of rights.
X*/
X
X#include "GIFMachine.h"
X
Xextern struct GIFdescriptor gdesc;
XEXTERNBITPLANE;
X
Xextern char *AbortMsg;
X
Xextern int NoBorderLineThresh;
X
X#define BorderCheck(a, b) ((BitPlane[b][a].rgb_Red   != BorderCol.rgb_Red) || \
X			   (BitPlane[b][a].rgb_Green != BorderCol.rgb_Green) || \
X			   (BitPlane[b][a].rgb_Blue  != BorderCol.rgb_Blue))
X
Xvoid StripBorder(void)
X{
X	register UWORD x;
X	register UWORD y;
X	register int thresh;
X	register BOOL breakout;
X	LONG LeftEdge, TopEdge;
X	LONG Width, Height;
X	UWORD OrigWidth, OrigHeight;
X	int WidthThresh, HeightThresh;
X	int Corner;
X
X	struct RGB BorderCol;
X
X	PutStr("...Removing border.\n");
X
X	OrigWidth = gdesc.gd_Width;
X	OrigHeight = gdesc.gd_Height;
X
X	for (Corner = 0; Corner < 4; Corner++) {
X		x = (Corner & 1) ? (gdesc.gd_Width - 1) : 0;
X		y = (Corner & 2) ? (gdesc.gd_Height - 1) : 0;
X
X		BorderCol = BitPlane[y][x];
X
X		WidthThresh  = NoBorderLineThresh * gdesc.gd_Width  / 100;
X		HeightThresh = NoBorderLineThresh * gdesc.gd_Height / 100;
X
X		for (breakout = y = 0; (y < gdesc.gd_Height) && !breakout; y++) {
X			for (thresh = x = 0; x < gdesc.gd_Width; x++)
X				if (BorderCheck(x, y))
X					if (++thresh > WidthThresh) {
X						breakout = TRUE;
X						break;
X					}
X
X			if (SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
X				PutStr(AbortMsg);
X				MyExit(ABORTEXITVAL);
X			}
X		}
X
X		TopEdge = y - 1;
X
X		for (breakout = 0, y = gdesc.gd_Height - 1; (y > 0) && !breakout; y--) {
X			for (thresh = x = 0; x < gdesc.gd_Width; x++)
X				if (BorderCheck(x, y))
X					if (++thresh > WidthThresh) {
X						breakout = TRUE;
X						break;
X					}
X
X			if (SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
X				PutStr(AbortMsg);
X				MyExit(ABORTEXITVAL);
X			}
X		}
X
X		Height = y - TopEdge + 2;
X
X		for (breakout = x = 0; (x < gdesc.gd_Width) && !breakout; x++) {
X			for (thresh = y = 0; y < gdesc.gd_Height; y++)
X				if (BorderCheck(x, y))
X					if (++thresh > HeightThresh) {
X						breakout = TRUE;
X						break;
X					}
X
X			if (SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
X				PutStr(AbortMsg);
X				MyExit(ABORTEXITVAL);
X			}
X		}
X
X		LeftEdge = x - 1;
X
X		for (breakout = 0, x = gdesc.gd_Width - 1; (x > 0) && !breakout; x--) {
X			for (thresh = y = 0; y < gdesc.gd_Height; y++)
X				if (BorderCheck(x, y))
X					if (++thresh > HeightThresh) {
X						breakout = TRUE;
X						break;
X					}
X
X			if (SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
X				PutStr(AbortMsg);
X				MyExit(ABORTEXITVAL);
X			}
X		}
X
X		Width = x - LeftEdge + 2;
X
X		if ((Width != gdesc.gd_Width) || (Height != gdesc.gd_Height)) {
X			if (Width < 5 || Height < 5) {
X				PutStr("......Too much of picture would be removed.  Not modified.\n");
X				return;
X			}
X
X			for (y = 0; y < Height; y++) {
X				for (x = 0; x < Width; x++)
X					BitPlane[y][x] = BitPlane[TopEdge + y][LeftEdge + x];
X
X				BitPlane[y][x].rgb_Red   =
X				BitPlane[y][x].rgb_Green =
X				BitPlane[y][x].rgb_Blue  = 0;
X
X				if (SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
X					PutStr(AbortMsg);
X					MyExit(ABORTEXITVAL);
X				}
X			}
X
X			gdesc.gd_Width = Width;
X			gdesc.gd_Height = Height;
X		}
X	}
X
X	if ((gdesc.gd_Width != OrigWidth) || (gdesc.gd_Height != OrigHeight)) {
X		if (gdesc.gd_Width & 1)
X			gdesc.gd_Width++;
X
X		MyPrintf("......New width = %ld, New height = %ld\n",
X			gdesc.gd_Width, gdesc.gd_Height);
X	}
X}
END_OF_FILE
if test 3390 -ne `wc -c <'Sources/stripborder.c'`; then
    echo shar: \"'Sources/stripborder.c'\" unpacked with wrong size!
fi
# end of 'Sources/stripborder.c'
fi
if test -f 'Sources/version.o.uu' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Sources/version.o.uu'\"
else
echo shar: Extracting \"'Sources/version.o.uu'\" \(217 characters\)
sed "s/^X//" >'Sources/version.o.uu' <<'END_OF_FILE'
Xbegin 666 version.o
XM```#YP````````/I````"P````(```"))%9%4CH@1TE&36%C:&EN92`R+C$S&
XM-R`H,C8N."XY,2D````````#[P$```)?5F5R<VEO;@`````!```#7U9E<G-IT
XF;VY)1```````&0$```-?4F5V:7-I;VX````````$`````````_(#Q
X``
Xend
Xsize 128
END_OF_FILE
if test 217 -ne `wc -c <'Sources/version.o.uu'`; then
    echo shar: \"'Sources/version.o.uu'\" unpacked with wrong size!
fi
# end of 'Sources/version.o.uu'
fi
if test -f 'Sources/warncli.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Sources/warncli.c'\"
else
echo shar: Extracting \"'Sources/warncli.c'\" \(1824 characters\)
sed "s/^X//" >'Sources/warncli.c' <<'END_OF_FILE'
X/* Copyright 1990 by Christopher A. Wichura.
X   See file GIFMachine.doc for full description of rights.
X*/
X
X#include <exec/types.h>
X#include <intuition/intuition.h>
X#include <graphics/text.h>
X
X#include <clib/exec_protos.h>
X#include <pragmas/exec_lib.h>
X
X#include <clib/intuition_protos.h>
Xextern struct IntuitionBase *IntuitionBase;
X#include <pragmas/intuition_lib.h>
X
Xstatic struct TextAttr TOPAZ60 = {"topaz.font", TOPAZ_SIXTY,
X	FS_NORMAL, FPF_ROMFONT};
X
Xstatic struct IntuiText BodyText2 = {-1, -1,    /* pen numbers */
X                             0,             /* draw mode */
X                             9,14,          /* starting offsets */
X                             &TOPAZ60,      /* text attribute pointer */
X                             "for CLI use only!",
X                             NULL };
X
Xstatic struct IntuiText BodyText1 = {-1,-1,      /* pen numbers */
X                             0,             /* draw mode */
X                             29,4,          /* starting offsets */
X                             &TOPAZ60,      /* text attribute pointer */
X                             "GIFMachine is",
X                             &BodyText2 };
X
Xstatic struct IntuiText ContinueText = {-1,-1,  /* pen numbers */
X                             0,             /* draw mode */
X                             4,4,           /* starting offsets */
X                             &TOPAZ60,      /* text attribute pointer */
X                             "CONTINUE",
X                             NULL };
X
Xvoid WarnMustUseCLI(void)
X{
X	BOOL	OpenedIntui;
X
X	if (IntuitionBase)
X		OpenedIntui = FALSE;
X	else {
X		if (!(IntuitionBase = OpenLibrary("intuition.library", 0)))
X			return;
X		OpenedIntui = TRUE;
X	}
X
X	AutoRequest(NULL,&BodyText1,NULL,&ContinueText,0,0,220,64);
X
X	if (OpenedIntui)
X		CloseLibrary(IntuitionBase);
X}
END_OF_FILE
if test 1824 -ne `wc -c <'Sources/warncli.c'`; then
    echo shar: \"'Sources/warncli.c'\" unpacked with wrong size!
fi
# end of 'Sources/warncli.c'
fi
if test -f 'Sources/xcomp.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Sources/xcomp.c'\"
else
echo shar: Extracting \"'Sources/xcomp.c'\" \(2328 characters\)
sed "s/^X//" >'Sources/xcomp.c' <<'END_OF_FILE'
X/* Copyright 1990 by Christopher A. Wichura.
X   See file GIFMachine.doc for full description of rights.
X*/
X
X/* This function will take the gif screen we have read in and scale it to
X   one half of its previous X size.
X
X   What we do here is just a step above skipping every other pixel (like
X   most routines I have seen do).  While we still put emphasis on the
X   even pixels, we at least take account of the odds next to them by
X   using a weighted average.
X
X   This method is by no means the best way to do this.  If anyone wants
X   to build a smarter one I would be very interested in seeing it.
X*/
X
X#include "GIFMachine.h"
X
Xextern struct GIFdescriptor gdesc;
XEXTERNBITPLANE;
X
Xextern char *AbortMsg;
X
Xextern BOOL DisplayCounts;
X
Xvoid DoXComp(void)
X{
X	register UWORD x1;
X	register UWORD x2;
X	register UWORD y;
X	register UWORD num;
X	UWORD ColBuf[3];
X	UWORD NewWidth;
X
X	NewWidth = gdesc.gd_Width >> 1;
X	if (NewWidth & 1)
X		NewWidth++;
X
X	MyPrintf("...Compressing width to %ld.\n......", NewWidth);
X	if (DisplayCounts)
X		PutStr("Line ");
X	else
X		PutStr("Working");
X	Flush(Output());
X
X        for (y = 0; y < gdesc.gd_Height; y++) {
X		if (DisplayCounts)
X			MyPrintf("%5ld", y);
X
X		for (x1 = x2 = 0; x2 < gdesc.gd_Width; x1++, x2 += 2) {
X			num = 4;
X
X			ColBuf[0] = BitPlane[y][x2].rgb_Red * 4;
X			ColBuf[1] = BitPlane[y][x2].rgb_Green * 4;
X			ColBuf[2] = BitPlane[y][x2].rgb_Blue * 4;
X
X			if (x2 > 1) {
X				num += 2;
X
X				ColBuf[0] += BitPlane[y][x2 - 1].rgb_Red * 2;
X				ColBuf[1] += BitPlane[y][x2 - 1].rgb_Green * 2;
X				ColBuf[2] += BitPlane[y][x2 - 1].rgb_Blue * 2;
X			}
X
X			if (x2 + 1 < gdesc.gd_Width) {
X				num += 2;
X
X				ColBuf[0] += BitPlane[y][x2 + 1].rgb_Red * 2;
X				ColBuf[1] += BitPlane[y][x2 + 1].rgb_Green * 2;
X				ColBuf[2] += BitPlane[y][x2 + 1].rgb_Blue * 2;
X			}
X
X			BitPlane[y][x1].rgb_Red   = ((ColBuf[0] + num / 2) / num);
X			BitPlane[y][x1].rgb_Green = ((ColBuf[1] + num / 2) / num);
X			BitPlane[y][x1].rgb_Blue  = ((ColBuf[2] + num / 2) / num);
X		}
X
X		BitPlane[y][x1].rgb_Red = BitPlane[y][x1].rgb_Green = BitPlane[y][x1].rgb_Blue = 0;
X
X		if (SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
X			MyPrintf("\n%s", AbortMsg);
X			MyExit(ABORTEXITVAL);
X		}
X
X		if (DisplayCounts)
X			PutStr("\x1B[5D");
X	}
X
X	MyPrintf("\x1B[%ldDCompressed.      \n", (DisplayCounts ? 5 : 7));
X
X	gdesc.gd_Width = NewWidth;
X}
END_OF_FILE
if test 2328 -ne `wc -c <'Sources/xcomp.c'`; then
    echo shar: \"'Sources/xcomp.c'\" unpacked with wrong size!
fi
# end of 'Sources/xcomp.c'
fi
echo shar: End of archive 1 \(of 3\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 3 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 3 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Mail submissions (sources or binaries) to <amiga@uunet.uu.net>.
Mail comments to the moderator at <amiga-request@uunet.uu.net>.
Post requests for sources, and general discussion to comp.sys.amiga.misc.
