Need some help with jpeglib

Discussion about everything. New games, 3d math, development tips...

Need some help with jpeglib

Postby Cristian » Wed May 09, 2012 12:41 pm

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:
cpp 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;
 
Cristian
 
Posts: 55
Joined: Fri Nov 25, 2005 12:02 pm

Re: Need some help with jpeglib

Postby REDDemon » Wed May 09, 2012 3:24 pm

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.
OpenGL is not hard. What you have to do is just explained in specifications. What is hard is dealing with poor OpenGL implementations.
User avatar
REDDemon
 
Posts: 831
Joined: Tue Aug 31, 2010 8:06 pm
Location: Genova (Italy)

Re: Need some help with jpeglib

Postby hendu » Wed May 09, 2012 3:28 pm

Why use a version that old? Current is 8, and the long-time stable one was 6b. I'd personally recommend jpeg-turbo.
hendu
 
Posts: 1556
Joined: Sat Dec 18, 2010 12:53 pm

Re: Need some help with jpeglib

Postby Cristian » Wed May 09, 2012 5:49 pm

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.
Cristian
 
Posts: 55
Joined: Fri Nov 25, 2005 12:02 pm

Re: Need some help with jpeglib

Postby REDDemon » Wed May 09, 2012 7:43 pm

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.
OpenGL is not hard. What you have to do is just explained in specifications. What is hard is dealing with poor OpenGL implementations.
User avatar
REDDemon
 
Posts: 831
Joined: Tue Aug 31, 2010 8:06 pm
Location: Genova (Italy)


Return to Off-topic

Who is online

Users browsing this forum: No registered users and 0 guests