Need some help with jpeglib

Discussion about everything. New games, 3d math, development tips...
Post Reply
Cristian
Posts: 55
Joined: Fri Nov 25, 2005 12:02 pm

Need some help with jpeglib

Post by Cristian »

Hi, I know it's not related to irrlicht and probably not that ok to ask but from past experience I know the poeple here are pretty knowledgeable, so I'm asking for a little help.

I'm currently working on a project and have pretty much hit a wall trying to load this jpg file using jpeglib (version 6a).
Image

But it ends up looking like this on-screen:
Image

Some jpeg files load properly but quite a few don't (they end up looking like the example above).
Can anyone tell me if this is solvable by upgrading the library or I'm doing something wrong ?

This is the code I'm using to load the image:

Code: Select all

 
        struct jpeg_decompress_struct cinfo;
        struct my_error_mgr jerr;
        JSAMPARRAY scanline;    /* Output row buffer */
        int row_stride;         /* Physical row width in output buffer */
        unsigned char* data = NULL;
        unsigned int   w = 0, h = 0, size = 0;
 
        /* Step 1: allocate and initialize JPEG decompression object */
        /* We set up the normal JPEG error routines, then override error_exit. */
        cinfo.err = jpeg_std_error(&jerr.pub);
        jerr.pub.error_exit = my_error_exit;
 
        /* Establish the setjmp return context for my_error_exit to use. */
        if (setjmp(jerr.setjmp_buffer))
        {
                /* If we get here, the JPEG code has signaled an error.
                 * We need to clean up the JPEG object, close the input file, and return.*/
                jpeg_destroy_decompress(&cinfo);
                s->Close();
                return false;
        }
 
        /* Now we can initialize the JPEG decompression object. */
        jpeg_create_decompress(&cinfo);
 
        /* Read the file in memory */
        unsigned int    _DataSize = s->Size();
        unsigned char*  _pData = (unsigned char*)malloc(_DataSize);
        if (!s->ReadBuffer(_pData, _DataSize))
        {
                jpeg_destroy_decompress(&cinfo);
                s->Close();
                return false;
        }
 
        /* Step 2: specify data source (eg, a file) */
        jpeg_mem_src(&cinfo, _pData, _DataSize);
 
        /* Step 3: read file parameters with jpeg_read_header() */
        (void) jpeg_read_header(&cinfo, TRUE);
 
        /* Step 4: Start decompressor */
        (void) jpeg_start_decompress(&cinfo);
 
        /* Alloc and open our new buffer */
        data = new unsigned char[cinfo.output_width * 3 * cinfo.output_height];
        if (data == NULL)
        {
                jpeg_destroy_decompress(&cinfo);
                s->Close();
                return false;
        }
 
        // how big is this thing gonna be?
        w = cinfo.output_width;
        h = cinfo.output_height;
        size = w * 3 * h;
 
        /* JSAMPLEs per row in output buffer */
        row_stride = cinfo.output_width * cinfo.output_components;
 
        /* Make a one-row-high sample array that will go away when done with image */
        scanline = (*cinfo.mem->alloc_sarray)
                ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
 
        /* Step 6: while (scan lines remain to be read) */
        /* Here we use the library's state variable cinfo.output_scanline as the
        * loop counter, so that we don't have to keep track ourselves.*/
        int row = cinfo.output_height - 1;
        while (cinfo.output_scanline < cinfo.output_height)
        {
                /* Read it one scanline at a time */
                (void) jpeg_read_scanlines(&cinfo, scanline, 1);
 
                /* Assume put_scanline_someplace wants a pointer and sample count. */
                if (cinfo.out_color_components == 3)
                        j_putRGBScanline(scanline[0], w, data, row);
                else if (cinfo.out_color_components == 1)
                        j_putGrayScanlineToRGB(scanline[0], w, data, row);
                
                row--;
        }
 
        /* Step 7: Finish decompression */
        (void) jpeg_finish_decompress(&cinfo);
 
        /* Step 8: Release JPEG decompression object */
        jpeg_destroy_decompress(&cinfo);
 
        free(_pData);
 
        /* Set ImageData parameters */
        id->m_iDataSize = size;
        id->m_iWidth    = w;
        id->m_iHeight   = h;
        id->m_iTextureWidth  = ImageData::NormalizeImageDimension(id->m_iWidth);
        id->m_iTextureHeight = ImageData::NormalizeImageDimension(id->m_iHeight);
        id->m_iTextureFormat = GL_UNSIGNED_BYTE;
        id->m_iInternalFormat = GL_RGB;
 
        SAFE_DEL(id->m_pPixels);
        id->m_pPixels = data;
 
REDDemon
Developer
Posts: 1044
Joined: Tue Aug 31, 2010 8:06 pm
Location: Genova (Italy)

Re: Need some help with jpeglib

Post by REDDemon »

You are using library correctly. It looks like wrong usage of OpenGL.

try using GL_UNPACK_ALIGNEMENT of 1 that should fix your problem. You have to set that before sending raw image data with glTexImage. Or just set it once in your application. Just remember that to set unpack alignement you need an active opengl context. ;-) (other possible alignements are 2,3,4).
Last edited by REDDemon on Wed May 09, 2012 3:28 pm, edited 1 time in total.
Junior Irrlicht Developer.
Real value in social networks is not about "increasing" number of followers, but about getting in touch with Amazing people.
- by Me
hendu
Posts: 2600
Joined: Sat Dec 18, 2010 12:53 pm

Re: Need some help with jpeglib

Post by hendu »

Why use a version that old? Current is 8, and the long-time stable one was 6b. I'd personally recommend jpeg-turbo.
Cristian
Posts: 55
Joined: Fri Nov 25, 2005 12:02 pm

Re: Need some help with jpeglib

Post by Cristian »

Well, thanks a lot, it worked.
Setting GL_UNPACK_ALIGNEMENT to 1 did the job.
I'm pretty ashamed of myself as the skewed image should have been a telltale sign of bad alignment.
Still, I'll most likely have to pad the bytes at some points, as I've read that changing GL_UNPACK_ALIGNEMENT isn't really recommended.
REDDemon
Developer
Posts: 1044
Joined: Tue Aug 31, 2010 8:06 pm
Location: Genova (Italy)

Re: Need some help with jpeglib

Post by REDDemon »

yeah theorically with UNPACK_ALIGNEMENT = 4 uploading textures to videocard is faster, because video drivers will convert your image to UNPACK_ALIGNEMENT = 4 (internally). But since video drivers usually do that faster than any user's code is useless changing alignement yourself just before loading. (drivers will do that faster anyway). What is worth is storing data already with correct alignement so that you don't need additional manipulation on data.(and I doubt anyone will be able to do that with a jpeg image).

Another reason why it is not reccomended is because users usually forget to restore original alignement after changing it. so doing that will make others code potentially not working.
Junior Irrlicht Developer.
Real value in social networks is not about "increasing" number of followers, but about getting in touch with Amazing people.
- by Me
Post Reply