[ Home  |  FAQ-Related Q&As  |  General Q&As  |  Answered Questions ]


    Search the Q&A Archives


Hello, I'm trying to build some program under Microsoft...

<< Back to: JPEG image compression FAQ, part 1/2

Question by cjmn
Submitted on 5/3/2005
Related FAQ: JPEG image compression FAQ, part 1/2
Rating: Not yet rated Rate this question: Vote
Hello,
I'm trying to build some program under Microsoft Visual C++ 6.0 using externals functions
contained in the "libjpeg.h" library and I can't make the link edit to generate the executable
module after compilation of source without error. The message errors I've seem like this :

"terrain.obj : error LNK2001 : unresolved external symbol" for the functions below :

01 - _jpeg_std_error;               02 - _jpeg_CreateDecompress
03- _jpeg_stdio_src                  04 - _jpeg_read_header
05- _jpeg_start_decompress   06 - _jpeg_read_scanlines
07- _jpeg_finish_decompress  08 - _jpeg_destroy_decompress

and after I have this message : "Debug/terrain.exe fatal error LNK1120 8 unresolved externals"

I don't know what happen under Windows XP... With OpenGL under Linux, the same program is
running very well.

Please help...

CJMN
N.B. you have the program source below :

/*************************************************************/
/*   terrain.c                     */
/*************************************************************/
/* Génération de terrain à partir d'uneimage JPEG           */
/*************************************************************/

/*    inclusion des fichiers d'entête Glut                  */

#include <GL/glut.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <jpeglib.h>
#include <jerror.h>

#define NB_SUBDIV_INIT 32
#define NB_SUBDIV_MAX 64
#define ECHELLE_VERT_INIT 0.3
#define ECHELLE_VERT_MAX 1.0
#define DISTANCE_INIT 4.0
#define DISTANCE_MAX 15.0


/* Variables globales   */

unsigned char image[256][256];         /* l'imagedu terrain            */
unsigned char afficheRepere = TRUE;      /* Affichage du repère            */
unsigned char faceArriere   = FALSE;      /* Affichage des faces arrieres de polygones   */
unsigned char areteTransv   = FALSE;      /* Affichage de l'arêtetransversale      */
int repere, terrain;            /* Identifiants des listes d'affichage   */
int nbSubdiv = NB_SUBDIV_INIT;         /* Nombre de subdivision du maillage      */
float echelleVert = ECHELLE_VERT_INIT;      /* echelle verticale du relief         */
char b_gauche = 0, b_droit = 0;         /* bouton de souris presse ?         */
int theta = -30, phi = 300;         /* Position de l'observateur      */
int xprec, yprec;            /* sauvegarde de la position de la souris   */
float distance = DISTANCE_INIT;         /* distance de l'observateurà l'origine*/

/* Prototype des fonctions */

void init();
void affichage(void);
void clavier(unsigned char touche, int x, int y);
void souris(int bouton, int etat, int x, int y);
void mouvement(int x, int y);
void redim(int l, int h);
void creeRepere();
void creeTerrain();
float elevation(int i, int j);
void loadJpegImage(char *filename);


/* **********************************************/
/*    int main(int argc, char **argv          */
/************************************************/
/*        fonction principale      */
/************************************************/

int main(int argc, char **argv)
{
   /* initialisation de glut et creation
      de la fenetre OpenGL   */

   glutInit(&argc, argv);
   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
   glutInitWindowSize(500, 500);
   glutCreateWindow(argv[0]);
   
   /* initialisation d'OpenGL   */
      
   init();
   loadJpegImage(argv[1]);
   
   /* Creation des objets          */
   
   creeRepere();
   creeTerrain();
   
   /* Entrée dans la boucle principale glut */

   glutMainLoop();
   return 0;
}
   
/********************************************************/
/*   void init()               */
/********************************************************/
/* Fonction d'nitialisationd'OpenGL         */
/********************************************************/
   
