Category : C Source Code
Archive   : GIF_LIB.ZIP
Filename : GIFBG.C

 
Output of file : GIFBG.C contained in archive : GIF_LIB.ZIP
/*****************************************************************************
* "Gif-Lib" - Yet another gif library. *
* *
* Written by: Gershon Elber IBM PC Ver 0.1, Jul. 1989 *
******************************************************************************
* Program to generate back ground image that can be used to replace constant *
* background. *
* Options: *
* -d direction : set direction image should increase intensity. *
* -l levels : number of color levels. *
* -c r g b : colors of the back ground. *
* -m min : minimin intensity in percent. *
* -M max : maximum intensity in percent. *
* -s width height : size of image to create. *
* -h : on line help. *
******************************************************************************
* History: *
* 9 Jul 89 - Version 1.0 by Gershon Elber. *
*****************************************************************************/

#include
#include
#include
#include
#include
#include "gif_lib.h"
#include "getarg.h"

#define PROGRAM_NAME "GifBG"
#define VERSION "á Version 1.0, "

#define DEFAULT_WIDTH 640
#define DEFAULT_HEIGHT 350

#define DEFAULT_COLOR_RED 0
#define DEFAULT_COLOR_GREEN 0
#define DEFAULT_COLOR_BLUE 255

#define DEFAULT_MIN_INTENSITY 10 /* In percent */
#define DEFAULT_MAX_INTENSITY 100

#define DEFAULT_NUM_LEVELS 16 /* Number of colors to gen the image */

enum { /* Direction the levels can be changed: */
DIR_NONE,
DIR_TOP,
DIR_TOP_RIGHT,
DIR_RIGHT,
DIR_BOT_RIGHT,
DIR_BOT,
DIR_BOT_LEFT,
DIR_LEFT,
DIR_TOP_LEFT
};

#define DEFAULT_DIR "T" /* TOP (North) direction */

extern unsigned int
_stklen = 16384; /* Increase default stack size */

static char
*VersionStr =
PROGRAM_NAME
" IBMPC "
VERSION
" Gershon Elber, "
__DATE__ ", " __TIME__ "\n"
"(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
static char
*CtrlStr =
PROGRAM_NAME
" d%-Dir!s l%-#Lvls!d c%-R|G|B!d!d!d m%-MinI!d M%-MaxI!d s%-W|H!d!d h%-";
static char
*ProgramName;
static int
MaximumIntensity = DEFAULT_MAX_INTENSITY, /* In percent */
MinimumIntensity = DEFAULT_MIN_INTENSITY,
NumLevels = DEFAULT_NUM_LEVELS,
ImageWidth = DEFAULT_WIDTH,
ImageHeight = DEFAULT_HEIGHT,
Direction;
static unsigned int
RedColor = DEFAULT_COLOR_RED,
GreenColor = DEFAULT_COLOR_GREEN,
BlueColor = DEFAULT_COLOR_BLUE;

static void QuitGifError(GifFileType *GifFile);

