/***********************************************************************************	@file			Image.cxx**	@brief		Class to load JPEG or PNG files into RAM.**	@version		1.0**	@date			28/12/2009**	@author		Franck P. Vidal**	@section		Copyright*					(c) by Franck P. Vidal franck.p.vidal@gmail.com, December 2009, 2009, version 1.0**********************************************************************************///******************************************************************************//	Include//******************************************************************************#include <iostream>#include <jpeglib.h>#include <png.h>#include "Image.h"//-----------------------------------------bool Image::LoadJPEG(const char* aFileName)//-----------------------------------------{	// Delete any previous data	Delete();		// We need a JPEG decompression structure	struct jpeg_decompress_struct jpeg_info;		// We must manage errors, that's why we need this structure	struct jpeg_error_mgr jpeg_err;		// The source file	FILE* jpeg_file(0);		// Open the source file	if ((jpeg_file = fopen(aFileName, "rb")) == 0)	{		std::cerr << "ERROR: cannot open the file \"" << aFileName << "\"." << std::endl;		return false;	}		// We set up the normal JPEG error routines	jpeg_info.err = jpeg_std_error(&jpeg_err);		// We intialise the JPEG decompression object	jpeg_create_decompress(&jpeg_info);		// We specify the source file	jpeg_stdio_src(&jpeg_info, jpeg_file);		// We read file parameters	jpeg_read_header(&jpeg_info, TRUE);		// We can update the image structure	m_width            = jpeg_info.image_width;	m_height           = jpeg_info.image_height;	if (jpeg_info.num_components == 1)	{		m_format = GL_LUMINANCE;	}	else if (jpeg_info.num_components == 2)	{		m_format = GL_LUMINANCE_ALPHA;	}	else if (jpeg_info.num_components == 3)	{		m_format = GL_RGB;	}	else if (jpeg_info.num_components == 4)	{		m_format = GL_RGBA;	}	else	{		std::cerr << "ERROR: invalid number of components in \"" << aFileName << ".\"" << std::endl;	}	m_bit_depth        = 8;		// Create new data and test if the buffer has been created	m_p_data = new unsigned char [m_width * m_height * jpeg_info.num_components];	if (!m_p_data)	{		std::cerr << "ERROR: allocation fault. Cannot create a " << m_width << "x" << m_height << "x" << jpeg_info.num_components << " image." << std::endl;		Delete();		// Destroy the JPEG decompression object		jpeg_destroy_decompress(&jpeg_info);		// Close the file		fclose(jpeg_file);		return false;	}	// Start decompression	jpeg_start_decompress(&jpeg_info);		// Read the data and flip the image	unsigned char* tmp(m_p_data);	while (jpeg_info.output_scanline < jpeg_info.output_height)	{		jpeg_read_scanlines(&jpeg_info, &tmp, 1);		tmp += m_width * jpeg_info.num_components;	}		// Finish the decompression	jpeg_finish_decompress(&jpeg_info);		// Destroy the JPEG decompression object	jpeg_destroy_decompress(&jpeg_info);		// Close the file	fclose(jpeg_file);		return true;}//----------------------------------------bool Image::LoadPNG(const char* aFileName)//----------------------------------------{	// Delete any previous data	Delete();	// The source file	FILE* png_file(0);		// Open the source file	if ((png_file = fopen(aFileName, "rb")) == 0)	{		std::cerr << "ERROR: cannot open the file \"" << aFileName << "\"." << std::endl;		Delete();		return false;	}		// Read the first 8 bytes of the file and make sure they match the PNG signature bytes	unsigned char signature[8];	fread(signature, 1, 8, png_file);	// Bad signature	if (!png_check_sig(signature, 8))	{		std::cerr << "ERROR: bad signature in the file \"" << aFileName << "\"." << std::endl;		Delete();		fclose(png_file);		return false;	}		// Intialise the PNG decompression object	png_structp png_ptr(png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL));	if (!png_ptr)	{		std::cerr << "ERROR: out of memory." << std::endl;		Delete();		fclose(png_file);		return false;	}	png_infop info_ptr(png_create_info_struct(png_ptr));	if (!info_ptr)	{		png_destroy_read_struct(&png_ptr, NULL, NULL);		std::cerr << "ERROR: out of memory." << std::endl;		Delete();		fclose(png_file);		return false;	}		// We read file parameters	png_init_io(png_ptr, png_file);	png_set_sig_bytes(png_ptr, 8);	png_read_info(png_ptr, info_ptr);	png_uint_32 width, height;	int color_type;	png_get_IHDR(png_ptr, info_ptr, &width, &height, &m_bit_depth, &color_type, NULL, NULL, NULL);	m_width = width;	m_height = height;	if (color_type == PNG_COLOR_TYPE_GRAY)	{		m_format = GL_LUMINANCE;	}	else if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA)	{		m_format = GL_LUMINANCE_ALPHA;	}	else if (color_type == PNG_COLOR_TYPE_RGB)	{		m_format = GL_RGB;	}	else if (color_type == PNG_COLOR_TYPE_RGB_ALPHA)	{		m_format = GL_RGBA;	}	else	{		std::cerr << "ERROR: invalid number of components in \"" << aFileName << ".\"" << std::endl;		Delete();		// Destroy the PNG decompression object		png_destroy_read_struct(&png_ptr, &info_ptr, NULL);				// Close the file		fclose(png_file);		return false;	}	// Create new data and test if the buffer has been created	int rowbytes(png_get_rowbytes(png_ptr, info_ptr));	int component_number(rowbytes / m_width);	m_p_data = new unsigned char [m_width * m_height * component_number];	if (!m_p_data)	{		std::cerr << "ERROR: allocation fault. Cannot create a " << m_width << "x" << m_height << "x" << component_number << " image." << std::endl;		Delete();		// Destroy the PNG decompression object		png_destroy_read_struct(&png_ptr, &info_ptr, NULL);		// Close the file		fclose(png_file);		return false;	}	// Start decompression	png_start_read_image(png_ptr);	// Set the individual row_pointers to point at the correct offsets	png_bytepp row_pointers(new png_bytep[m_height]);	for (unsigned int i(0);  i < m_height;  ++i)		row_pointers[i] = m_p_data + i * rowbytes;	// Read the whole image	png_read_image(png_ptr, row_pointers);		delete [] row_pointers;	row_pointers = 0;		// Finish the decompression	png_read_end(png_ptr, info_ptr);	// Destroy the PNG decompression object	png_destroy_read_struct(&png_ptr, &info_ptr, NULL);		// Close the file	fclose(png_file);	return true;}