home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / IRIT / POLY3DRS.ZIP / COLORTBL.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-05-05  |  9.6 KB  |  246 lines

  1. /*****************************************************************************
  2. *   Routines to    prpepare the color table for the given scene. Each color     *
  3. * get equal share in the map table, so its modules does:             *
  4. * 1. Scans all objects and retrieve all possible colors.             *
  5. * 2. Create a color map table, of the specified size (in ShadingInfo global  *
  6. *    structure) and interpolate intensity levels for each color into it.     *
  7. * 3. Update the objects for their index into the color map.             *
  8. *                                         *
  9. * Written by:  Gershon Elber                Ver 2.0, Mar. 1990   *
  10. *****************************************************************************/
  11.  
  12. #ifdef __MSDOS__
  13. #include <stdlib.h>
  14. #endif /* __MSDOS__ */
  15.  
  16. #include <math.h>
  17. #include <stdio.h>
  18. #include <time.h>
  19. #include "program.h"
  20. #include "parser.h"
  21. #include "gif_lib.h"
  22.  
  23. /* The colors can be specified as indices in which we must convert to RGB: */
  24. /* We uses the EGA convension (see also TC 2.0 graphics.h file).       */
  25. static int TransColorTable[][4] = {
  26.     { /* BLACK        */ 0,    0,   0,   0 },
  27.     { /* BLUE        */ 1,    0,   0, 255 },
  28.     { /* GREEN        */ 2,    0, 255,   0 },
  29.     { /* CYAN        */ 3,    0, 255, 255 },
  30.     { /* RED        */ 4,  255,   0,   0 },
  31.     { /* MAGENTA     */ 5,  255,   0, 255 },
  32.     { /* BROWN        */ 20,  50,   0,   0 },
  33.     { /* LIGHTGRAY    */ 7,  127, 127, 127 },
  34.     { /* DARKGRAY    */ 56,  63,  63,  63 },
  35.     { /* LIGHTBLUE    */ 57,   0,   0, 255 },
  36.     { /* LIGHTGREEN    */ 58,   0, 255,   0 },
  37.     { /* LIGHTCYAN    */ 59,   0, 255, 255 },
  38.     { /* LIGHTRED    */ 60, 255,   0,   0 },
  39.     { /* LIGHTMAGENTA    */ 61, 255,   0, 255 },
  40.     { /* YELLOW        */ 62, 255, 255,   0 },
  41.     { /* WHITE        */ 63, 255, 255, 255 },
  42.     {               -1,   0,   0,   0 }
  43. };
  44.  
  45.  
  46. static void PrepareAllObjects1(FileDescription **FD, GifColorType *Colors,
  47.                             int *NumColors);
  48. static void VisitObjectTree1(BinTree *PBinTree, GifColorType *Colors,
  49.                             int *NumColors);
  50. static void InsertColor(ObjectStruct *PObject, GifColorType *Colors,
  51.                             int *NumColors);
  52. static void PrepareAllObjects2(FileDescription **FD, GifColorType *Colors,
  53.                             int NumColors);
  54. static void VisitObjectTree2(BinTree *PBinTree, GifColorType *Colors,
  55.                             int NumColors);
  56. static void UpdateColorIndex(ObjectStruct *PObject, GifColorType *Colors,
  57.                             int NumColors);
  58.  
  59. /*****************************************************************************
  60. * Routine to prepare color map for the given scene.                 *
  61. *****************************************************************************/
  62. void PrepareColorTable(FileDescription **FD, int NumOfObjects,
  63.                     int RealNumOfObjects, char **Objects)
  64. {
  65.     int    i, j, NumColors = 0, ColorMapSize, Levels, *MinIntensityIndex;
  66.     float DIntensity, CrntIntensity;
  67.     GifColorType *Colors, *ColorMap;
  68.     struct ObjectStruct    *PObject;
  69.  
  70.     Colors = (GifColorType *) MyMalloc(sizeof(GifColorType) * RealNumOfObjects);
  71.  
  72.     if (NumOfObjects > 0)       /* There was something on command line... */
  73.     for (i=0; i<NumOfObjects; i++) {
  74.         if ((PObject = SearchObject(FD, *Objects)) != NULL)
  75.         InsertColor(PObject, Colors, &NumColors);
  76.     }
  77.     else {            /* Prepare all objects by scanning object trees. */
  78.     PrepareAllObjects1(FD, Colors, &NumColors);
  79.     }
  80.  
  81.     /* Allocate color table and fill it in: */
  82.     ColorMapSize = (1 << ShadingInfo.BitsPerPixel);
  83.     ShadingInfo.PColorMap = ColorMap =
  84.     (GifColorType *) MyMalloc(sizeof(GifColorType) * ColorMapSize);
  85.     ShadingInfo.MinIntensityIndex = MinIntensityIndex =
  86.     (int *) MyMalloc(sizeof(int) * ColorMapSize);
  87.  
  88.     /* Save one place to hold the back ground color: */
  89.     if (NumColors == 0) {
  90.     fprintf(stderr, "No color allocated - that is really wierd!\n");
  91.     MyExit(1);
  92.     }
  93.     ShadingInfo.LevelsPerColor = Levels = (ColorMapSize - 1) / NumColors;
  94.     if (Levels == 0) {
  95.     fprintf(stderr, "Too many colors (%d) for color map size (%d), exit\n",
  96.                         NumColors, ColorMapSize);
  97.     MyExit(1);
  98.     }
  99.  
  100.     /* Insert the back ground color in: */
  101.     for (i=0; TransColorTable[i][0] >= 0; i++)
  102.     if (TransColorTable[i][0] == ShadingInfo.BackGroundColor) break;
  103.     if (TransColorTable[i][0] < 0) {
  104.     fprintf(stderr,
  105.         "Undefined color required (%d) for background, default selected instead.\n",
  106.         PObject -> Color);
  107.     PObject -> Color = ShadingInfo.DefaultColor;
  108.     }
  109.     ColorMap[0].Red   = TransColorTable[i][1];
  110.     ColorMap[0].Green = TransColorTable[i][2];
  111.     ColorMap[0].Blue  = TransColorTable[i][3];
  112.  
  113.     /* O.k. time to interpolate the colors. Each given color intensities are */
  114.     /* interplated between the ambient light and full intensity (1.0):         */
  115.     DIntensity = (1.0 - ShadingInfo.Ambient) / Levels;
  116.     for (i=0; i<NumColors; i++) {
  117.     CrntIntensity = 1.0;
  118.     for (j=0; j<Levels; j++) {
  119.         ColorMap[i * Levels + j + 1].Red =
  120.                     (int) (Colors[i].Red * CrntIntensity);
  121.         ColorMap[i * Levels + j + 1].Green =
  122.                     (int) (Colors[i].Green * CrntIntensity);
  123.         ColorMap[i * Levels + j + 1].Blue =
  124.                     (int) (Colors[i].Blue * CrntIntensity);
  125.         MinIntensityIndex[i * Levels + j + 1] = (i + 1) * Levels;
  126.         CrntIntensity -= DIntensity;
  127.     }
  128.     }
  129.  
  130.     /* Now the final step - let the objects know where their color is mapped */
  131.     /* to in the color table.                             */
  132.     if (NumOfObjects > 0)       /* There was something on command line... */
  133.     for (i=0; i<NumOfObjects; i++) {
  134.         if ((PObject = SearchObject(FD, *Objects)) != NULL)
  135.         UpdateColorIndex(PObject, Colors, NumColors);
  136.     }
  137.     else {            /* Prepare all objects by scanning object trees. */
  138.     PrepareAllObjects2(FD, Colors, NumColors);
  139.     }
  140.  
  141.     free((char *) Colors);
  142. }
  143.  
  144. /*****************************************************************************
  145. * Scan all objects.                                 *
  146. *****************************************************************************/
  147. static void PrepareAllObjects1(FileDescription **FD, GifColorType *Colors,
  148.                             int *NumColors)
  149. {
  150.     while (*FD)    VisitObjectTree1((*FD++) -> ObjectPointer, Colors, NumColors);
  151. }
  152.  
  153. /*****************************************************************************
  154. * Scanning all the object in tree PBinTree and prepare them.             *
  155. *****************************************************************************/
  156. static void VisitObjectTree1(BinTree *PBinTree, GifColorType *Colors,
  157.                             int *NumColors)
  158. {
  159.     if (PBinTree == (BinTree *)    NULL) return;
  160.  
  161.     VisitObjectTree1(PBinTree -> right, Colors, NumColors);
  162.  
  163.     InsertColor(PBinTree -> Data.PObject, Colors, NumColors);
  164.  
  165.     VisitObjectTree1(PBinTree -> left, Colors, NumColors);
  166. }
  167.  
  168. /*****************************************************************************
  169. * Scanning all the object in tree PBinTree and prepare them.             *
  170. *****************************************************************************/
  171. static void InsertColor(ObjectStruct *PObject, GifColorType *Colors,
  172.                             int *NumColors)
  173. {
  174.     int i;
  175.  
  176.     if (PObject -> Color != RGB_COLOR_GIVEN) {
  177.     /* Translate the color into RGB form: */
  178.     for (i=0; TransColorTable[i][0] >= 0; i++)
  179.         if (TransColorTable[i][0] == PObject -> Color) break;
  180.     if (TransColorTable[i][0] < 0) {
  181.         fprintf(stderr,
  182.         "Undefined color required (%d), default selected instead.\n",
  183.         PObject -> Color);
  184.         PObject -> Color = ShadingInfo.DefaultColor;
  185.     }
  186.     PObject -> RGBColor[0] = TransColorTable[i][1];
  187.     PObject -> RGBColor[1] = TransColorTable[i][2];
  188.     PObject -> RGBColor[2] = TransColorTable[i][3];
  189.     }
  190.  
  191.     /* Lets see if this color exists in table already, and if so do nothing: */
  192.     for (i=0; i<*NumColors; i++)
  193.     if (PObject -> RGBColor[0] == Colors[i].Red &&
  194.         PObject -> RGBColor[1] == Colors[i].Green &&
  195.         PObject -> RGBColor[2] == Colors[i].Blue) return;
  196.  
  197.     /* Its a new color - add it to out colors table to allocate: */
  198.     Colors[*NumColors].Red      = PObject -> RGBColor[0];
  199.     Colors[*NumColors].Green    = PObject -> RGBColor[1];
  200.     Colors[(*NumColors)++].Blue = PObject -> RGBColor[2];
  201. }
  202.  
  203. /*****************************************************************************
  204. * Scan all objects.                                 *
  205. *****************************************************************************/
  206. static void PrepareAllObjects2(FileDescription **FD, GifColorType *Colors,
  207.                             int NumColors)
  208. {
  209.     while (*FD)    VisitObjectTree2((*FD++) -> ObjectPointer, Colors, NumColors);
  210. }
  211.  
  212. /*****************************************************************************
  213. * Scanning all the object in tree PBinTree and prepare them.             *
  214. *****************************************************************************/
  215. static void VisitObjectTree2(BinTree *PBinTree, GifColorType *Colors,
  216.                             int NumColors)
  217. {
  218.     if (PBinTree == (BinTree *)    NULL) return;
  219.  
  220.     VisitObjectTree2(PBinTree -> right, Colors, NumColors);
  221.  
  222.     UpdateColorIndex(PBinTree -> Data.PObject, Colors, NumColors);
  223.  
  224.     VisitObjectTree2(PBinTree -> left, Colors, NumColors);
  225. }
  226.  
  227. /*****************************************************************************
  228. * Update object with the index to its color in the color map.             *
  229. *****************************************************************************/
  230. static void UpdateColorIndex(ObjectStruct *PObject, GifColorType *Colors,
  231.                             int NumColors)
  232. {
  233.     int i;
  234.  
  235.     /* Find this color in table (must be in it...): */
  236.     for (i=0; i<NumColors; i++)
  237.     if (PObject -> RGBColor[0] == Colors[i].Red &&
  238.         PObject -> RGBColor[1] == Colors[i].Green &&
  239.         PObject -> RGBColor[2] == Colors[i].Blue) break;
  240.  
  241.     /* Color table hold this object color, with decreasing intensity, from   */
  242.     /* this index up to (i + 1) * ShadingInfo.LevelsPerColor.             */
  243.     PObject -> Color = i * ShadingInfo.LevelsPerColor + 1;
  244. }
  245.  
  246.