home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
- * Routines to prpepare the color table for the given scene. Each color *
- * get equal share in the map table, so its modules does: *
- * 1. Scans all objects and retrieve all possible colors. *
- * 2. Create a color map table, of the specified size (in ShadingInfo global *
- * structure) and interpolate intensity levels for each color into it. *
- * 3. Update the objects for their index into the color map. *
- * *
- * Written by: Gershon Elber Ver 2.0, Mar. 1990 *
- *****************************************************************************/
-
- #ifdef __MSDOS__
- #include <stdlib.h>
- #endif /* __MSDOS__ */
-
- #include <math.h>
- #include <stdio.h>
- #include <time.h>
- #include "program.h"
- #include "parser.h"
- #include "gif_lib.h"
-
- /* The colors can be specified as indices in which we must convert to RGB: */
- /* We uses the EGA convension (see also TC 2.0 graphics.h file). */
- static int TransColorTable[][4] = {
- { /* BLACK */ 0, 0, 0, 0 },
- { /* BLUE */ 1, 0, 0, 255 },
- { /* GREEN */ 2, 0, 255, 0 },
- { /* CYAN */ 3, 0, 255, 255 },
- { /* RED */ 4, 255, 0, 0 },
- { /* MAGENTA */ 5, 255, 0, 255 },
- { /* BROWN */ 20, 50, 0, 0 },
- { /* LIGHTGRAY */ 7, 127, 127, 127 },
- { /* DARKGRAY */ 56, 63, 63, 63 },
- { /* LIGHTBLUE */ 57, 0, 0, 255 },
- { /* LIGHTGREEN */ 58, 0, 255, 0 },
- { /* LIGHTCYAN */ 59, 0, 255, 255 },
- { /* LIGHTRED */ 60, 255, 0, 0 },
- { /* LIGHTMAGENTA */ 61, 255, 0, 255 },
- { /* YELLOW */ 62, 255, 255, 0 },
- { /* WHITE */ 63, 255, 255, 255 },
- { -1, 0, 0, 0 }
- };
-
-
- static void PrepareAllObjects1(FileDescription **FD, GifColorType *Colors,
- int *NumColors);
- static void VisitObjectTree1(BinTree *PBinTree, GifColorType *Colors,
- int *NumColors);
- static void InsertColor(ObjectStruct *PObject, GifColorType *Colors,
- int *NumColors);
- static void PrepareAllObjects2(FileDescription **FD, GifColorType *Colors,
- int NumColors);
- static void VisitObjectTree2(BinTree *PBinTree, GifColorType *Colors,
- int NumColors);
- static void UpdateColorIndex(ObjectStruct *PObject, GifColorType *Colors,
- int NumColors);
-
- /*****************************************************************************
- * Routine to prepare color map for the given scene. *
- *****************************************************************************/
- void PrepareColorTable(FileDescription **FD, int NumOfObjects,
- int RealNumOfObjects, char **Objects)
- {
- int i, j, NumColors = 0, ColorMapSize, Levels, *MinIntensityIndex;
- float DIntensity, CrntIntensity;
- GifColorType *Colors, *ColorMap;
- struct ObjectStruct *PObject;
-
- Colors = (GifColorType *) MyMalloc(sizeof(GifColorType) * RealNumOfObjects);
-
- if (NumOfObjects > 0) /* There was something on command line... */
- for (i=0; i<NumOfObjects; i++) {
- if ((PObject = SearchObject(FD, *Objects)) != NULL)
- InsertColor(PObject, Colors, &NumColors);
- }
- else { /* Prepare all objects by scanning object trees. */
- PrepareAllObjects1(FD, Colors, &NumColors);
- }
-
- /* Allocate color table and fill it in: */
- ColorMapSize = (1 << ShadingInfo.BitsPerPixel);
- ShadingInfo.PColorMap = ColorMap =
- (GifColorType *) MyMalloc(sizeof(GifColorType) * ColorMapSize);
- ShadingInfo.MinIntensityIndex = MinIntensityIndex =
- (int *) MyMalloc(sizeof(int) * ColorMapSize);
-
- /* Save one place to hold the back ground color: */
- if (NumColors == 0) {
- fprintf(stderr, "No color allocated - that is really wierd!\n");
- MyExit(1);
- }
- ShadingInfo.LevelsPerColor = Levels = (ColorMapSize - 1) / NumColors;
- if (Levels == 0) {
- fprintf(stderr, "Too many colors (%d) for color map size (%d), exit\n",
- NumColors, ColorMapSize);
- MyExit(1);
- }
-
- /* Insert the back ground color in: */
- for (i=0; TransColorTable[i][0] >= 0; i++)
- if (TransColorTable[i][0] == ShadingInfo.BackGroundColor) break;
- if (TransColorTable[i][0] < 0) {
- fprintf(stderr,
- "Undefined color required (%d) for background, default selected instead.\n",
- PObject -> Color);
- PObject -> Color = ShadingInfo.DefaultColor;
- }
- ColorMap[0].Red = TransColorTable[i][1];
- ColorMap[0].Green = TransColorTable[i][2];
- ColorMap[0].Blue = TransColorTable[i][3];
-
- /* O.k. time to interpolate the colors. Each given color intensities are */
- /* interplated between the ambient light and full intensity (1.0): */
- DIntensity = (1.0 - ShadingInfo.Ambient) / Levels;
- for (i=0; i<NumColors; i++) {
- CrntIntensity = 1.0;
- for (j=0; j<Levels; j++) {
- ColorMap[i * Levels + j + 1].Red =
- (int) (Colors[i].Red * CrntIntensity);
- ColorMap[i * Levels + j + 1].Green =
- (int) (Colors[i].Green * CrntIntensity);
- ColorMap[i * Levels + j + 1].Blue =
- (int) (Colors[i].Blue * CrntIntensity);
- MinIntensityIndex[i * Levels + j + 1] = (i + 1) * Levels;
- CrntIntensity -= DIntensity;
- }
- }
-
- /* Now the final step - let the objects know where their color is mapped */
- /* to in the color table. */
- if (NumOfObjects > 0) /* There was something on command line... */
- for (i=0; i<NumOfObjects; i++) {
- if ((PObject = SearchObject(FD, *Objects)) != NULL)
- UpdateColorIndex(PObject, Colors, NumColors);
- }
- else { /* Prepare all objects by scanning object trees. */
- PrepareAllObjects2(FD, Colors, NumColors);
- }
-
- free((char *) Colors);
- }
-
- /*****************************************************************************
- * Scan all objects. *
- *****************************************************************************/
- static void PrepareAllObjects1(FileDescription **FD, GifColorType *Colors,
- int *NumColors)
- {
- while (*FD) VisitObjectTree1((*FD++) -> ObjectPointer, Colors, NumColors);
- }
-
- /*****************************************************************************
- * Scanning all the object in tree PBinTree and prepare them. *
- *****************************************************************************/
- static void VisitObjectTree1(BinTree *PBinTree, GifColorType *Colors,
- int *NumColors)
- {
- if (PBinTree == (BinTree *) NULL) return;
-
- VisitObjectTree1(PBinTree -> right, Colors, NumColors);
-
- InsertColor(PBinTree -> Data.PObject, Colors, NumColors);
-
- VisitObjectTree1(PBinTree -> left, Colors, NumColors);
- }
-
- /*****************************************************************************
- * Scanning all the object in tree PBinTree and prepare them. *
- *****************************************************************************/
- static void InsertColor(ObjectStruct *PObject, GifColorType *Colors,
- int *NumColors)
- {
- int i;
-
- if (PObject -> Color != RGB_COLOR_GIVEN) {
- /* Translate the color into RGB form: */
- for (i=0; TransColorTable[i][0] >= 0; i++)
- if (TransColorTable[i][0] == PObject -> Color) break;
- if (TransColorTable[i][0] < 0) {
- fprintf(stderr,
- "Undefined color required (%d), default selected instead.\n",
- PObject -> Color);
- PObject -> Color = ShadingInfo.DefaultColor;
- }
- PObject -> RGBColor[0] = TransColorTable[i][1];
- PObject -> RGBColor[1] = TransColorTable[i][2];
- PObject -> RGBColor[2] = TransColorTable[i][3];
- }
-
- /* Lets see if this color exists in table already, and if so do nothing: */
- for (i=0; i<*NumColors; i++)
- if (PObject -> RGBColor[0] == Colors[i].Red &&
- PObject -> RGBColor[1] == Colors[i].Green &&
- PObject -> RGBColor[2] == Colors[i].Blue) return;
-
- /* Its a new color - add it to out colors table to allocate: */
- Colors[*NumColors].Red = PObject -> RGBColor[0];
- Colors[*NumColors].Green = PObject -> RGBColor[1];
- Colors[(*NumColors)++].Blue = PObject -> RGBColor[2];
- }
-
- /*****************************************************************************
- * Scan all objects. *
- *****************************************************************************/
- static void PrepareAllObjects2(FileDescription **FD, GifColorType *Colors,
- int NumColors)
- {
- while (*FD) VisitObjectTree2((*FD++) -> ObjectPointer, Colors, NumColors);
- }
-
- /*****************************************************************************
- * Scanning all the object in tree PBinTree and prepare them. *
- *****************************************************************************/
- static void VisitObjectTree2(BinTree *PBinTree, GifColorType *Colors,
- int NumColors)
- {
- if (PBinTree == (BinTree *) NULL) return;
-
- VisitObjectTree2(PBinTree -> right, Colors, NumColors);
-
- UpdateColorIndex(PBinTree -> Data.PObject, Colors, NumColors);
-
- VisitObjectTree2(PBinTree -> left, Colors, NumColors);
- }
-
- /*****************************************************************************
- * Update object with the index to its color in the color map. *
- *****************************************************************************/
- static void UpdateColorIndex(ObjectStruct *PObject, GifColorType *Colors,
- int NumColors)
- {
- int i;
-
- /* Find this color in table (must be in it...): */
- for (i=0; i<NumColors; i++)
- if (PObject -> RGBColor[0] == Colors[i].Red &&
- PObject -> RGBColor[1] == Colors[i].Green &&
- PObject -> RGBColor[2] == Colors[i].Blue) break;
-
- /* Color table hold this object color, with decreasing intensity, from */
- /* this index up to (i + 1) * ShadingInfo.LevelsPerColor. */
- PObject -> Color = i * ShadingInfo.LevelsPerColor + 1;
- }
-
-