/***************************************************************************** * "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 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); }