home *** CD-ROM | disk | FTP | other *** search
/ Gambler 19 / GAMBLERCD19.BIN / UTILS / RIVA128 / Uzytki / ssystem-1.2 / SOURCE / INIT.C next >
C/C++ Source or Header  |  1998-05-01  |  35KB  |  1,055 lines

  1. /*
  2.   Initialization routines:
  3.   
  4.       - Read texture images
  5.       - Initialize planets' data
  6.       - Create display lists
  7.       - Other initialization routines
  8.   
  9.   Major code reorganization since 1.02
  10.   
  11.   Satellites' textures (except Moon) are 128x128 so we don't reach the 2MB 
  12.   limit in many Voodoo Graphics cards. May change in the future, since all 
  13.   Voodoo2 cards come with a minimum of 4MB on board.
  14.   
  15. */
  16.  
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <math.h>
  20. #include <malloc.h>
  21. #include <time.h>
  22. #include "jpeglib.h"
  23. #include <setjmp.h>
  24. #include <GL/glut.h>
  25. #include "planets.h"
  26.  
  27. char * filenames[NUMBODIES]=    {"sun.jpg",
  28.             "mercury.jpg",
  29.             "venus.jpg",
  30.             "earth.jpg",
  31.             "mars.jpg",
  32.             "jupiter.jpg",
  33.             "saturn.jpg",
  34.             "uranus.jpg",
  35.             "neptune.jpg",
  36.             "pluto.jpg",
  37.             "moon.jpg",
  38.             "io.jpg",
  39.             "europa.jpg",
  40.             "ganymede.jpg",
  41.             "callisto.jpg",
  42.             "tethys.jpg",
  43.             "dione.jpg",
  44.             "rhea.jpg",
  45.             "titan.jpg",
  46.             "triton.jpg",
  47.             "charon.jpg",
  48.             "satrings.jpg"};
  49.  
  50. GLfloat LightPos[4] = {0.0, 0.0, 0.0, 1.0};
  51. GLfloat ambient[4] = {0.6, 0.6, 0.6, 1.0};
  52. GLfloat White[4] = {1.0, 1.0, 1.0, 1.0};
  53. GLfloat Black[4] = {0.0, 0.0, 0.0, 1.0};
  54. GLuint texName[NUMBODIES],texture=1,smodel=GL_SMOOTH,lighting=1,drawstars=1;
  55. GLuint Stars,red,polaris;
  56. int ImgWidth, ImgHeight;
  57. GLenum ImgFormat;
  58. planetdata planets[NUMBODIES];
  59. GLfloat stars[NUMSTARS][4];
  60. double days,timefactor=1/(24.0*60.0); /* iterarion = 1 minute */
  61. int SLICES=12,STACKS=12;
  62. char texturepath[100]=".";
  63. static void InitSun(void),InitMercury(void),InitVenus(void),InitEarth(void),
  64.     InitMars(void),InitJupiter(void),InitSaturn(void),InitUranus(void),
  65.     InitNeptune(void),InitPluto(void),InitStars(void);
  66.  
  67. GLubyte *read_JPEG_file (char *);
  68.  
  69. void Init( void )
  70. {
  71.    time_t t;
  72.    
  73.    glEnable(GL_LIGHTING);
  74.    glEnable(GL_LIGHT0);
  75.    glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
  76.    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
  77.  
  78.    t=time(NULL);
  79.    srand(t);
  80.    days=t/3600.0/24.0-10093.0;
  81.    glEnable(GL_DEPTH_TEST);
  82.    glEnable(GL_CULL_FACE);
  83.    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  84.    glGenTextures(NUMBODIES, texName);
  85.    InitSun();      
  86.    InitMercury();   
  87.    InitVenus();
  88.    InitEarth();
  89.    InitMars();
  90.    InitJupiter(); 
  91.    InitSaturn();   
  92.    InitUranus();   
  93.    InitNeptune();   
  94.    InitPluto();   
  95.    InitStars();
  96.    glEnable(GL_TEXTURE_2D);
  97.    glShadeModel(GL_SMOOTH);
  98.    glBlendFunc(GL_DST_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
  99. }
  100.  
  101.  
  102. static void InitSun(void)
  103.    static int i,j;
  104.    static char *localimage;
  105.    
  106.    planets[SUN].Radius=2.0; /*Real Radius is 109.6*/
  107.    planets[SUN].Degrees=0.0;
  108.    planets[SUN].DeltaRotation=0.0;
  109.    planets[SUN].Rotation=360.0/28.0;
  110.    planets[SUN].Sat=0;
  111.    planets[SUN].posx=planets[SUN].posy=planets[SUN].posz=0.0;
  112.    sprintf(planets[SUN].Name,"Sun");
  113.  
  114.    planets[SUN].Object = gluNewQuadric();
  115.    gluQuadricTexture( planets[SUN].Object, GL_FALSE );   
  116.    planets[SUN].Sphere= glGenLists(1);
  117.    glNewList( planets[SUN].Sphere, GL_COMPILE );
  118.    gluSphere( planets[SUN].Object,RADIUSSCALE(planets[SUN].Radius), SLICES, STACKS );
  119.    glEndList();
  120.  
  121.    planets[SUN].Image = read_JPEG_file(filenames[SUN]);
  122.    if (!planets[SUN].Image) {
  123.       printf("Couldn't read image\n");
  124.       exit(0);
  125.    }
  126.  
  127.    localimage=malloc(128*128*4);
  128.    for (i=0;i<(128*128);i++) {
  129.     localimage[i*4]=planets[SUN].Image[i*3];
  130.     localimage[i*4+1]=planets[SUN].Image[i*3+1];
  131.     localimage[i*4+2]=planets[SUN].Image[i*3+2];
  132.     j=planets[SUN].Image[i*3]*2;
  133.     localimage[i*4+3]=j>255?255:j;
  134.    }
  135.  
  136.    glBindTexture(GL_TEXTURE_2D, texName[SUN]);
  137.    glTexImage2D( GL_TEXTURE_2D,
  138.                  0,
  139.                  4,
  140.                  128, 128,
  141.                  0,
  142.                  GL_RGBA, GL_UNSIGNED_BYTE,
  143.                  localimage );
  144.    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  145.    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  146.    glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);                 
  147.    free(planets[SUN].Image);
  148.    free(localimage);
  149.  
  150.  
  151. static void InitMercury(void)
  152. {
  153.    planets[MERCURY].Radius=0.382;
  154.    planets[MERCURY].Degrees=0.0;
  155.    planets[MERCURY].DeltaRotation=0.0;
  156.    planets[MERCURY].Rotation=360.0/58.6462;
  157.    planets[MERCURY].Inclination=DEG2RAD(7.00507);
  158.    planets[MERCURY].AscendingNode=DEG2RAD(48.3339);
  159.    planets[MERCURY].Perihelion=DEG2RAD(77.45399999999999);
  160.    planets[MERCURY].MeanDistance=DISTCORRECTION(0.3870978);
  161.    planets[MERCURY].DailyMotion=DEG2RAD(4.092353);
  162.    planets[MERCURY].Eccentricity=0.2056324;
  163.    planets[MERCURY].MeanLongitude=DEG2RAD(314.42369);
  164.    planets[MERCURY].Sat=0;
  165.    sprintf(planets[MERCURY].Name,"Mercury");
  166.  
  167.    planets[MERCURY].Image = read_JPEG_file(filenames[MERCURY]);
  168.    if (!planets[MERCURY].Image) {
  169.       printf("Couldn't read image\n");
  170.       exit(0);
  171.    }
  172.  
  173.    glBindTexture(GL_TEXTURE_2D, texName[MERCURY]);
  174.    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  175.    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  176.    glTexImage2D( GL_TEXTURE_2D,
  177.                  0,
  178.                  3,
  179.                  256, 256,
  180.                  0,
  181.                  GL_RGB, GL_UNSIGNED_BYTE,
  182.                  planets[MERCURY].Image );
  183.    free(planets[MERCURY].Image);
  184.    planets[MERCURY].Object = gluNewQuadric();
  185.    gluQuadricTexture( planets[MERCURY].Object, GL_TRUE );   
  186.    planets[MERCURY].Sphere= glGenLists(1);
  187.    glNewList( planets[MERCURY].Sphere, GL_COMPILE );
  188.    gluSphere( planets[MERCURY].Object,RADIUSSCALE(planets[MERCURY].Radius), SLICES, STACKS );
  189.    glEndList();
  190.  
  191.  
  192.  
  193. static void InitVenus(void)
  194. {
  195.    planets[VENUS].Radius=0.95;
  196.    planets[VENUS].Degrees=177.3;
  197.    planets[VENUS].DeltaRotation=0.0;
  198.    planets[VENUS].Rotation=360.0/243.0187;
  199.    planets[VENUS].Inclination=DEG2RAD(3.39472);
  200.    planets[VENUS].AscendingNode=DEG2RAD(76.6889);
  201.    planets[VENUS].Perihelion=DEG2RAD(131.761);
  202.    planets[VENUS].MeanDistance=DISTCORRECTION(0.7233238);
  203.    planets[VENUS].DailyMotion=DEG2RAD(1.602158);
  204.    planets[VENUS].Eccentricity=0.0067933;
  205.    planets[VENUS].MeanLongitude=DEG2RAD(236.94045);
  206.    planets[VENUS].Sat=0;
  207.    sprintf(planets[VENUS].Name,"Venus");
  208.    
  209.  
  210.    planets[VENUS].Image = read_JPEG_file(filenames[VENUS]);
  211.    if (!planets[VENUS].Image) {
  212.       printf("Couldn't read image\n");
  213.       exit(0);
  214.    }
  215.  
  216.    glBindTexture(GL_TEXTURE_2D, texName[VENUS]);
  217.    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  218.    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  219.    glTexImage2D( GL_TEXTURE_2D,
  220.                  0,
  221.                  3,
  222.                  128, 128,
  223.                  0,
  224.                  GL_RGB, GL_UNSIGNED_BYTE,
  225.                  planets[VENUS].Image );
  226.    free(planets[VENUS].Image);
  227.    planets[VENUS].Object = gluNewQuadric();
  228.    gluQuadricTexture( planets[VENUS].Object, GL_TRUE );   
  229.    planets[VENUS].Sphere= glGenLists(1);
  230.    glNewList( planets[VENUS].Sphere, GL_COMPILE );
  231.    gluSphere( planets[VENUS].Object,RADIUSSCALE(planets[VENUS].Radius), SLICES, STACKS );
  232.    glEndList();
  233.  
  234.  
  235.  
  236.  
  237. static void InitEarth(void)
  238. {
  239.    planets[EARTH].Radius=1.0;
  240.    planets[EARTH].Degrees=23.45;
  241.    planets[EARTH].DeltaRotation=0.0;
  242.    planets[EARTH].Rotation=360.0/(365.0/365.256);
  243.    planets[EARTH].Inclination=DEG2RAD(0.00041);
  244.    planets[EARTH].AscendingNode=DEG2RAD(349.2);
  245.    planets[EARTH].Perihelion=DEG2RAD(102.8517);
  246.    planets[EARTH].MeanDistance=DISTCORRECTION(1.00002);
  247.    planets[EARTH].DailyMotion=DEG2RAD(0.9855796);
  248.    planets[EARTH].Eccentricity=0.0166967;
  249.    planets[EARTH].MeanLongitude=DEG2RAD(328.40353);
  250.    planets[EARTH].Sat=0;
  251.    sprintf(planets[EARTH].Name,"Earth");
  252.  
  253.    planets[MOON].Radius=0.2724;
  254.    planets[MOON].Degrees=5.1454;
  255.    planets[MOON].DeltaRotation=0.0;
  256.    planets[MOON].Rotation=360.0/27.32166;
  257.    planets[MOON].Inclination=DEG2RAD(5.1454);
  258.    planets[MOON].AscendingNode=DEG2RAD(125.1228);
  259.    planets[MOON].Perihelion=DEG2RAD(83.1862);
  260.    planets[MOON].MeanDistance=RADIUSSCALE(60.2666)/4.0;
  261.    planets[MOON].DailyMotion=DEG2RAD(13.0649929509);
  262.    planets[MOON].Eccentricity=0.054900;
  263.    planets[MOON].MeanLongitude=DEG2RAD(328.40353);
  264.    planets[MOON].Sat=EARTH;
  265.    sprintf(planets[MOON].Name,"Moon");
  266.  
  267.  
  268.    planets[EARTH].Image = read_JPEG_file(filenames[EARTH]);
  269.    if (!planets[EARTH].Image) {
  270.       printf("Couldn't read image\n");
  271.       exit(0);
  272.    }
  273.  
  274.    glBindTexture(GL_TEXTURE_2D, texName[EARTH]);
  275.    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  276.    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  277.    glTexImage2D( GL_TEXTURE_2D,
  278.                  0,
  279.                  3,
  280.                  256, 256,
  281.                  0,
  282.                  GL_RGB, GL_UNSIGNED_BYTE,
  283.                  planets[EARTH].Image );
  284.    free(planets[EARTH].Image);
  285.    planets[EARTH].Object = gluNewQuadric();
  286.    gluQuadricTexture( planets[EARTH].Object, GL_TRUE );   
  287.    planets[EARTH].Sphere= glGenLists(1);
  288.    glNewList( planets[EARTH].Sphere, GL_COMPILE );
  289.    gluSphere( planets[EARTH].Object,RADIUSSCALE(planets[EARTH].Radius), SLICES, STACKS );
  290.    glEndList();
  291.  
  292.  
  293.    planets[MOON].Image = read_JPEG_file(filenames[MOON]);
  294.    if (!planets[MOON].Image) {
  295.       printf("Couldn't read image\n");
  296.       exit(0);
  297.    }
  298.  
  299.    glBindTexture(GL_TEXTURE_2D, texName[MOON]);
  300.    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  301.    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  302.    glTexImage2D( GL_TEXTURE_2D,
  303.                  0,
  304.                  3,
  305.                  256, 256,
  306.                  0,
  307.                  GL_RGB, GL_UNSIGNED_BYTE,
  308.                  planets[MOON].Image );
  309.    free(planets[MOON].Image);
  310.    planets[MOON].Object = gluNewQuadric();
  311.    gluQuadricTexture( planets[MOON].Object, GL_TRUE );   
  312.    planets[MOON].Sphere= glGenLists(1);
  313.    glNewList( planets[MOON].Sphere, GL_COMPILE );
  314.    gluSphere( planets[MOON].Object,RADIUSSCALE(planets[MOON].Radius), SLICES, STACKS );
  315.    glEndList();
  316.  
  317.  
  318.  
  319. static void InitMars(void)
  320. {
  321.    planets[MARS].Radius=0.532;
  322.    planets[MARS].Degrees=25.19;
  323.    planets[MARS].DeltaRotation=0.0;
  324.    planets[MARS].Rotation=360.0/1.025957;
  325.    planets[MARS].Inclination=DEG2RAD(1.84992);
  326.    planets[MARS].AscendingNode=DEG2RAD(49.5664);
  327.    planets[MARS].Perihelion=DEG2RAD(336.0882);
  328.    planets[MARS].MeanDistance=DISTCORRECTION(1.5236365);
  329.    planets[MARS].DailyMotion=DEG2RAD(0.5240613);
  330.    planets[MARS].Eccentricity=0.0934231;
  331.    planets[MARS].MeanLongitude=DEG2RAD(262.42784);
  332.    planets[MARS].Sat=0;
  333.    sprintf(planets[MARS].Name,"Mars");
  334.  
  335.    planets[MARS].Image = read_JPEG_file(filenames[MARS]);
  336.    if (!planets[MARS].Image) {
  337.       printf("Couldn't read image\n");
  338.       exit(0);
  339.    }
  340.  
  341.    glBindTexture(GL_TEXTURE_2D, texName[MARS]);
  342.    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  343.    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  344.    glTexImage2D( GL_TEXTURE_2D,
  345.                  0,
  346.                  3,
  347.                  256, 256,
  348.                  0,
  349.                  GL_RGB, GL_UNSIGNED_BYTE,
  350.                  planets[MARS].Image );
  351.    free(planets[MARS].Image);
  352.    planets[MARS].Object = gluNewQuadric();
  353.    gluQuadricTexture( planets[MARS].Object, GL_TRUE );   
  354.    planets[MARS].Sphere= glGenLists(1);
  355.    glNewList( planets[MARS].Sphere, GL_COMPILE );
  356.    gluSphere( planets[MARS].Object,RADIUSSCALE(planets[MARS].Radius), SLICES, STACKS );
  357.    glEndList();
  358.  
  359.     
  360.            
  361.  
  362.  
  363. static void InitJupiter(void)
  364. {
  365.    int i;
  366.    
  367.    planets[JUPITER].Radius=11.27;
  368.    planets[JUPITER].Degrees=3.12;
  369.    planets[JUPITER].DeltaRotation=0.0;
  370.    planets[JUPITER].Rotation=360.0/0.41354;
  371.    planets[JUPITER].Inclination=DEG2RAD(1.30463);
  372.    planets[JUPITER].AscendingNode=DEG2RAD(100.4713);
  373.    planets[JUPITER].Perihelion=DEG2RAD(15.6978);
  374.    planets[JUPITER].MeanDistance=DISTCORRECTION(5.202597);
  375.    planets[JUPITER].DailyMotion=DEG2RAD(8.309618000000001E-02);
  376.    planets[JUPITER].Eccentricity=0.0484646;
  377.    planets[JUPITER].MeanLongitude=DEG2RAD(322.55983);
  378.    planets[JUPITER].Sat=0;
  379.    sprintf(planets[JUPITER].Name,"Jupiter");
  380.  
  381.  
  382.    planets[IO].Radius=1820.0/6378.0;
  383.    planets[IO].Degrees=0.0;
  384.    planets[IO].DeltaRotation=360.0/1.769138;
  385.    planets[IO].Rotation=0.0;
  386.    planets[IO].Inclination=0.0;
  387.    planets[IO].Sat=JUPITER;
  388.    sprintf(planets[IO].Name,"Io");
  389.  
  390.    planets[EUROPA].Radius=1565.0/6378.0;
  391.    planets[EUROPA].Degrees=0.0;
  392.    planets[EUROPA].DeltaRotation=0.0;
  393.    planets[EUROPA].Rotation=360.0/3.551181;
  394.    planets[EUROPA].Inclination=0.0;
  395.    planets[EUROPA].Sat=JUPITER;
  396.    sprintf(planets[EUROPA].Name,"Europa");
  397.  
  398.    planets[GANYMEDE].Radius=2635.0/6378.0;
  399.    planets[GANYMEDE].Degrees=0.0;
  400.    planets[GANYMEDE].DeltaRotation=0.0;
  401.    planets[GANYMEDE].Rotation=360.0/7.154553;
  402.    planets[GANYMEDE].Inclination=0.0;   
  403.    planets[GANYMEDE].Sat=JUPITER;
  404.    sprintf(planets[GANYMEDE].Name,"Ganymede");
  405.    
  406.    planets[CALLISTO].Radius=2420.0/6378.0;
  407.    planets[CALLISTO].Degrees=0.0;
  408.    planets[CALLISTO].DeltaRotation=0.0;
  409.    planets[CALLISTO].Rotation=360.0/16.68902;
  410.    planets[CALLISTO].Inclination=0.0;   
  411.    planets[CALLISTO].Sat=JUPITER;
  412.    sprintf(planets[CALLISTO].Name,"Callisto");
  413.  
  414.  
  415.  
  416.    planets[JUPITER].Image = read_JPEG_file(filenames[JUPITER]);
  417.    if (!planets[JUPITER].Image) {
  418.       printf("Couldn't read image\n");
  419.       exit(0);
  420.    }
  421.  
  422.    glBindTexture(GL_TEXTURE_2D, texName[JUPITER]);
  423.    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  424.    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  425.    glTexImage2D( GL_TEXTURE_2D,
  426.                  0,
  427.                  3,
  428.                  256,256,
  429.                  0,
  430.                  GL_RGB, GL_UNSIGNED_BYTE,
  431.                  planets[JUPITER].Image );
  432.    free(planets[JUPITER].Image);
  433.    planets[JUPITER].Object = gluNewQuadric();
  434.    gluQuadricTexture( planets[JUPITER].Object, GL_TRUE );   
  435.    planets[JUPITER].Sphere= glGenLists(1);
  436.    glNewList( planets[JUPITER].Sphere, GL_COMPILE );
  437.    gluSphere( planets[JUPITER].Object,RADIUSSCALE(planets[JUPITER].Radius), SLICES, STACKS );
  438.    glEndList();
  439.  
  440.  
  441.    for (i=IO;i<=CALLISTO;i++) {
  442.        planets[i].Image = read_JPEG_file(filenames[i]);
  443.        if (!planets[i].Image) {
  444.           printf("Couldn't read image\n");
  445.           exit(0);
  446.        }
  447.  
  448.        glBindTexture(GL_TEXTURE_2D, texName[i]);
  449.        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  450.        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  451.        glTexImage2D( GL_TEXTURE_2D,
  452.                      0,
  453.                      3,
  454.                      128, 128,
  455.                      0,
  456.                      GL_RGB, GL_UNSIGNED_BYTE,
  457.                      planets[i].Image );
  458.        free(planets[i].Image);
  459.        planets[i].Object = gluNewQuadric();
  460.        gluQuadricTexture( planets[i].Object, GL_TRUE );   
  461.        planets[i].Sphere= glGenLists(1);
  462.        glNewList( planets[i].Sphere, GL_COMPILE );
  463.        gluSphere( planets[i].Object,RADIUSSCALE(planets[i].Radius), SLICES, STACKS );
  464.        glEndList();
  465.    }
  466.     
  467.  
  468.  
  469. static void InitSaturn(void)
  470. {
  471.    int i;
  472.    unsigned char *localimage;
  473.    
  474.    planets[SATURN].Radius=9.5;
  475.    planets[SATURN].Degrees=26.73;
  476.    planets[SATURN].DeltaRotation=0.0;
  477.    planets[SATURN].Rotation=360.0/0.44401;
  478.    planets[SATURN].Inclination=DEG2RAD(2.48524);
  479.    planets[SATURN].AscendingNode=DEG2RAD(113.6358);
  480.    planets[SATURN].Perihelion=DEG2RAD(88.863);
  481.    planets[SATURN].MeanDistance=DISTCORRECTION(9.571899999999999);
  482.    planets[SATURN].DailyMotion=DEG2RAD(0.03328656);
  483.    planets[SATURN].Eccentricity=0.0531651;
  484.    planets[SATURN].MeanLongitude=DEG2RAD(20.95759);
  485.    planets[SATURN].Sat=0;
  486.    sprintf(planets[SATURN].Name,"Saturn");
  487.  
  488.    planets[TETHYS].Radius=525.0/6378.0;
  489.    planets[TETHYS].Degrees=0.0;
  490.    planets[TETHYS].DeltaRotation=0.0;
  491.    planets[TETHYS].Rotation=360.0/1.8880926;
  492.    planets[TETHYS].Inclination=0.0;
  493.    planets[TETHYS].Sat=SATURN;
  494.    sprintf(planets[TETHYS].Name,"Tethys");
  495.  
  496.    planets[DIONE].Radius=560.0/6378.0;
  497.    planets[DIONE].Degrees=0.0;
  498.    planets[DIONE].DeltaRotation=0.0;
  499.    planets[DIONE].Rotation=360.0/2.7375218;
  500.    planets[DIONE].Inclination=0.0;
  501.    planets[DIONE].Sat=SATURN;
  502.    sprintf(planets[DIONE].Name,"Dione");
  503.  
  504.    planets[RHEA].Radius=765.0/6378.0;
  505.    planets[RHEA].Degrees=0.0;
  506.    planets[RHEA].DeltaRotation=0.0;
  507.    planets[RHEA].Rotation=360.0/4.5191631;
  508.    planets[RHEA].Inclination=0.0;
  509.    planets[RHEA].Sat=SATURN;
  510.    sprintf(planets[RHEA].Name,"Rhea");
  511.  
  512.    planets[TITAN].Radius=2575.0/6378.0;
  513.    planets[TITAN].Degrees=0.0;
  514.    planets[TITAN].DeltaRotation=0.0;
  515.    planets[TITAN].Rotation=360.0/15.9669028;
  516.    planets[TITAN].Inclination=0.0;
  517.    planets[TITAN].Sat=SATURN;
  518.    sprintf(planets[TITAN].Name,"Titan");
  519.  
  520.    planets[SATURN].Image = read_JPEG_file(filenames[SATURN]);
  521.    if (!planets[SATURN].Image) {
  522.       printf("Couldn't read image\n");
  523.       exit(0);
  524.    }
  525.  
  526.    glBindTexture(GL_TEXTURE_2D, texName[SATURN]);
  527.    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  528.    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  529.    glTexImage2D( GL_TEXTURE_2D,
  530.                  0,
  531.                  3,
  532.                  128, 128,
  533.                  0,
  534.                  GL_RGB, GL_UNSIGNED_BYTE,
  535.                  planets[SATURN].Image );
  536.    free(planets[SATURN].Image);
  537.  
  538.    planets[SATURN].Image = read_JPEG_file(filenames[RINGS]);
  539.    if (!planets[SATURN].Image) {
  540.       printf("Couldn't read image\n");
  541.       exit(0);
  542.    }
  543.    
  544.    localimage=malloc(256*256*4);
  545.    for (i=0;i<(256*256);i++) {
  546.     localimage[i*4]=planets[SATURN].Image[i*3];
  547.     localimage[i*4+1]=planets[SATURN].Image[i*3+1];
  548.     localimage[i*4+2]=planets[SATURN].Image[i*3+2];
  549.     localimage[i*4+3]=planets[SATURN].Image[i*3]>10?255:0;
  550.    }
  551.    glBindTexture(GL_TEXTURE_2D, texName[RINGS]);
  552.    glTexImage2D( GL_TEXTURE_2D,
  553.                  0,
  554.                  4,
  555.                  256, 256,
  556.                  0,
  557.                  GL_RGBA, GL_UNSIGNED_BYTE,
  558.                  localimage );
  559.    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  560.    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  561.    glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
  562.    free(planets[SATURN].Image);
  563.    free(localimage);
  564.  
  565.  
  566.  
  567.    planets[SATURN].Object = gluNewQuadric();
  568.    gluQuadricTexture( planets[SATURN].Object, GL_TRUE );   
  569.    planets[SATURN].Sphere= glGenLists(1);
  570.    glNewList( planets[SATURN].Sphere, GL_COMPILE );
  571.    gluSphere( planets[SATURN].Object,RADIUSSCALE(planets[SATURN].Radius), SLICES, STACKS );
  572.    glBindTexture(GL_TEXTURE_2D, texName[RINGS]);
  573.    glDisable(GL_CULL_FACE);
  574.    glDisable(GL_LIGHTING);
  575.    glEnable(GL_BLEND);
  576.    gluDisk(planets[SATURN].Object,
  577.            1.5*RADIUSSCALE(planets[SATURN].Radius),
  578.            1.9*RADIUSSCALE(planets[SATURN].Radius),
  579.            SLICES*2,1);
  580.    gluDisk(planets[SATURN].Object,
  581.            2.0*RADIUSSCALE(planets[SATURN].Radius),
  582.            2.2*RADIUSSCALE(planets[SATURN].Radius),
  583.            SLICES*2,1);
  584.    glDisable(GL_BLEND);        
  585.    glEnable(GL_LIGHTING);
  586.    glEnable(GL_CULL_FACE);
  587.    glEndList();
  588.  
  589.    for (i=TETHYS;i<=TITAN;i++) {
  590.        planets[i].Image = read_JPEG_file(filenames[i]);
  591.        if (!planets[i].Image) {
  592.           printf("Couldn't read image\n");
  593.           exit(0);
  594.        }
  595.  
  596.        glBindTexture(GL_TEXTURE_2D, texName[i]);
  597.        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  598.        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  599.        glTexImage2D( GL_TEXTURE_2D,
  600.                      0,
  601.                      3,
  602.                      128, 128,
  603.                      0,
  604.                      GL_RGB, GL_UNSIGNED_BYTE,
  605.                      planets[i].Image );
  606.        free(planets[i].Image);
  607.        planets[i].Object = gluNewQuadric();
  608.        gluQuadricTexture( planets[i].Object, GL_TRUE );   
  609.        planets[i].Sphere= glGenLists(1);
  610.        glNewList( planets[i].Sphere, GL_COMPILE );
  611.        gluSphere( planets[i].Object,RADIUSSCALE(planets[i].Radius), SLICES, STACKS );
  612.        glEndList();
  613.    }
  614.  
  615.  
  616. static void InitUranus(void)
  617. {
  618.    planets[URANUS].Radius=3.9;
  619.    planets[URANUS].Degrees=97.86;
  620.    planets[URANUS].DeltaRotation=0.0;
  621.    planets[URANUS].Rotation=360.0/0.71833;
  622.    planets[URANUS].Inclination=DEG2RAD(0.77343);
  623.    planets[URANUS].AscendingNode=DEG2RAD(74.0954);
  624.    planets[URANUS].Perihelion=DEG2RAD(175.6807);
  625.    planets[URANUS].MeanDistance=DISTCORRECTION(19.30181);
  626.    planets[URANUS].DailyMotion=DEG2RAD(0.01162295);
  627.    planets[URANUS].Eccentricity=0.0428959;
  628.    planets[URANUS].MeanLongitude=DEG2RAD(303.18967);
  629.    planets[URANUS].Sat=0;
  630.    sprintf(planets[URANUS].Name,"Uranus");
  631.  
  632.  
  633.    planets[URANUS].Image = read_JPEG_file(filenames[URANUS]);
  634.    if (!planets[URANUS].Image) {
  635.       printf("Couldn't read image\n");
  636.       exit(0);
  637.    }
  638.  
  639.    glBindTexture(GL_TEXTURE_2D, texName[URANUS]);
  640.    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  641.    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  642.    glTexImage2D( GL_TEXTURE_2D,
  643.                  0,
  644.                  3,
  645.                  128, 128,
  646.                  0,
  647.                  GL_RGB, GL_UNSIGNED_BYTE,
  648.                  planets[URANUS].Image );
  649.    free(planets[URANUS].Image);
  650.    planets[URANUS].Object = gluNewQuadric();
  651.    gluQuadricTexture( planets[URANUS].Object, GL_TRUE );   
  652.    planets[URANUS].Sphere= glGenLists(1);
  653.    glNewList( planets[URANUS].Sphere, GL_COMPILE );
  654.    gluSphere( planets[URANUS].Object,RADIUSSCALE(planets[URANUS].Radius), SLICES, STACKS );
  655.    glEndList();
  656.  
  657.     
  658.  
  659.  
  660. static void InitNeptune(void)
  661. {
  662.    planets[NEPTUNE].Radius=4.0;
  663.    planets[NEPTUNE].Degrees=29.0;
  664.    planets[NEPTUNE].DeltaRotation=0.0;
  665.    planets[NEPTUNE].Rotation=360.0/0.67125;
  666.    planets[NEPTUNE].Inclination=DEG2RAD(1.7681);
  667.    planets[NEPTUNE].AscendingNode=DEG2RAD(131.7925);
  668.    planets[NEPTUNE].Perihelion=DEG2RAD(7.206);
  669.    planets[NEPTUNE].MeanDistance=DISTCORRECTION(30.26664);
  670.    planets[NEPTUNE].DailyMotion=DEG2RAD(0.005919282);
  671.    planets[NEPTUNE].Eccentricity=0.0102981;
  672.    planets[NEPTUNE].MeanLongitude=DEG2RAD(299.8641);
  673.    planets[NEPTUNE].Sat=0;
  674.    sprintf(planets[NEPTUNE].Name,"Neptune");
  675.  
  676.    planets[TRITON].Radius=1353.0/6378.0;
  677.    planets[TRITON].Degrees=0.0;
  678.    planets[TRITON].DeltaRotation=0.0;
  679.    planets[TRITON].Rotation=360.0/5.876854;
  680.    planets[TRITON].Inclination=DEG2RAD(157.0);
  681.    planets[TRITON].Sat=NEPTUNE;
  682.    sprintf(planets[TRITON].Name,"Triton");
  683.  
  684.  
  685.  
  686.    planets[NEPTUNE].Image = read_JPEG_file(filenames[NEPTUNE]);
  687.    if (!planets[NEPTUNE].Image) {
  688.       printf("Couldn't read image\n");
  689.       exit(0);
  690.    }
  691.  
  692.    glBindTexture(GL_TEXTURE_2D, texName[NEPTUNE]);
  693.    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  694.    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  695.    glTexImage2D( GL_TEXTURE_2D,
  696.                  0,
  697.                  3,
  698.                  128, 128,
  699.                  0,
  700.                  GL_RGB, GL_UNSIGNED_BYTE,
  701.                  planets[NEPTUNE].Image );
  702.    free(planets[NEPTUNE].Image);
  703.    planets[NEPTUNE].Object = gluNewQuadric();
  704.    gluQuadricTexture( planets[NEPTUNE].Object, GL_TRUE );   
  705.    planets[NEPTUNE].Sphere= glGenLists(1);
  706.    glNewList( planets[NEPTUNE].Sphere, GL_COMPILE );
  707.    gluSphere( planets[NEPTUNE].Object,RADIUSSCALE(planets[NEPTUNE].Radius), SLICES, STACKS );
  708.    glEndList();
  709.  
  710.  
  711.    planets[TRITON].Image = read_JPEG_file(filenames[TRITON]);
  712.    if (!planets[TRITON].Image) {
  713.       printf("Couldn't read image\n");
  714.       exit(0);
  715.    }
  716.  
  717.    glBindTexture(GL_TEXTURE_2D, texName[TRITON]);
  718.    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  719.    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  720.    glTexImage2D( GL_TEXTURE_2D,
  721.                  0,
  722.                  3,
  723.                  128, 128,
  724.                  0,
  725.                  GL_RGB, GL_UNSIGNED_BYTE,
  726.                  planets[TRITON].Image );
  727.    free(planets[TRITON].Image);
  728.    planets[TRITON].Object = gluNewQuadric();
  729.    gluQuadricTexture( planets[TRITON].Object, GL_TRUE );   
  730.    planets[TRITON].Sphere= glGenLists(1);
  731.    glNewList( planets[TRITON].Sphere, GL_COMPILE );
  732.    gluSphere( planets[TRITON].Object,RADIUSSCALE(planets[TRITON].Radius), SLICES, STACKS );
  733.    glEndList();
  734.  
  735.  
  736.     
  737.  
  738.  
  739. static void InitPluto(void)
  740. {
  741.    planets[PLUTO].Radius=0.45;
  742.    planets[PLUTO].Degrees=118.0;
  743.    planets[PLUTO].DeltaRotation=0.0;
  744.    planets[PLUTO].Rotation=360.0/6.3872;
  745.    planets[PLUTO].Inclination=DEG2RAD(17.12137);
  746.    planets[PLUTO].AscendingNode=DEG2RAD(110.3833);
  747.    planets[PLUTO].Perihelion=DEG2RAD(224.8025);
  748.    planets[PLUTO].MeanDistance=DISTCORRECTION(39.5804);
  749.    planets[PLUTO].DailyMotion=DEG2RAD(0.003958072);
  750.    planets[PLUTO].Eccentricity=0.2501272;
  751.    planets[PLUTO].MeanLongitude=DEG2RAD(235.7656);
  752.    planets[PLUTO].Sat=0;
  753.    sprintf(planets[PLUTO].Name,"Pluto");
  754.  
  755.    planets[CHARON].Radius=593.0/6378.0;
  756.    planets[CHARON].Degrees=0.0;
  757.    planets[CHARON].DeltaRotation=0.0;
  758.    planets[CHARON].Rotation=360.0/6.38725;
  759.    planets[CHARON].Inclination=DEG2RAD(99.0);   
  760.    planets[CHARON].Sat=PLUTO;
  761.    sprintf(planets[CHARON].Name,"Charon");
  762.  
  763.  
  764.    planets[PLUTO].Image = read_JPEG_file(filenames[PLUTO]);
  765.    if (!planets[PLUTO].Image) {
  766.       printf("Couldn't read image\n");
  767.       exit(0);
  768.    }
  769.  
  770.    glBindTexture(GL_TEXTURE_2D, texName[PLUTO]);
  771.    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  772.    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  773.    glTexImage2D( GL_TEXTURE_2D,
  774.                  0,
  775.                  3,
  776.                  128, 128,
  777.                  0,
  778.                  GL_RGB, GL_UNSIGNED_BYTE,
  779.                  planets[PLUTO].Image );
  780.    free(planets[PLUTO].Image);
  781.    planets[PLUTO].Object = gluNewQuadric();
  782.    gluQuadricTexture( planets[PLUTO].Object, GL_TRUE );   
  783.    planets[PLUTO].Sphere= glGenLists(1);
  784.    glNewList( planets[PLUTO].Sphere, GL_COMPILE );
  785.    gluSphere( planets[PLUTO].Object,RADIUSSCALE(planets[PLUTO].Radius), SLICES, STACKS );
  786.    glEndList();
  787.  
  788.  
  789.    planets[CHARON].Image = read_JPEG_file(filenames[CHARON]);
  790.    if (!planets[CHARON].Image) {
  791.       printf("Couldn't read image\n");
  792.       exit(0);
  793.    }
  794.  
  795.    glBindTexture(GL_TEXTURE_2D, texName[CHARON]);
  796.    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  797.    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  798.    glTexImage2D( GL_TEXTURE_2D,
  799.                  0,
  800.                  3,
  801.                  128, 128,
  802.                  0,
  803.                  GL_RGB, GL_UNSIGNED_BYTE,
  804.                  planets[CHARON].Image );
  805.    free(planets[CHARON].Image);
  806.    planets[CHARON].Object = gluNewQuadric();
  807.    gluQuadricTexture( planets[CHARON].Object, GL_TRUE );   
  808.    planets[CHARON].Sphere= glGenLists(1);
  809.    glNewList( planets[CHARON].Sphere, GL_COMPILE );
  810.    gluSphere( planets[CHARON].Object,RADIUSSCALE(planets[CHARON].Radius), SLICES, STACKS );
  811.    glEndList();
  812.     
  813.  
  814.  
  815.  
  816. static void InitStars(void)
  817.    static char line[100],*tmp;
  818.    FILE *f;
  819.    static float ascention,declination,magnitude;
  820.    int i;
  821.    
  822.    f=fopen("Stars.dat","rt");
  823.    for (i=0;i<NUMSTARS;i++) {
  824.     fgets(line,100,f);
  825.     if (feof(f)) break;
  826.     while (line[0]=='#') fgets(line,100,f);
  827.     tmp=line;
  828.     while (tmp[0]!=',') tmp++;
  829.     *tmp='\0';
  830.     tmp++;
  831.     red=0;
  832.     /* Print some stars in red color for testing */
  833.     if (!strcmp(line,"Polaris")) { red=1; polaris=i; }
  834.     if (!strcmp(line,"Dubhe")) red=1;
  835.     if (!strcmp(line,"Merak")) red=1;
  836.     if (!strcmp(line,"Phecda")) red=1;
  837.     if (!strcmp(line,"Megrez")) red=1;
  838.     if (!strcmp(line,"Alioth")) red=1;
  839.     if (!strcmp(line,"Mizar")) red=1;
  840.     sscanf(tmp,"%f,%f,%f\n",&ascention,&declination,&magnitude);
  841.     stars[i][0]=DISTCORRECTION(500.0)*cos(-ascention)*cos(declination);
  842.     stars[i][1]=DISTCORRECTION(500.0)*sin(declination);
  843.     stars[i][2]=DISTCORRECTION(500.0)*sin(-ascention)*cos(declination);
  844.     magnitude=sqrt(1.0/(1.46+magnitude));
  845.     if (red) magnitude=-magnitude;
  846.     stars[i][3]=magnitude;
  847.    }
  848.    fclose(f);
  849.  
  850.    Stars = glGenLists(1);
  851.    glNewList( Stars, GL_COMPILE );
  852.    glBegin(GL_POINTS);
  853.    magnitude=1.0;
  854.    for (i=0;i<NUMSTARS;i++) {
  855.        /* Since star catalog is sorted by magnitude and there are many stars
  856.           with the same magnitude this will avoid extra calls to glColor */
  857.     if (magnitude!=stars[i][3]) {
  858.         glColor3f(stars[i][3],stars[i][3],stars[i][3]);
  859.         magnitude=stars[i][3];
  860.     }
  861.     if (stars[i][3]<0) glColor3f(1.0,0.0,0.0);
  862.     glVertex3f(stars[i][0],stars[i][1],stars[i][2]);
  863.    }
  864.    glEnd();
  865.    glEndList();
  866. }
  867.  
  868.  
  869. /***************************************************************/
  870. /* JPEG DECOMPRESSION CODE TAKEN FROM JPEG LIBRARY SAMPLE CODE */
  871. /***************************************************************/
  872. struct my_error_mgr {
  873.   struct jpeg_error_mgr pub;    /* "public" fields */
  874.  
  875.   jmp_buf setjmp_buffer;    /* for return to caller */
  876. };
  877.  
  878. typedef struct my_error_mgr * my_error_ptr;
  879.  
  880. /*
  881.  * Here's the routine that will replace the standard error_exit method:
  882.  */
  883.  
  884. METHODDEF(void)
  885. my_error_exit (j_common_ptr cinfo)
  886. {
  887.   /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
  888.   my_error_ptr myerr = (my_error_ptr) cinfo->err;
  889.  
  890.   /* Always display the message. */
  891.   /* We could postpone this until after returning, if we chose. */
  892.   (*cinfo->err->output_message) (cinfo);
  893.  
  894.   /* Return control to the setjmp point */
  895.   longjmp(myerr->setjmp_buffer, 1);
  896. }
  897.  
  898.  
  899. /*
  900.  * Sample routine for JPEG decompression.  We assume that the source file name
  901.  * is passed in.  We want to return 1 on success, 0 on error.
  902.  */
  903.  
  904.  
  905. GLubyte *read_JPEG_file (char * fname)
  906. {
  907.   /* This struct contains the JPEG decompression parameters and pointers to
  908.    * working space (which is allocated as needed by the JPEG library).
  909.    */
  910.   struct jpeg_decompress_struct cinfo;
  911.   /* We use our private extension JPEG error handler.
  912.    * Note that this struct must live as long as the main JPEG parameter
  913.    * struct, to avoid dangling-pointer problems.
  914.    */
  915.   struct my_error_mgr jerr;
  916.   /* More stuff */
  917.   FILE * infile;        /* source file */
  918.   JSAMPARRAY buffer;        /* Output row buffer */
  919.   int row_stride;        /* physical row width in output buffer */
  920.   long cont;
  921.   JSAMPLE *image_buffer;
  922.   char filename[128];
  923.   
  924.   /* In this example we want to open the input file before doing anything else,
  925.    * so that the setjmp() error recovery below can assume the file is open.
  926.    * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
  927.    * requires it in order to read binary files.
  928.    */
  929.  
  930.   sprintf(filename,"%s/%s",texturepath,fname);
  931.   if ((infile = fopen(filename, "rb")) == NULL) {
  932.     fprintf(stderr, "can't open %s\n", filename);
  933.     return NULL;
  934.   }
  935.  
  936.   /* Step 1: allocate and initialize JPEG decompression object */
  937.  
  938.   /* We set up the normal JPEG error routines, then override error_exit. */
  939.   cinfo.err = jpeg_std_error(&jerr.pub);
  940.   jerr.pub.error_exit = my_error_exit;
  941.   /* Establish the setjmp return context for my_error_exit to use. */
  942.   if (setjmp(jerr.setjmp_buffer)) {
  943.     /* If we get here, the JPEG code has signaled an error.
  944.      * We need to clean up the JPEG object, close the input file, and return.
  945.      */
  946.     jpeg_destroy_decompress(&cinfo);
  947.     fclose(infile);
  948.     return NULL;
  949.   }
  950.   /* Now we can initialize the JPEG decompression object. */
  951.   jpeg_create_decompress(&cinfo);
  952.  
  953.   /* Step 2: specify data source (eg, a file) */
  954.  
  955.   jpeg_stdio_src(&cinfo, infile);
  956.  
  957.   /* Step 3: read file parameters with jpeg_read_header() */
  958.  
  959.   (void) jpeg_read_header(&cinfo, TRUE);
  960.   /* We can ignore the return value from jpeg_read_header since
  961.    *   (a) suspension is not possible with the stdio data source, and
  962.    *   (b) we passed TRUE to reject a tables-only JPEG file as an error.
  963.    * See libjpeg.doc for more info.
  964.    */
  965.  
  966.   /* Step 4: set parameters for decompression */
  967.  
  968.   /* In this example, we don't need to change any of the defaults set by
  969.    * jpeg_read_header(), so we do nothing here.
  970.    */
  971.  
  972.   /* Step 5: Start decompressor */
  973.  
  974.   (void) jpeg_start_decompress(&cinfo);
  975.   /* We can ignore the return value since suspension is not possible
  976.    * with the stdio data source.
  977.    */
  978.  
  979.   /* We may need to do some setup of our own at this point before reading
  980.    * the data.  After jpeg_start_decompress() we have the correct scaled
  981.    * output image dimensions available, as well as the output colormap
  982.    * if we asked for color quantization.
  983.    * In this example, we need to make an output work buffer of the right size.
  984.    */ 
  985.   /* JSAMPLEs per row in output buffer */
  986.   row_stride = cinfo.output_width * cinfo.output_components;
  987.   /* Make a one-row-high sample array that will go away when done with image */
  988.   buffer = (*cinfo.mem->alloc_sarray)
  989.         ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
  990.  
  991.   /* Step 6: while (scan lines remain to be read) */
  992.   /*           jpeg_read_scanlines(...); */
  993.  
  994.   /* Here we use the library's state variable cinfo.output_scanline as the
  995.    * loop counter, so that we don't have to keep track ourselves.
  996.    */
  997.  
  998.  image_buffer=(JSAMPLE *) malloc(cinfo.image_width*cinfo.image_height*3);
  999.  
  1000.  
  1001.   
  1002.   cont=cinfo.output_height-1;
  1003.   while (cinfo.output_scanline < cinfo.output_height) {
  1004.     /* jpeg_read_scanlines expects an array of pointers to scanlines.
  1005.      * Here the array is only one element long, but you could ask for
  1006.      * more than one scanline at a time if that's more convenient.
  1007.      */
  1008.     (void) jpeg_read_scanlines(&cinfo, buffer, 1);
  1009.     /* Assume put_scanline_someplace wants a pointer and sample count. */
  1010.     /* put_scanline_someplace(buffer[0], row_stride); */
  1011.     memcpy(image_buffer+cinfo.image_width*3*cont,buffer[0],row_stride);
  1012.     cont--;
  1013.   }
  1014.  
  1015.   /* Step 7: Finish decompression */
  1016.  
  1017.   (void) jpeg_finish_decompress(&cinfo);
  1018.   /* We can ignore the return value since suspension is not possible
  1019.    * with the stdio data source.
  1020.    */
  1021.  
  1022.   /* Step 8: Release JPEG decompression object */
  1023.  
  1024.   /* This is an important step since it will release a good deal of memory. */
  1025.   jpeg_destroy_decompress(&cinfo);
  1026.  
  1027.   /* After finish_decompress, we can close the input file.
  1028.    * Here we postpone it until after no more JPEG errors are possible,
  1029.    * so as to simplify the setjmp error logic above.  (Actually, I don't
  1030.    * think that jpeg_destroy can do an error exit, but why assume anything...)
  1031.    */
  1032.   fclose(infile);
  1033.  
  1034.   /* At this point you may want to check to see whether any corrupt-data
  1035.    * warnings occurred (test whether jerr.pub.num_warnings is nonzero).
  1036.    */
  1037.  
  1038.   /* And we're done! */
  1039.   return image_buffer;
  1040. }
  1041.  
  1042.  
  1043.