I'm currently working on a project and have pretty much hit a wall trying to load this jpg file using jpeglib (version 6a).
But it ends up looking like this on-screen:
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;