Need some suggestion about reading and displaying an image file

Hello, I would like to read a jpeg file and display the pixel using glColor3f. I have extracted the pixel dimension from the image.
Now my quetion is pixelWidth by pixelHeight are the number of bytes. I should deduct that number from the whole amount of bytes and then should I just start reading the bytes (unsigned char) and try to display it?
Please provide me some suggestion.
Thanks in advance.

Now my quetion is pixelWidth by pixelHeight are the number of bytes.

That would only be true for an image with a single channel and no compression. More common would be 3-4 channels (RGB, RGBA) and compression, hence use libjpeg to read the image from disk, or use a multi image format loader library, e.g. OpenImageIO, DevIL.

DevIL is a good image loader library

As i need to manipulate the pixel value and I have already started coding in C, I just need the information from where the image data starts i.e. what is the marker for that as I already have the width and height of the image. It would be good if you provide some suggestions regarding this.

These libs will give you access to uncompressed pixels if you need to modify the image. You really don’t want to write your own jpeg decoder…

You can too use libTIFF http://www.libtiff.org/ , libTGA http://tgalib.sourceforge.net/ or libJPEG http://libjpeg.sourceforge.net/ but DevIL is very more generic and work really very well for loading various images files formats into OpenGL textures such as listed at http://openil.sourceforge.net/features.php

Generally, an image file format is a very more complex thing that only a marker where begin a single succession of height lines of width columns of 8 bits gray pixels …
(pixels can be stored on 1/2/4/8 bits on B/W, RGB, RGBA, GRAY or PALETTE INDICES, on form of lines, planes, strips, tiles and patchs … and all this with a lot of various compression schemes)
=> take a look at http://en.wikipedia.org/wiki/Image_file_formats for to have an idea of the number of differences that you can find between two images files formats …

I tried to look at libjpeg website, but didn’t find any particular direction/ example about the use of it. Please provide me some suggestions.

[QUOTE=jenny_wui;1250285]I tried to look at libjpeg website, but didn’t find any particular direction/ example about the use of it. Please provide me some suggestions.[/QUOTE]I have also found DevIL to be fairly easy to use. They give you examples. Like you, I am inputting images, combining them according to some complex rules, and displaying the result on the screen. So I need access to the RGB values of every pixel.

You can find DevIL tutorials at http://openil.sourceforge.net/tuts/tut_step/index.htm, http://openil.sourceforge.net/tuts/tut_5/index.htm or http://content.gpwiki.org/index.php/DevIL:Tutorials:Basics

