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 specified size (in GlblShadeInfo 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 "iritprsr.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 */ 6, 50, 0, 0 },
- { /* LIGHTGRAY */ 7, 127, 127, 127 },
- { /* DARKGRAY */ 8, 63, 63, 63 },
- { /* LIGHTBLUE */ 9, 0, 0, 255 },
- { /* LIGHTGREEN */ 10, 0, 255, 0 },
- { /* LIGHTCYAN */ 11, 0, 255, 255 },
- { /* LIGHTRED */ 12, 255, 0, 0 },
- { /* LIGHTMAGENTA */ 13, 255, 0, 255 },
- { /* YELLOW */ 14, 255, 255, 0 },
- { /* WHITE */ 15, 255, 255, 255 },
- { /* BROWN */ 20, 50, 0, 0 },
- { /* 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(IPObjectStruct *PObjects,
- GifColorType *Colors, int *NumColors);
- static void InsertColor(IPObjectStruct *PObject, GifColorType *Colors,
- int *NumColors);
- static void PrepareAllObjects2(IPObjectStruct *PObjects, GifColorType *Colors,
- int NumColors);
- static void UpdateColorIndex(IPObjectStruct *PObject, GifColorType *Colors,
- int NumColors);
-
- /*****************************************************************************
- * Routine to prepare color map for the given scene. *
- *****************************************************************************/
- void PrepareColorTable(IPObjectStruct *PObjects)
- {
- int i, j, NumColors = 0, NumOfObjs, ColorMapSize, Levels,
- *MinIntensityIndex;
- RealType DIntensity, CrntIntensity;
- GifColorType *Colors, *ColorMap;
- IPObjectStruct *PObject;
-
- for (NumOfObjs = 0, PObject = PObjects; /* How many objects do we have? */
- PObject != NULL;
- NumOfObjs++, PObject = PObject -> Pnext);
-
- Colors = (GifColorType *) MyMalloc(sizeof(GifColorType) * NumOfObjs);
-
- PrepareAllObjects1(PObjects, Colors, &NumColors);
-
- /* Allocate color table and fill it in: */
- ColorMapSize = (1 << GlblShadeInfo.BitsPerPixel);
- GlblShadeInfo.PColorMap = ColorMap =
- (GifColorType *) MyMalloc(sizeof(GifColorType) * ColorMapSize);
- GlblShadeInfo.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);
- }
- GlblShadeInfo.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] == GlblShadeInfo.BackGroundColor) break;
- if (TransColorTable[i][0] < 0) {
- fprintf(stderr,
- "Undefined color required (%d) for background, default selected instead.\n",
- PObjects -> Color);
- PObjects -> Color = GlblShadeInfo.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 - GlblShadeInfo.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. */
- PrepareAllObjects2(PObjects, Colors, NumColors);
-
- free((char *) Colors);
- }
-
- /*****************************************************************************
- * Scan all objects (first pass). *
- *****************************************************************************/
- static void PrepareAllObjects1(IPObjectStruct *PObjects, GifColorType *Colors,
- int *NumColors)
- {
- while (PObjects) {
- InsertColor(PObjects, Colors, NumColors);
- PObjects = PObjects -> Pnext;
- }
- }
-
- /*****************************************************************************
- * Scanning all the object in tree PBinTree and prepare them. *
- *****************************************************************************/
- static void InsertColor(IPObjectStruct *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 = GlblShadeInfo.DefaultColor;
- }
- PObject -> RGB[0] = TransColorTable[i][1];
- PObject -> RGB[1] = TransColorTable[i][2];
- PObject -> RGB[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 -> RGB[0] == Colors[i].Red &&
- PObject -> RGB[1] == Colors[i].Green &&
- PObject -> RGB[2] == Colors[i].Blue) return;
-
- /* Its a new color - add it to out colors table to allocate: */
- Colors[*NumColors].Red = PObject -> RGB[0];
- Colors[*NumColors].Green = PObject -> RGB[1];
- Colors[(*NumColors)++].Blue = PObject -> RGB[2];
- }
-
- /*****************************************************************************
- * Scan all objects (second pass). *
- *****************************************************************************/
- static void PrepareAllObjects2(IPObjectStruct *PObjects,
- GifColorType *Colors, int NumColors)
- {
- while (PObjects) {
- UpdateColorIndex(PObjects, Colors, NumColors);
- PObjects = PObjects -> Pnext;
- }
- }
-
- /*****************************************************************************
- * Update object with the index to its color in the color map. *
- *****************************************************************************/
- static void UpdateColorIndex(IPObjectStruct *PObject, GifColorType *Colors,
- int NumColors)
- {
- int i;
-
- /* Find this color in table (must be in it...): */
- for (i = 0; i < NumColors; i++)
- if (PObject -> RGB[0] == Colors[i].Red &&
- PObject -> RGB[1] == Colors[i].Green &&
- PObject -> RGB[2] == Colors[i].Blue) break;
-
- /* Color table hold this object color, with decreasing intensity, from */
- /* this index up to (i + 1) * GlblShadeInfo.LevelsPerColor. */
- PObject -> Color = i * GlblShadeInfo.LevelsPerColor + 1;
- }
-
-