/******************************************************************************
* Interpret the command line and scan the given GIF file. *
******************************************************************************/
void main(int argc, char **argv)
{
unsigned int Ratio;
int i, j, l, LevelHeight, LevelWidth, Error, LogNumLevels, FlipDir,
Accumulator, StartX, StepX, Count = 0, DoAllMaximum = FALSE,
DirectionFlag = FALSE, LevelsFlag = FALSE, ColorFlag = FALSE,
MinFlag = FALSE, MaxFlag = FALSE, SizeFlag = FALSE, HelpFlag = FALSE;
PixelType Color;
char *DirectionStr = DEFAULT_DIR;
RowType Line;
GifColorType *ColorMap;
GifFileType *GifFile;

if (strlen(ProgramName = argv[0]) == 0) /* DOS 3.x only! */
ProgramName = PROGRAM_NAME; /* Do something reasonable for 2.x */

if ((Error = GAGetArgs(argc, argv, CtrlStr,
&DirectionFlag, &DirectionStr, &LevelsFlag, &NumLevels,
&ColorFlag, &RedColor, &GreenColor, &BlueColor,
&MinFlag, &MinimumIntensity, &MaxFlag, &MaximumIntensity,
&SizeFlag, &ImageWidth, &ImageHeight,
&HelpFlag)) != FALSE) {
GAPrintErrMsg(Error);
GAPrintHowTo(CtrlStr);
exit(1);
}

if (HelpFlag) {
fprintf(stderr, VersionStr);
GAPrintHowTo(CtrlStr);
exit(0);
}

/* Make sure intensities are in the right range: */
if (MinimumIntensity < 0 || MinimumIntensity > 100 ||
MaximumIntensity < 0 || MaximumIntensity > 100)
EXIT("Intensities (-m or -M options) are not in [0..100] range (percent)\n");

/* Convert DirectionStr to our local representation: */
Direction = DIR_NONE;
FlipDir = FALSE;
strupr(DirectionStr);
switch(DirectionStr[0]) {
case 'T': /* Top or North */
case 'N':
if (strlen(DirectionStr) < 2) Direction = DIR_TOP;
else
switch(DirectionStr[1]) {
case 'R':
case 'E':
Direction = DIR_TOP_RIGHT;
break;
case 'L':
case 'W':
Direction = DIR_TOP_LEFT;
FlipDir = TRUE;
break;
}
break;
case 'R': /* Right or East */
case 'E':
Direction = DIR_RIGHT;
break;
case 'B': /* Bottom or South */
case 'S':
if (strlen(DirectionStr) < 2) {
Direction = DIR_BOT;
FlipDir = TRUE;
}
else
switch(DirectionStr[1]) {
case 'R':
case 'E':
Direction = DIR_BOT_RIGHT;
break;
case 'L':
case 'W':
Direction = DIR_BOT_LEFT;
FlipDir = TRUE;
break;
}
break;
case 'L': /* Left or West */
case 'W':
Direction = DIR_LEFT;
FlipDir = TRUE;
break;
}
if (Direction == DIR_NONE)
EXIT("Direction requested (-d option) is wierd!\n");

/* We are going to handle only TOP, TOP_RIGHT, RIGHT, BOT_RIGHT so flip */
/* the complement cases (TOP <-> BOT for example) by flipping the */
/* Color i with color (NumLevels - i - 1). */
if (FlipDir) {
switch (Direction) {
case DIR_BOT:
Direction = DIR_TOP;
break;
case DIR_BOT_LEFT:
Direction = DIR_TOP_RIGHT;
break;
case DIR_LEFT:
Direction = DIR_RIGHT;
break;
case DIR_TOP_LEFT:
Direction = DIR_BOT_RIGHT;
break;
}
}

/* If binary mask is requested (special case): */
if (MinimumIntensity == 100 && MaximumIntensity == 100 && NumLevels == 2) {
MinimumIntensity = 0;
DoAllMaximum = TRUE;
Direction = DIR_RIGHT;
}

/* Make sure colors are in the right range: */
if (RedColor > 255 || GreenColor > 255 || BlueColor > 255)
EXIT("Colors are not in the ragne [0..255]\n");

/* Make sure the number of levels is power of 2 (up to 8 bits per pixel) */
for (i=1; i<8; i++) if (NumLevels == (1 << i)) break;
if (i == 8) EXIT("#Lvls (-l option) is not power of 2\n");
LogNumLevels = i;

/* Open stdout for the output file: */
if ((GifFile = EGifOpenFileHandle(1)) == NULL)
QuitGifError(GifFile);

/* Dump out screen description with given size and generated color map: */
if ((ColorMap = (GifColorType *) malloc(NumLevels * sizeof(GifColorType)))
== NULL) EXIT("Failed to allocate memory required, aborted");

for (i=1; i<=NumLevels; i++) {
/* Ratio will be in the range of 0..100 for required intensity: */
Ratio = (MaximumIntensity * (i * (256 / NumLevels)) +
MinimumIntensity * ((NumLevels - i) * (256 / NumLevels))) /
256;
ColorMap[i-1].Red = (RedColor * Ratio) / 100;
ColorMap[i-1].Green = (GreenColor * Ratio) / 100;
ColorMap[i-1].Blue = (BlueColor * Ratio) / 100;
}
if (EGifPutScreenDesc(GifFile,
ImageWidth, ImageHeight, LogNumLevels, 0, LogNumLevels, ColorMap)
== ERROR)
QuitGifError(GifFile);

/* Dump out the image descriptor: */
if (EGifPutImageDesc(GifFile,
0, 0, ImageWidth, ImageHeight, FALSE, LogNumLevels, NULL) == ERROR)
QuitGifError(GifFile);

fprintf(stderr, "\n%s: Image 1 at (%d, %d) [%dx%d]: ",
ProgramName, GifFile -> ILeft, GifFile -> ITop,
GifFile -> IWidth, GifFile -> IHeight);

/* Allocate one scan line twice as big as image is as we are going to */
/* shift along it, while we dump the scan lines: */
if ((Line = (RowType) malloc(sizeof(PixelType) * ImageWidth * 2)) == NULL)
EXIT("Failed to allocate memory required, aborted");

if (Direction == DIR_TOP) {
/* We must evaluate the line each time level is changing: */
LevelHeight = ImageHeight / NumLevels;
for (Color=NumLevels, i=l=0; i if (i == l) {
/* Time to update the line to next color level: */
if (Color != 0) Color--;
for (j=0; j Line[j] = (FlipDir ? NumLevels - Color - 1 : Color);
l += LevelHeight;
}
if (EGifPutLine(GifFile, Line, ImageWidth) == ERROR)
QuitGifError(GifFile);
fprintf(stderr, "\b\b\b\b%-4d", Count++);
}
}
else if (Direction == DIR_RIGHT) {
/* We pre-prepare the scan lines as going from color zero to maximum */
/* color and dump the same scan line Height times: */
/* Note this case should handle the Boolean Mask special case. */
LevelWidth = ImageWidth / NumLevels;
if (DoAllMaximum) {
/* Special case - do all in maximum color: */
for (i=0; i }
else {
for (Color=i=0, l=LevelWidth; i if (l == 0) {
l = LevelWidth;
if (Color < NumLevels - 1) Color++;
}
Line[i] = (FlipDir ? NumLevels - Color - 1 : Color);
}
}

for (i=0; i if (EGifPutLine(GifFile, Line, ImageWidth) == ERROR)
QuitGifError(GifFile);
fprintf(stderr, "\b\b\b\b%-4d", Count++);
}
}
else {
/* We are in one of the TOP_RIGHT, BOT_RIGHT cases: we will */
/* initialize the Line with its double ImageWidth length from the */
/* minimum intensity to the maximum intensity and shift along it */
/* while we go along the image height. */
LevelWidth = ImageWidth * 2 / NumLevels;
for (Color=i=0, l=LevelWidth; i if (l == 0) {
l = LevelWidth;
if (Color < NumLevels - 1) Color++;
}
Line[i] = (FlipDir ? NumLevels - Color - 1 : Color);
}
/* We need to implement a DDA to know how much to shift Line while */
/* we go down along image height. we set the parameters for it now: */
Accumulator = 0;
switch(Direction) {
case DIR_TOP_RIGHT:
StartX = ImageWidth;
StepX = -1;
break;
case DIR_BOT_RIGHT:
StartX = 0;
StepX = 1;
break;
}

/* Time to dump information out: */
for (i=0; i if (EGifPutLine(GifFile, &Line[StartX], ImageWidth) == ERROR)
QuitGifError(GifFile);
fprintf(stderr, "\b\b\b\b%-4d", Count++);
if ((Accumulator += ImageWidth) > ImageHeight) {
while (Accumulator > ImageHeight) {
Accumulator -= ImageHeight;
StartX += StepX;
}
if (Direction < 0) Direction = 0;
if (Direction > ImageWidth) Direction = ImageWidth;
}
}
}

if (EGifCloseFile(GifFile) == ERROR)
QuitGifError(GifFile);
}

/******************************************************************************
* Close output file (if open), and exit. *
******************************************************************************/
static void QuitGifError(GifFileType *GifFile)
{
PrintGifError();
if (GifFile != NULL) DGifCloseFile(GifFile);
exit(1);
}


  3 Responses to “Category : C Source Code
Archive   : GIF_LIB.ZIP
Filename : GIFBG.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/