Posteriormente a consultar expertos en el tema, programadores de deferentes ramas y profesores hemos dado con la solución al problema y la plasmamos en este post.
Solución:
Aquí hay una muestra para leer una imagen jpeg:
/***************************************************
To read a jpg image file and download
it as a texture map for openGL
Derived from Tom Lane's example.c
-- Obtain & install jpeg stuff from web
(jpeglib.h, jerror.h jmore.h, jconfig.h,jpeg.lib)
****************************************************/
#include
#include
//================================
GLuint LoadJPEG(char* FileName)
//================================
unsigned long x, y;
unsigned int texture_id;
unsigned long data_size; // length of the file
int channels; // 3 =>RGB 4 =>RGBA
unsigned int type;
unsigned char * rowptr[1]; // pointer to an array
unsigned char * jdata; // data for the image
struct jpeg_decompress_struct info; //for our jpeg info
struct jpeg_error_mgr err; //the error handler
FILE* file = fopen(FileName, "rb"); //open the file
info.err = jpeg_std_error(& err);
jpeg_create_decompress(& info); //fills info structure
//if the jpeg file doesn't load
if(!file)
fprintf(stderr, "Error reading JPEG file %s!", FileName);
return 0;
jpeg_stdio_src(&info, file);
jpeg_read_header(&info, TRUE); // read jpeg file header
jpeg_start_decompress(&info); // decompress the file
//set width and height
x = info.output_width;
y = info.output_height;
channels = info.num_components;
type = GL_RGB;
if(channels == 4) type = GL_RGBA;
data_size = x * y * 3;
//--------------------------------------------
// read scanlines one at a time & put bytes
// in jdata[] array. Assumes an RGB image
//--------------------------------------------
jdata = (unsigned char *)malloc(data_size);
while (info.output_scanline < info.output_height) // loop
// Enable jpeg_read_scanlines() to fill our jdata array
rowptr[0] = (unsigned char *)jdata + // secret to method
3* info.output_width * info.output_scanline;
jpeg_read_scanlines(&info, rowptr, 1);
//---------------------------------------------------
jpeg_finish_decompress(&info); //finish decompressing
//----- create OpenGL tex map (omit if not needed) --------
glGenTextures(1,&texture_id);
glBindTexture(GL_TEXTURE_2D, texture_id);
gluBuild2DMipmaps(GL_TEXTURE_2D,3,x,y,GL_RGB,GL_UNSIGNED_BYTE,jdata);
jpeg_destroy_decompress(&info);
fclose(file); //close the file
free(jdata);
return texture_id; // for OpenGL tex maps
La función jpeg_read_scanlines recibe un array de punteros (no el puntero directo de píxeles como imageData->pixels). Así que primero deberíamos crear un JSAMPARRAY:
int buffer_height = 1;
JSAMPARRAY buffer = (JSAMPARRAY)malloc(sizeof(JSAMPROW) * buffer_height);
buffer[0] = (JSAMPROW)malloc(sizeof(JSAMPLE) * row_stride);
En su código ha creado un "búfer" con "cinfo.mem->alloc_sarray" pero nunca lo usa. El paso final es pasar el "búfer" como argumento de jpeg_read_scanlines:
while (cinfo.output_scanline < cinfo.output_height)
jpeg_read_scanlines(&cinfo, buffer, 1);
memcpy(imageData->pixels+counter, buffer[0], row_stride);
counter += row_stride;
Vea que estamos usando "imageData->pixels+counter", no solo "imageData->pixels" como en su código. De esta manera, escribimos cada fila tras otra en el fragmento de memoria completo "imageData->pixels".
Como dijo dacap, está esperando un JSAMPARRAY. Dicho esto, puede escribir directamente en su imageData->pixels array si desea. Solo necesitas hacer algo como esto:
// Allocate imageData->pixels to be the correct size, start decompress and all
// that jazz, like you did in your code. Skip allocating buffer though.
// ...
JSAMPROW output_data;
unsigned int scanline_len = cinfo.output_width * cinfo.output_components;
unsigned int scanline_count = 0;
while (cinfo.output_scanline < cinfo.output_height)
output_data = (imageData->pixels + (scanline_count * scanline_len));
jpeg_read_scanlines(&cinfo, &output_data, 1);
scanline_count++;
A continuación, puede omitir la asignación de búfer por completo. Usar memcpy funciona bien, pero ¿por qué hacer la copia adicional si no es necesario?
Sección de Reseñas y Valoraciones
Nos encantaría que puedieras dar difusión a este enunciado si lograste el éxito.