void init()
{
   glClearColor(0.8, 0.8, 0.8, 1.0);
   glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
   glCullFace(GL_BACK);
      
   if (faceArriere)
      glDisable(GL_CULL_FACE);
   else
      glEnable(GL_CULL_FACE);

   /* Mise en place de la perspective         */
   
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   gluPerspective(45.0, 1.0, 0.1, 20.0);
   glMatrixMode(GL_MODELVIEW);
         
   /* Mise en place des fonctions de rappel glut */

   glutDisplayFunc(affichage);
   glutKeyboardFunc(clavier);
   glutMouseFunc(souris);
   glutMotionFunc(mouvement);
   glutReshapeFunc(redim);
}
      
/********************************************************/
/*   void affichage()            */
/********************************************************/
/* fonction de rappel pour l'affichage      */
/********************************************************/
      
void affichage()
{
   glClear(GL_COLOR_BUFFER_BIT);   
   glLoadIdentity();
   gluLookAt(0.0, 0.0, distance, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
   glRotatef(phi, 1.0, 0.0, 0.0);
   glRotatef(theta, 0.0, 0.0, 1.0);
   glCallList(terrain);
   //   
   if (afficheRepere)
      glCallList(repere);
   
   /* On echange les buffers ou zones tampons */
   
   glutSwapBuffers();
}

/********************************************************/
/*   void clavier()               */
/********************************************************/
/* fonction de rappel clavier            */
/********************************************************/

void clavier(unsigned char touche, int x, int y)
   {
   switch (touche)
      {
   
      case 27:   /* touche 'ESC' pour quitter      */
      exit(0);

      case '+':    /* augmentation du nombre de subdivisions   */
      
         nbSubdiv++;
         if (nbSubdiv > NB_SUBDIV_MAX)
               nbSubdiv = NB_SUBDIV_MAX;
         creeTerrain();
         glutPostRedisplay();
         break;
      
      case '-':    /* dimunition du nombre de subdivisions      */
      
         nbSubdiv--;
         if (nbSubdiv < 1)
               nbSubdiv = 1;
         creeTerrain();
         glutPostRedisplay();
         break;
                  
      case 'p':   /* augmentation de l'echelleverticale      */
   
         echelleVert += 0.2;
         if (echelleVert > ECHELLE_VERT_MAX)
               echelleVert = ECHELLE_VERT_MAX;
         creeTerrain();
         glutPostRedisplay();
         break;

      case 'o':   /* diminution de l'echelleverticale       */
      
         echelleVert -= 0.2;
         if (echelleVert < -ECHELLE_VERT_MAX)
               echelleVert = -ECHELLE_VERT_MAX;
         creeTerrain();
         glutPostRedisplay();
         break;

      case 'r':   /* Affichage du repere ON/OFF          */
      
         afficheRepere = 1 - afficheRepere;
         glutPostRedisplay();
         break;

      case 'c':   /* affichage des faces arrières ON/OFF       */
      
         faceArriere = 1 - faceArriere;
         if (faceArriere)
            glDisable(GL_CULL_FACE);
         else
            glEnable(GL_CULL_FACE);
         glutPostRedisplay();
         break;
      
      case 't':   /* Affichage des aretes transversales       */
      
         areteTransv = 1 - areteTransv;
         creeTerrain();
         glutPostRedisplay();
         break;
   }
}


/********************************************************/
/*   void souris(int bouton, int etat, int x, int y)      */
/********************************************************/
/* fonction de rappel pour l'appuisur bouton de souris   */
/********************************************************/

void souris(int bouton, int etat, int x, int y)
{
   if (bouton == GLUT_LEFT_BUTTON &&etat == GLUT_DOWN)

      {
         b_gauche = 1;      /* le booleen presse passe à 1 (vrai)   */
         xprec = x;      /* on sauvegarde la position de la souris   */
         yprec = y;
      }

   if (bouton == GLUT_LEFT_BUTTON &&etat == GLUT_UP)
         b_gauche = 0;      /* le booleen presse passe à 0 (faux)   */

   if (bouton == GLUT_RIGHT_BUTTON &&etat == GLUT_DOWN)
      {
         b_droit = 1;      /* le booleen presse passe à 1 (vrai)   */
         yprec = y;
      }

   if (bouton == GLUT_RIGHT_BUTTON &&etat == GLUT_UP)
         b_droit = 0;      /* le booleen presse passe à 0 (faux)   */
}

/********************************************************/
/*   void mouvement(int x, int y)         */
/********************************************************/
/* fonction de rappel pour les mouvements de souris   */
/********************************************************/

void mouvement(int x, int y)
{
   /* si le bouton gauche est pressé   */
   
   if (b_gauche)
      {
            theta += x - xprec;
            //
            if (theta >= 360)
               while (theta >360)
                  theta -= 360;
            phi += y - yprec;
            //
            if (phi < 0)
               while (phi < 0)
                  phi += 360;
            //
            xprec = x;         /* sauvegarde des valeurs courantes de la position de la souris */
            yprec = y;
            //
            glutPostRedisplay();   /* on demande un rafraichissement de l'affichage*/
      }

   /* si le bouton droit est pressé   */
   
   if (b_droit)
      {
         distance += ((float)(y - yprec))/10.0;

         if (distance < 1.0)
               distance = 1.0;

         if (distance > DISTANCE_MAX)
               distance = DISTANCE_MAX;

            
         glutPostRedisplay();   /* on demande un rafraichissement de l'affichage*/
         yprec = y;
      }
      
}

/****************************************************************/
/*   void redim(int l, int h)            */
/****************************************************************/
/* fonction de rappel pour le redimensinnement de la fenêtre   */
/****************************************************************/

void redim(int l, int h)
{
   if (l < h)
     glViewport(0, (h-l)/2, l, l);
   else
     glViewport((l-h)/2, 0, h, h);
}

/********************************************************/
/*   void inactif               */
/********************************************************/
/* fonction de rappel pour l'inactivité(idle)      */
/********************************************************/
/*
void inactif()
{
   /* increment du decalage      */
/*
   decalage += 0.1;
   if (decalage > 2*PI);
      decalage -= 2*PI;

   /* rechargement de la texture      */
/*
   chargeTextureProc(IdTex[1]);
   glutPostRedisplay();
}
*/

/********************************************************/
/*   void creeRepere()            */
/********************************************************/
/*  chréation de la liste d'affichagepour      */
/*   le repere               */
/********************************************************/

void creeRepere()
{
   repere = glGenLists(1);
   glNewList(repere, GL_COMPILE);
   glLineWidth(2.0);
   //
      glBegin(GL_LINES);
         glColor3f (1.0, 0.0, 0.0);
         glVertex3f(0.0, 0.0, 0.0);
         glVertex3f(0.3, 0.0, 0.0);
         glColor3f (0.0, 1.0, 0.0);
         glVertex3f(0.0, 0.0, 0.0);
         glVertex3f(0.0, 0.3, 0.0);
         glColor3f (0.0, 0.0, 1.0);
         glVertex3f(0.0, 0.0, 0.0);
         glVertex3f(0.0, 0.0, 0.3);
      glEnd();
   //
   glEndList();
}

/********************************************************/
/*   void creeTerrain            */
/********************************************************/
/*  Création de la liste d'affichagepour       */
/*   le terrain               */
/********************************************************/

void creeTerrain()
{
   int i, j;
   float pas = 2.0 / nbSubdiv;
   float P1[3], P2[3], P3[3], P4[3];
   
   /* Liste pour l'objetterrain         */
                     
   if (glIsList(terrain))
      glDeleteLists(terrain, 1);
   terrain = glGenLists(1);
   //
   glNewList(terrain, GL_COMPILE);
   glColor3f(0.0, 0.0, 0.0);
   glLineWidth(1.0);
   //
   for (i = 0; i < nbSubdiv; i++)
      for (j = 0; j < nbSubdiv; j++)
         {
            P1[0] =- 1.0 + i*pas;      P1[1] =- 1.0 + j*pas;      P1[2] = elevation(i, j);
            P2[0] =- 1.0 + (i + 1)*pas;   P2[1] =- 1.0 + j*pas;      P2[2] = elevation(i + 1, j);
            P3[0] =- 1.0 + (i + 1)*pas;   P3[1] =- 1.0 + (j + 1)*pas;   P3[2] = elevation(i + 1, j + 1);
            P4[0] =- 1.0 + i*pas;      P4[1] =- 1.0 + (j + 1)*pas;   P4[2] = elevation(i, j + 1);
            //
            glBegin(GL_TRIANGLES);
            //
            /* triangle 1   */
            //
            glEdgeFlag(TRUE);
            glVertex3fv(P1);
            glVertex3fv(P2);
            //
            if (!areteTransv)
               glEdgeFlag(FALSE);
            glVertex3fv(P3);
            //
            /* triangle 2   */
            //
            glVertex3fv(P1);
            //
            if (!areteTransv)
               glEdgeFlag(TRUE);
            glVertex3fv(P3);
            glVertex3fv(P4);
            glEnd();
         }
      glEndList();
}

/********************************************************/
/*   Calcul de la hauteur d'unpoint       */
/********************************************************/

float elevation(int i, int j)
{
   int valeur = image[(int) ((float)i / nbSubdiv*255)][(int)((float)j / nbSubdiv*255)];
   return ((float)valeur / 128.0 - 1.0)*echelleVert;
}

/********************************************************/
/*   void loadJpegImage(char *filename)      */
/********************************************************/
/*  Chargement d'uneimage jpeg            */
/********************************************************/

void loadJpegImage(char *filename)
{
   FILE *file;
   struct jpeg_decompress_struct cinfo;
   struct jpeg_error_mgr jerr;
   unsigned char *im = (unsigned char *)image, *ligne;
            
   cinfo.err = jpeg_std_error(&jerr);
   jpeg_create_decompress(&cinfo);
   
   /* On met en place une image par défaut si filename = NULL   */
   
   if (filename == NULL)
   {
      filename = (char *)malloc(128);
      strcpy(filename, "terrain.jpg");
   }
   //
   if (!(file = fopen(filename, "rb")))
   {
      fprintf(stderr, "Erreur : impossible d'ouvrir%s\n", filename);
      exit(1);
   }
         
   jpeg_stdio_src(&cinfo, file);
   jpeg_read_header(&cinfo, TRUE);
   //   
   if ((cinfo.image_width != 256) || (cinfo.image_height != 256))
   {
      fprintf(stderr, "Erreur : l'imagedoit être de taille 256 x 256 \n");
      exit(1);
   }
      
   jpeg_start_decompress(&cinfo);
//   ligne = image;
      
   while (cinfo.output_scanline < 256)
   {
      ligne = im + 256*cinfo.output_scanline;
      jpeg_read_scanlines(&cinfo, &ligne, 1);
   }
      
   jpeg_finish_decompress(&cinfo);
   jpeg_destroy_decompress(&cinfo);
}


Your answer will be published for anyone to see and rate.  Your answer will not be displayed immediately.  If you'd like to get expert points and benefit from positive ratings, please create a new account or login into an existing account below.


Your name or nickname:
If you'd like to create a new account or access your existing account, put in your password here:
Your answer:

FAQS.ORG reserves the right to edit your answer as to improve its clarity.  By submitting your answer you authorize FAQS.ORG to publish your answer on the WWW without any restrictions. You agree to hold harmless and indemnify FAQS.ORG against any claims, costs, or damages resulting from publishing your answer.

 

FAQS.ORG makes no guarantees as to the accuracy of the posts. Each post is the personal opinion of the poster. These posts are not intended to substitute for medical, tax, legal, investment, accounting, or other professional advice. FAQS.ORG does not endorse any opinion or any product or service mentioned mentioned in these posts.

 

<< Back to: JPEG image compression FAQ, part 1/2


[ Home  |  FAQ-Related Q&As  |  General Q&As  |  Answered Questions ]

© 2008 FAQS.ORG. All rights reserved.