Or only google “devil opengl tutorial” for to find a lot more DevIL’s tutorials
(I find the link http://content.gpwiki.org/index.php/DevIL:Tutorials:Basics very didactic, you can easily replace the SDL part by the GLUT equivalent for example)

Here a very simple example using DevIL and GLUT :
(it’s only a fast port from SDL to GLUT of the last link)


#include <IL/il.h>
#include <GL/glut.h>

int width  = 640;
int height = 480;


/* Initialize OpenGL Graphics */
void initGL() 
{
     glViewport(0, 0, width, height);
     glEnable(GL_TEXTURE_2D);
     glMatrixMode(GL_PROJECTION);
     glLoadIdentity();
     glOrtho(0.0, width, height, 0.0, 0.0, 100.0);
     glMatrixMode(GL_MODELVIEW);
     glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
     glClearDepth(0.0f);
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
/* Handler for window-repaint event. Called back when the window first appears and
   whenever the window needs to be re-painted. */
void display() 
{
    // Clear color and depth buffers
       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
       glMatrixMode(GL_MODELVIEW);     // Operate on model-view matrix

    /* Draw a quad */
       glBegin(GL_QUADS);
           glTexCoord2i(0, 0); glVertex2i(0,   0);
           glTexCoord2i(0, 1); glVertex2i(0,   height);
           glTexCoord2i(1, 1); glVertex2i(width, height);
           glTexCoord2i(1, 0); glVertex2i(width, 0);
       glEnd();

    glutSwapBuffers();
} 

/* Handler for window re-size event. Called back when the window first appears and
   whenever the window is re-sized with its new width and height */
void reshape(GLsizei newwidth, GLsizei newheight) 
{  
    // Set the viewport to cover the new window
       glViewport(0, 0, width=newwidth, height=newheight);
     glMatrixMode(GL_PROJECTION);
     glLoadIdentity();
     glOrtho(0.0, width, height, 0.0, 0.0, 100.0);
     glMatrixMode(GL_MODELVIEW);
    glutPostRedisplay();
}

/* Load an image using DevIL and return the devIL handle (-1 if failure) */
int LoadImage(char *filename)
{
    ILboolean success; 
     ILuint image; 

    ilGenImages(1, &image); /* Generation of one image name */
     ilBindImage(image); /* Binding of image name */
     success = ilLoadImage(filename); /* Loading of the image filename by DevIL */
     
    if (success) /* If no error occured: */
    {
        /* Convert every colour component into unsigned byte. If your image contains alpha channel you can replace IL_RGB with IL_RGBA */
           success = ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE); 
   
        if (!success)
           {
                 return -1;
           }
    }
    else
        return -1;

    return image;
}
  

int main(int argc, char **argv) 
{

    GLuint texid;
    int    image;

    if ( argc < 1)
    {
        /* no image file to  display */
        return -1;
    }

     if (ilGetInteger(IL_VERSION_NUM) < IL_VERSION)
     {
           printf("wrong DevIL version 
");
           return -1;
     }

    /* Initialization of DevIL */
     ilInit(); 

    /* load the file picture with DevIL */
    image = LoadImage(argv[1]);
    if ( image == -1 )
    {
        printf("Can't load picture file %s by DevIL 
", argv[1]);
        return -1;
    }

    /* GLUT init */
    glutInit(&argc, argv);            // Initialize GLUT
       glutInitDisplayMode(GLUT_DOUBLE); // Enable double buffered mode
       glutInitWindowSize(640, 480);   // Set the window's initial width & height
       glutCreateWindow(argv[0]);      // Create window with the name of the executable
       glutDisplayFunc(display);       // Register callback handler for window re-paint event
       glutReshapeFunc(reshape);       // Register callback handler for window re-size event

    
    /* OpenGL texture generation */
       glGenTextures(1, &texid); /* Texture name generation */
       glBindTexture(GL_TEXTURE_2D, texid); /* Binding of texture name */
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); /* We will use linear interpolation for magnification filter */
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); /* We will use linear interpolation for minifying filter */
       glTexImage2D(GL_TEXTURE_2D, 0, ilGetInteger(IL_IMAGE_BPP), ilGetInteger(IL_IMAGE_WIDTH), ilGetInteger(IL_IMAGE_HEIGHT), 
        0, ilGetInteger(IL_IMAGE_FORMAT), GL_UNSIGNED_BYTE, ilGetData()); /* Texture specification */
 
    /* Main loop */
    initGL();
    glutMainLoop();
    
    /* Delete used resources and quit */
     ilDeleteImages(1, &image); /* Because we have already copied image data into texture data we can release memory used by image. */
     glDeleteTextures(1, &texid);

     return 0;
} 

This compile like this on a linux box :


gcc devil_example.c -lGL -lglut -lIL -o devil_example

Note that with the line “success = ilConvertImage(IL_RGB, IL_UNSIGNED_BYTE);” from the original SDL code, the file image isn’t good loaded on my Linux box (the texture is gray + shifted)
=> I have to use “success = ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE);” instead
(I think this is because the default pixel color format is RGB24 on SDL when it’s RGBA on GLUT)

Thank you very much Little body, I have installed devil and tried your code. It works fine in loading a jpeg image. Now Could you help a bit more. How to manipulate the pixel values of my image and then write it back as a new jpg file. Thanks in advance.

For to manipulate the image, alls informations you need are already used at the line that load the texture from the RAM to OpenGL …



glTexImage2D(GL_TEXTURE_2D, 0, ilGetInteger(IL_IMAGE_BPP), ilGetInteger(IL_IMAGE_WIDTH), ilGetInteger(IL_IMAGE_HEIGHT),          0, ilGetInteger(IL_IMAGE_FORMAT), GL_UNSIGNED_BYTE, ilGetData()); /* Texture specification */

For to write it, use this DevIL functions :


ILboolean ilSaveImage(const char *FileName);

(you can found a .pdf file that explain how to use DevIL at http://openil.sourceforge.net/docs/DevIL%20Manual.pdf)

Thanks a lot.