高级应用加载TGA BMP PNG JEPG ——包含JPEG解码
2013-03-12 13:29
232 查看
texture.cpp
#include <StdAfx.h>
#include"texture.h"
///////////JPGE读写操作库头文件
#include "include/jpeglib.h"
////////////PNG读写操作库文件
#include "include/pnglib.h"
///JPGE读写操作库
#pragma comment(lib, "lib/jpeg.lib")
////PNG读写操作库
#pragma comment(lib, "lib/png.lib")
/////////////////////////////////////////////////////////////////////////////////////////////////
// JPEG TEXTURE LOADER
/////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////
bool CREATE_Texture(UINT &texture, LPSTR strFileName)
{
if(!strFileName) return false;
int components;
//////////////////////////////////////////////////////////Load TGA Image
if(strstr(strFileName, ".jpg"))
{
tImageJPG *pBitMap = NULL;
pBitMap = Load_JPEG(strFileName,&components);
if(pBitMap == NULL) return false;
GLenum format;
switch(components)///图象类型
{
case 1:
format = GL_LUMINANCE;
break;
case 2:
format = GL_LUMINANCE_ALPHA;
break;
case 3:
format = GL_RGB;
break;
case 4:
format = GL_RGBA;
break;
}
glGenTextures(1, &texture);
glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
glBindTexture(GL_TEXTURE_2D, texture);
gluBuild2DMipmaps(GL_TEXTURE_2D, components, pBitMap->sizeX, pBitMap->sizeY, format, GL_UNSIGNED_BYTE, pBitMap->data);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR_MIPMAP_LINEAR);
if (pBitMap!=NULL)
{
if (pBitMap->data!=NULL)
{
free(pBitMap->data);
}
free(pBitMap);
}
return true;
}
//////////////////////////////////////////////////////////////// Load PNG Image
else if(strstr(strFileName, ".png"))
{
tPNG * pBitMap = NULL;
pBitMap = LoadPNG(strFileName,&components);
if(pBitMap == NULL) return false;
GLenum format;
switch(components)///图象类型
{
case 1:
format = GL_LUMINANCE;
break;
case 2:
format = GL_LUMINANCE_ALPHA;
break;
case 3:
format = GL_RGB;
break;
case 4:
format = GL_RGBA;
break;
}
glGenTextures(1, &texture);
glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
glBindTexture(GL_TEXTURE_2D, texture);
gluBuild2DMipmaps(GL_TEXTURE_2D, components, pBitMap->sizeX, pBitMap->sizeY, format, GL_UNSIGNED_BYTE, pBitMap->data);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR_MIPMAP_LINEAR);
if (pBitMap!=NULL)
{
if (pBitMap->data!=NULL)
{
free(pBitMap->data);
}
free(pBitMap);
}
return true;
}
//////////////////////////////////////////////////////////////// Load BMP Image
else if(strstr(strFileName, ".bmp"))
{
AUX_RGBImageRec *pImage = NULL;
pImage = LoadBMP(strFileName,&components);
if(pImage == NULL) return false;
GLenum format;
switch(components)///图象类型
{
case 1:
format = GL_LUMINANCE;
break;
case 2:
format = GL_LUMINANCE_ALPHA;
break;
case 3:
format = GL_RGB;
break;
case 4:
format = GL_RGBA;
break;
}
/////
glGenTextures(1, &texture);
glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
glBindTexture(GL_TEXTURE_2D, texture);
gluBuild2DMipmaps(GL_TEXTURE_2D, components, pImage->sizeX, pImage->sizeY, format, GL_UNSIGNED_BYTE, pImage->data);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR_MIPMAP_LINEAR);
if (pImage!=NULL)
{
if (pImage->data!=NULL)
{
free(pImage->data);
}
free(pImage);
}
return true;
}
////////////////////////////////////////////////////////////////////////////// Load TGA Image
else if(strstr(strFileName, ".tga"))
{
tTGA *pImage =NULL;
pImage=LoadTGA(strFileName,&components);
if(pImage == NULL) return false;
GLenum format;
switch(components)///图象类型
{
case 1:
format = GL_LUMINANCE;
break;
case 2:
format = GL_LUMINANCE_ALPHA;
break;
case 3:
format = GL_RGB;
break;
case 4:
format = GL_RGBA;
break;
}
/////
glGenTextures(1, &texture);
glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
glBindTexture(GL_TEXTURE_2D, texture);
gluBuild2DMipmaps(GL_TEXTURE_2D, components, pImage->sizeX, pImage->sizeY, format, GL_UNSIGNED_BYTE, pImage->data);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR_MIPMAP_LINEAR);
if (pImage!=NULL)
{
if (pImage->data!=NULL)
{
free(pImage->data);
}
free(pImage);
}
return true;
}
////////////////////////////////////////////////////////////////类型不符合
else return false;
}
///////////////////////////////////////////////////////////////////////////////
tImageJPG *Load_JPEG(const char *strfilename,int *components)
{
FILE *pFile;
if((pFile = fopen(strfilename, "rb")) == NULL)
{
MessageBox(NULL, "Error loading jpg file.", "ERROR", MB_OK);
return NULL;
}
struct jpeg_decompress_struct cInfo;
my_error_mgr jerr;
// 错误处理
cInfo.err = jpeg_std_error(&jerr.pub);
jerr.pub.error_exit = my_error_exit;
if (setjmp(jerr.setjmp_buffer))
{
jpeg_destroy_decompress(&cInfo);
fclose(pFile);
cout<<"无法解压 "<<strfilename<<endl;
fclose(pFile);
return NULL;
}
//////////////////////////////////////////////////////
tImageJPG *pImgData = NULL;
////////////////////////////////////////////////
jpeg_create_decompress(&cInfo);
jpeg_stdio_src(&cInfo, pFile);
pImgData = (tImageJPG*)malloc(sizeof(tImageJPG));
(*components) =Decompress_JPEG(&cInfo, pImgData);
/////////////////////////////////////////////////
jpeg_destroy_decompress(&cInfo);
fclose(pFile);
return pImgData;
}
int Decompress_JPEG(jpeg_decompress_struct* cInfo, tImageJPG *pImgData)
{
jpeg_read_header(cInfo, TRUE);
jpeg_start_decompress(cInfo);
pImgData->rowSpan = cInfo->image_width * cInfo->num_components;
int components = cInfo->num_components;
pImgData->sizeX = cInfo->image_width;
pImgData->sizeY = cInfo->image_height;
pImgData->data = new unsigned char[pImgData->rowSpan * pImgData->sizeY];
unsigned char** rowPtr = new unsigned char*[pImgData->sizeY];
for (int i = 0; i < pImgData->sizeY; i++)
rowPtr[i] = &(pImgData->data[i*pImgData->rowSpan]);
int rowsRead = cInfo->output_height-1;
while (cInfo->output_scanline < cInfo->output_height)
{
rowsRead -= jpeg_read_scanlines(cInfo, &rowPtr[rowsRead], cInfo->output_height - rowsRead);
}
delete [] rowPtr;
jpeg_finish_decompress(cInfo);
return components;
}
void my_error_exit (j_common_ptr cinfo)
{
my_error_ptr myerr = (my_error_ptr) cinfo->err;
// 输出错误信息
char buffer[JMSG_LENGTH_MAX];
(*cinfo->err->format_message) (cinfo, buffer);
cout<<"libjpeg: "<<buffer<<endl;
longjmp(myerr->setjmp_buffer, 1);
}
//////////////////////////////////
AUX_RGBImageRec *LoadBMP(const char *strFileName,int *components) // 载入位图图象
{
AUX_RGBImageRec *pBitmap = NULL;
FILE *pFile = NULL;
if((pFile = fopen(strFileName, "rb")) == NULL)
{
MessageBox(NULL, "Can't load BMP image!", "ERROR", MB_OK | MB_ICONINFORMATION);
return NULL;
}
pBitmap = auxDIBImageLoad(strFileName);
(*components) = 3;
fclose(pFile);
return pBitmap;
}
/////////////////////////////////
tTGA *LoadTGA(const char *strFileName,int *components)
{
tTGA * pImageData = NULL;
FILE *pFile = NULL;
WORD width = 0, height = 0;
byte length = 0;
byte imageType = 0;
byte bits = 0;
(*components) = 0;
int stride = 0;
int i = 0;
if((pFile = fopen(strFileName, "rb")) == NULL)
{
MessageBox(NULL, "Can't load TGA image!", "ERROR", MB_OK | MB_ICONINFORMATION);
return NULL;
}
pImageData = (tTGA*)malloc(sizeof(tTGA));
fread(&length, sizeof(byte), 1, pFile);
fseek(pFile,1,SEEK_CUR);
fread(&imageType, sizeof(byte), 1, pFile);
fseek(pFile, 9, SEEK_CUR);
fread(&width, sizeof(WORD), 1, pFile);
fread(&height, sizeof(WORD), 1, pFile);
fread(&bits, sizeof(byte), 1, pFile);
fseek(pFile, length + 1, SEEK_CUR);
if(imageType != TGA_RLE)
{
if(bits == 24 || bits == 32)
{
(*components) = bits / 8;
stride = (*components) * width;
pImageData->data = ((unsigned char*)malloc(sizeof(unsigned char)*stride*height));
for(int y = 0; y < height; y++)
{
unsigned char *pLine = &(pImageData->data[stride * y]);
fread(pLine, stride, 1, pFile);
for(i = 0; i < stride; i += (*components))
{
int temp = pLine[i];
pLine[i] = pLine[i + 2];
pLine[i + 2] = temp;
}
}
}
else if(bits == 16)
{
unsigned short pixels = 0;
int r=0, g=0, b=0;
(*components) = 3;
stride = (*components) * width;
pImageData->data = ((unsigned char*)malloc(sizeof(unsigned char)*stride*height));
for(int i = 0; i < width*height; i++)
{
fread(&pixels, sizeof(unsigned short), 1, pFile);
b = (pixels & 0x1f) << 3;
g = ((pixels >> 5) & 0x1f) << 3;
r = ((pixels >> 10) & 0x1f) << 3;
pImageData->data[i * 3 + 0] = r;
pImageData->data[i * 3 + 1] = g;
pImageData->data[i * 3 + 2] = b;
}
}
else
{
fclose(pFile);
if(pImageData!=NULL)
{
free(pImageData);
}
return NULL;
}
}
else
{
byte rleID = 0;
int colorsRead = 0;
(*components) = bits / 8;
stride = (*components) * width;
pImageData->data = ((unsigned char*)malloc(sizeof(unsigned char)*stride*height));
byte *pColors = ((byte*)malloc(sizeof(byte)*(*components)));
while(i < width*height)
{
fread(&rleID, sizeof(byte), 1, pFile);
if(rleID < 128)
{
rleID++;
while(rleID)
{
fread(pColors, sizeof(byte) * (*components), 1, pFile);
pImageData->data[colorsRead + 0] = pColors[2];
pImageData->data[colorsRead + 1] = pColors[1];
pImageData->data[colorsRead + 2] = pColors[0];
if(bits == 32)
pImageData->data[colorsRead + 3] = pColors[3];
i++;
rleID--;
colorsRead += (*components);
}
}
else
{
rleID -= 127;
fread(pColors, sizeof(byte) * (*components), 1, pFile);
while(rleID)
{
pImageData->data[colorsRead + 0] = pColors[2];
pImageData->data[colorsRead + 1] = pColors[1];
pImageData->data[colorsRead + 2] = pColors[0];
if(bits == 32)
pImageData->data[colorsRead + 3] = pColors[3];
i++;
rleID--;
colorsRead += (*components);
}
}
}
}
fclose(pFile);
pImageData->sizeX = width;
pImageData->sizeY = height;
return pImageData;
}
/////////////////////////////////
tPNG *LoadPNG(const char *strFileName,int *components)
{
FILE *fp;
png_structp png_ptr;
png_infop info_ptr;
unsigned int sig_read = 0;
png_uint_32 width, height;
int bit_depth, color_type;
// 打开文件
if((fp = fopen(strFileName, "rb")) == NULL)
{
cout<<"无法打开 "<<strFileName<<endl;
return NULL;
}
///////////////////////////////////////////////////////////////////////
tPNG *pImgData ;
/////////////////////////////////////////////////////////////////////
// 创建并初始化read_struct
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
NULL, user_error_fn, user_warning_fn);
if (png_ptr == NULL)
{
fclose(fp);
return NULL;
}
info_ptr = png_create_info_struct(png_ptr);
if (info_ptr == NULL)
{
fclose(fp);
png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
return NULL;
}
// 错误处理
if (setjmp(png_jmpbuf(png_ptr)))
{
png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
fclose(fp);
cout<<"无法读取 "<<strFileName<<endl;
fclose(fp);
return NULL;
}
// 开始读
png_init_io(png_ptr, fp);
png_set_sig_bytes(png_ptr, sig_read);
png_read_info(png_ptr, info_ptr);
pImgData = (tPNG*)malloc(sizeof(tPNG));
// 文件信息
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,int_p_NULL, int_p_NULL, int_p_NULL);
pImgData->sizeX = width;
pImgData->sizeY = height;
if(color_type == PNG_COLOR_TYPE_GRAY)
{
(*components) = 1;
}
else if(color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
{
(*components) = 2;
}
else if(color_type == PNG_COLOR_TYPE_RGB)
{
(*components) = 3;
}
else if(color_type == PNG_COLOR_TYPE_RGB_ALPHA)
{
(*components) = 4;
}
// 转换格式
if (color_type == PNG_COLOR_TYPE_PALETTE)
{
png_set_palette_to_rgb(png_ptr);
(*components) = 3;
}
else if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
{
png_set_expand_gray_1_2_4_to_8(png_ptr);
}
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
{
png_set_tRNS_to_alpha(png_ptr);
(*components) = 4;
}
if (bit_depth == 16)
{
png_set_strip_16(png_ptr);
}
else if (bit_depth < 8)
{
png_set_packing(png_ptr);
}
// 分配内存,需在使用后自行删除
png_uint_32 rowbytes = width * (*components);
pImgData->data = new png_byte[rowbytes * height];
// 读取数据
for(png_uint_32 y=0; y < height; y++)
{
png_bytep row = pImgData->data + rowbytes * (height - y - 1);
png_read_rows(png_ptr, &row, png_bytepp_NULL, 1);
}
png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
fclose(fp);
return pImgData;
}
void user_error_fn(png_structp png_ptr, png_const_charp error_message)
{
cout<<"libpng error: "<<error_message<<endl;
if (png_ptr)
{
longjmp(png_ptr->jmpbuf, 1);
}
}
void user_warning_fn(png_structp png_ptr, png_const_charp warning_message)
{
cout<<"libpng warning: "<<warning_message<<endl;
}
texture.h
#ifndef TEXTURE_H
#define TEXTURE_H
#include "include/jpeglib.h"
#include <setjmp.h>//////////////////循环错误结构
#include "include/pnglib.h"
#define TGA_RGB 2
#define TGA_A 3
#define TGA_RLE 10
/////////////////////TGA结构///////////////////////////////
struct tTGA
{
GLuint sizeX;
GLuint sizeY;
unsigned char *data;
};
/////////////////////////PNG结构/////////////////////////
struct tPNG
{
png_uint_32 sizeX;
png_uint_32 sizeY;
png_byte *data;
};
/////////////////////////////////////////////////////
typedef struct my_error_mgr
{
jpeg_error_mgr pub;
jmp_buf setjmp_buffer;
} * my_error_ptr;
///////////////////////////////////////////////////
tImageJPG * Load_JPEG(const char * strfilename,int * components);
int Decompress_JPEG(jpeg_decompress_struct* cInfo, tImageJPG * pImgData);
bool CREATE_Texture(UINT &texture, LPSTR strFileName);
AUX_RGBImageRec *LoadBMP(const char *strFileName,int *components);
tTGA *LoadTGA(const char *strFileName,int *components);
tPNG *LoadPNG(const char *strFileName,int *components);
static void my_error_exit (j_common_ptr cinfo);
static void user_error_fn(png_structp png_ptr, png_const_charp error_message);
static void user_warning_fn(png_structp png_ptr, png_const_charp warning_message);
#endif
去找 PNG。LIB PNG。H JPEG。LIB JPEG。H ZLIB。LIB ZLIB。H (ZLIB 就是 zip)
#include <StdAfx.h>
#include"texture.h"
///////////JPGE读写操作库头文件
#include "include/jpeglib.h"
////////////PNG读写操作库文件
#include "include/pnglib.h"
///JPGE读写操作库
#pragma comment(lib, "lib/jpeg.lib")
////PNG读写操作库
#pragma comment(lib, "lib/png.lib")
/////////////////////////////////////////////////////////////////////////////////////////////////
// JPEG TEXTURE LOADER
/////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////
bool CREATE_Texture(UINT &texture, LPSTR strFileName)
{
if(!strFileName) return false;
int components;
//////////////////////////////////////////////////////////Load TGA Image
if(strstr(strFileName, ".jpg"))
{
tImageJPG *pBitMap = NULL;
pBitMap = Load_JPEG(strFileName,&components);
if(pBitMap == NULL) return false;
GLenum format;
switch(components)///图象类型
{
case 1:
format = GL_LUMINANCE;
break;
case 2:
format = GL_LUMINANCE_ALPHA;
break;
case 3:
format = GL_RGB;
break;
case 4:
format = GL_RGBA;
break;
}
glGenTextures(1, &texture);
glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
glBindTexture(GL_TEXTURE_2D, texture);
gluBuild2DMipmaps(GL_TEXTURE_2D, components, pBitMap->sizeX, pBitMap->sizeY, format, GL_UNSIGNED_BYTE, pBitMap->data);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR_MIPMAP_LINEAR);
if (pBitMap!=NULL)
{
if (pBitMap->data!=NULL)
{
free(pBitMap->data);
}
free(pBitMap);
}
return true;
}
//////////////////////////////////////////////////////////////// Load PNG Image
else if(strstr(strFileName, ".png"))
{
tPNG * pBitMap = NULL;
pBitMap = LoadPNG(strFileName,&components);
if(pBitMap == NULL) return false;
GLenum format;
switch(components)///图象类型
{
case 1:
format = GL_LUMINANCE;
break;
case 2:
format = GL_LUMINANCE_ALPHA;
break;
case 3:
format = GL_RGB;
break;
case 4:
format = GL_RGBA;
break;
}
glGenTextures(1, &texture);
glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
glBindTexture(GL_TEXTURE_2D, texture);
gluBuild2DMipmaps(GL_TEXTURE_2D, components, pBitMap->sizeX, pBitMap->sizeY, format, GL_UNSIGNED_BYTE, pBitMap->data);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR_MIPMAP_LINEAR);
if (pBitMap!=NULL)
{
if (pBitMap->data!=NULL)
{
free(pBitMap->data);
}
free(pBitMap);
}
return true;
}
//////////////////////////////////////////////////////////////// Load BMP Image
else if(strstr(strFileName, ".bmp"))
{
AUX_RGBImageRec *pImage = NULL;
pImage = LoadBMP(strFileName,&components);
if(pImage == NULL) return false;
GLenum format;
switch(components)///图象类型
{
case 1:
format = GL_LUMINANCE;
break;
case 2:
format = GL_LUMINANCE_ALPHA;
break;
case 3:
format = GL_RGB;
break;
case 4:
format = GL_RGBA;
break;
}
/////
glGenTextures(1, &texture);
glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
glBindTexture(GL_TEXTURE_2D, texture);
gluBuild2DMipmaps(GL_TEXTURE_2D, components, pImage->sizeX, pImage->sizeY, format, GL_UNSIGNED_BYTE, pImage->data);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR_MIPMAP_LINEAR);
if (pImage!=NULL)
{
if (pImage->data!=NULL)
{
free(pImage->data);
}
free(pImage);
}
return true;
}
////////////////////////////////////////////////////////////////////////////// Load TGA Image
else if(strstr(strFileName, ".tga"))
{
tTGA *pImage =NULL;
pImage=LoadTGA(strFileName,&components);
if(pImage == NULL) return false;
GLenum format;
switch(components)///图象类型
{
case 1:
format = GL_LUMINANCE;
break;
case 2:
format = GL_LUMINANCE_ALPHA;
break;
case 3:
format = GL_RGB;
break;
case 4:
format = GL_RGBA;
break;
}
/////
glGenTextures(1, &texture);
glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
glBindTexture(GL_TEXTURE_2D, texture);
gluBuild2DMipmaps(GL_TEXTURE_2D, components, pImage->sizeX, pImage->sizeY, format, GL_UNSIGNED_BYTE, pImage->data);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR_MIPMAP_LINEAR);
if (pImage!=NULL)
{
if (pImage->data!=NULL)
{
free(pImage->data);
}
free(pImage);
}
return true;
}
////////////////////////////////////////////////////////////////类型不符合
else return false;
}
///////////////////////////////////////////////////////////////////////////////
tImageJPG *Load_JPEG(const char *strfilename,int *components)
{
FILE *pFile;
if((pFile = fopen(strfilename, "rb")) == NULL)
{
MessageBox(NULL, "Error loading jpg file.", "ERROR", MB_OK);
return NULL;
}
struct jpeg_decompress_struct cInfo;
my_error_mgr jerr;
// 错误处理
cInfo.err = jpeg_std_error(&jerr.pub);
jerr.pub.error_exit = my_error_exit;
if (setjmp(jerr.setjmp_buffer))
{
jpeg_destroy_decompress(&cInfo);
fclose(pFile);
cout<<"无法解压 "<<strfilename<<endl;
fclose(pFile);
return NULL;
}
//////////////////////////////////////////////////////
tImageJPG *pImgData = NULL;
////////////////////////////////////////////////
jpeg_create_decompress(&cInfo);
jpeg_stdio_src(&cInfo, pFile);
pImgData = (tImageJPG*)malloc(sizeof(tImageJPG));
(*components) =Decompress_JPEG(&cInfo, pImgData);
/////////////////////////////////////////////////
jpeg_destroy_decompress(&cInfo);
fclose(pFile);
return pImgData;
}
int Decompress_JPEG(jpeg_decompress_struct* cInfo, tImageJPG *pImgData)
{
jpeg_read_header(cInfo, TRUE);
jpeg_start_decompress(cInfo);
pImgData->rowSpan = cInfo->image_width * cInfo->num_components;
int components = cInfo->num_components;
pImgData->sizeX = cInfo->image_width;
pImgData->sizeY = cInfo->image_height;
pImgData->data = new unsigned char[pImgData->rowSpan * pImgData->sizeY];
unsigned char** rowPtr = new unsigned char*[pImgData->sizeY];
for (int i = 0; i < pImgData->sizeY; i++)
rowPtr[i] = &(pImgData->data[i*pImgData->rowSpan]);
int rowsRead = cInfo->output_height-1;
while (cInfo->output_scanline < cInfo->output_height)
{
rowsRead -= jpeg_read_scanlines(cInfo, &rowPtr[rowsRead], cInfo->output_height - rowsRead);
}
delete [] rowPtr;
jpeg_finish_decompress(cInfo);
return components;
}
void my_error_exit (j_common_ptr cinfo)
{
my_error_ptr myerr = (my_error_ptr) cinfo->err;
// 输出错误信息
char buffer[JMSG_LENGTH_MAX];
(*cinfo->err->format_message) (cinfo, buffer);
cout<<"libjpeg: "<<buffer<<endl;
longjmp(myerr->setjmp_buffer, 1);
}
//////////////////////////////////
AUX_RGBImageRec *LoadBMP(const char *strFileName,int *components) // 载入位图图象
{
AUX_RGBImageRec *pBitmap = NULL;
FILE *pFile = NULL;
if((pFile = fopen(strFileName, "rb")) == NULL)
{
MessageBox(NULL, "Can't load BMP image!", "ERROR", MB_OK | MB_ICONINFORMATION);
return NULL;
}
pBitmap = auxDIBImageLoad(strFileName);
(*components) = 3;
fclose(pFile);
return pBitmap;
}
/////////////////////////////////
tTGA *LoadTGA(const char *strFileName,int *components)
{
tTGA * pImageData = NULL;
FILE *pFile = NULL;
WORD width = 0, height = 0;
byte length = 0;
byte imageType = 0;
byte bits = 0;
(*components) = 0;
int stride = 0;
int i = 0;
if((pFile = fopen(strFileName, "rb")) == NULL)
{
MessageBox(NULL, "Can't load TGA image!", "ERROR", MB_OK | MB_ICONINFORMATION);
return NULL;
}
pImageData = (tTGA*)malloc(sizeof(tTGA));
fread(&length, sizeof(byte), 1, pFile);
fseek(pFile,1,SEEK_CUR);
fread(&imageType, sizeof(byte), 1, pFile);
fseek(pFile, 9, SEEK_CUR);
fread(&width, sizeof(WORD), 1, pFile);
fread(&height, sizeof(WORD), 1, pFile);
fread(&bits, sizeof(byte), 1, pFile);
fseek(pFile, length + 1, SEEK_CUR);
if(imageType != TGA_RLE)
{
if(bits == 24 || bits == 32)
{
(*components) = bits / 8;
stride = (*components) * width;
pImageData->data = ((unsigned char*)malloc(sizeof(unsigned char)*stride*height));
for(int y = 0; y < height; y++)
{
unsigned char *pLine = &(pImageData->data[stride * y]);
fread(pLine, stride, 1, pFile);
for(i = 0; i < stride; i += (*components))
{
int temp = pLine[i];
pLine[i] = pLine[i + 2];
pLine[i + 2] = temp;
}
}
}
else if(bits == 16)
{
unsigned short pixels = 0;
int r=0, g=0, b=0;
(*components) = 3;
stride = (*components) * width;
pImageData->data = ((unsigned char*)malloc(sizeof(unsigned char)*stride*height));
for(int i = 0; i < width*height; i++)
{
fread(&pixels, sizeof(unsigned short), 1, pFile);
b = (pixels & 0x1f) << 3;
g = ((pixels >> 5) & 0x1f) << 3;
r = ((pixels >> 10) & 0x1f) << 3;
pImageData->data[i * 3 + 0] = r;
pImageData->data[i * 3 + 1] = g;
pImageData->data[i * 3 + 2] = b;
}
}
else
{
fclose(pFile);
if(pImageData!=NULL)
{
free(pImageData);
}
return NULL;
}
}
else
{
byte rleID = 0;
int colorsRead = 0;
(*components) = bits / 8;
stride = (*components) * width;
pImageData->data = ((unsigned char*)malloc(sizeof(unsigned char)*stride*height));
byte *pColors = ((byte*)malloc(sizeof(byte)*(*components)));
while(i < width*height)
{
fread(&rleID, sizeof(byte), 1, pFile);
if(rleID < 128)
{
rleID++;
while(rleID)
{
fread(pColors, sizeof(byte) * (*components), 1, pFile);
pImageData->data[colorsRead + 0] = pColors[2];
pImageData->data[colorsRead + 1] = pColors[1];
pImageData->data[colorsRead + 2] = pColors[0];
if(bits == 32)
pImageData->data[colorsRead + 3] = pColors[3];
i++;
rleID--;
colorsRead += (*components);
}
}
else
{
rleID -= 127;
fread(pColors, sizeof(byte) * (*components), 1, pFile);
while(rleID)
{
pImageData->data[colorsRead + 0] = pColors[2];
pImageData->data[colorsRead + 1] = pColors[1];
pImageData->data[colorsRead + 2] = pColors[0];
if(bits == 32)
pImageData->data[colorsRead + 3] = pColors[3];
i++;
rleID--;
colorsRead += (*components);
}
}
}
}
fclose(pFile);
pImageData->sizeX = width;
pImageData->sizeY = height;
return pImageData;
}
/////////////////////////////////
tPNG *LoadPNG(const char *strFileName,int *components)
{
FILE *fp;
png_structp png_ptr;
png_infop info_ptr;
unsigned int sig_read = 0;
png_uint_32 width, height;
int bit_depth, color_type;
// 打开文件
if((fp = fopen(strFileName, "rb")) == NULL)
{
cout<<"无法打开 "<<strFileName<<endl;
return NULL;
}
///////////////////////////////////////////////////////////////////////
tPNG *pImgData ;
/////////////////////////////////////////////////////////////////////
// 创建并初始化read_struct
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
NULL, user_error_fn, user_warning_fn);
if (png_ptr == NULL)
{
fclose(fp);
return NULL;
}
info_ptr = png_create_info_struct(png_ptr);
if (info_ptr == NULL)
{
fclose(fp);
png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
return NULL;
}
// 错误处理
if (setjmp(png_jmpbuf(png_ptr)))
{
png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
fclose(fp);
cout<<"无法读取 "<<strFileName<<endl;
fclose(fp);
return NULL;
}
// 开始读
png_init_io(png_ptr, fp);
png_set_sig_bytes(png_ptr, sig_read);
png_read_info(png_ptr, info_ptr);
pImgData = (tPNG*)malloc(sizeof(tPNG));
// 文件信息
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,int_p_NULL, int_p_NULL, int_p_NULL);
pImgData->sizeX = width;
pImgData->sizeY = height;
if(color_type == PNG_COLOR_TYPE_GRAY)
{
(*components) = 1;
}
else if(color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
{
(*components) = 2;
}
else if(color_type == PNG_COLOR_TYPE_RGB)
{
(*components) = 3;
}
else if(color_type == PNG_COLOR_TYPE_RGB_ALPHA)
{
(*components) = 4;
}
// 转换格式
if (color_type == PNG_COLOR_TYPE_PALETTE)
{
png_set_palette_to_rgb(png_ptr);
(*components) = 3;
}
else if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
{
png_set_expand_gray_1_2_4_to_8(png_ptr);
}
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
{
png_set_tRNS_to_alpha(png_ptr);
(*components) = 4;
}
if (bit_depth == 16)
{
png_set_strip_16(png_ptr);
}
else if (bit_depth < 8)
{
png_set_packing(png_ptr);
}
// 分配内存,需在使用后自行删除
png_uint_32 rowbytes = width * (*components);
pImgData->data = new png_byte[rowbytes * height];
// 读取数据
for(png_uint_32 y=0; y < height; y++)
{
png_bytep row = pImgData->data + rowbytes * (height - y - 1);
png_read_rows(png_ptr, &row, png_bytepp_NULL, 1);
}
png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
fclose(fp);
return pImgData;
}
void user_error_fn(png_structp png_ptr, png_const_charp error_message)
{
cout<<"libpng error: "<<error_message<<endl;
if (png_ptr)
{
longjmp(png_ptr->jmpbuf, 1);
}
}
void user_warning_fn(png_structp png_ptr, png_const_charp warning_message)
{
cout<<"libpng warning: "<<warning_message<<endl;
}
texture.h
#ifndef TEXTURE_H
#define TEXTURE_H
#include "include/jpeglib.h"
#include <setjmp.h>//////////////////循环错误结构
#include "include/pnglib.h"
#define TGA_RGB 2
#define TGA_A 3
#define TGA_RLE 10
/////////////////////TGA结构///////////////////////////////
struct tTGA
{
GLuint sizeX;
GLuint sizeY;
unsigned char *data;
};
/////////////////////////PNG结构/////////////////////////
struct tPNG
{
png_uint_32 sizeX;
png_uint_32 sizeY;
png_byte *data;
};
/////////////////////////////////////////////////////
typedef struct my_error_mgr
{
jpeg_error_mgr pub;
jmp_buf setjmp_buffer;
} * my_error_ptr;
///////////////////////////////////////////////////
tImageJPG * Load_JPEG(const char * strfilename,int * components);
int Decompress_JPEG(jpeg_decompress_struct* cInfo, tImageJPG * pImgData);
bool CREATE_Texture(UINT &texture, LPSTR strFileName);
AUX_RGBImageRec *LoadBMP(const char *strFileName,int *components);
tTGA *LoadTGA(const char *strFileName,int *components);
tPNG *LoadPNG(const char *strFileName,int *components);
static void my_error_exit (j_common_ptr cinfo);
static void user_error_fn(png_structp png_ptr, png_const_charp error_message);
static void user_warning_fn(png_structp png_ptr, png_const_charp warning_message);
#endif
去找 PNG。LIB PNG。H JPEG。LIB JPEG。H ZLIB。LIB ZLIB。H (ZLIB 就是 zip)
相关文章推荐
- Windows下轻松加载BMP, GIF, JPEG, PNG, and TIFF图片
- C#中使用FreeImage库加载Bmp、JPG、PNG、PCX、TGA、PSD等25种格式的图像(源码)。
- Windows下OpenGL轻松加载BMP, GIF, JPEG, PNG, and TIFF图片
- Windows下OpenGL轻松加载BMP, GIF, JPEG, PNG, and TIFF图片
- 解析BMP GIF JPEG TGA PNG图像格式
- C#中使用FreeImage库加载Bmp、JPG、PNG、PCX、TGA、PSD等25种格式的图像(源码)。
- 一次上传多张图片包含不同类型png, jpeg
- GDI+实现图片格式转换(bmp、jpeg、gif、tiff、png) .
- 图片原理解说(综合版:JPEG,PNG,BMP,GIF)
- delphi 中 image 控件加载bmp、JPG、GIF、PNG等图片的办法
- VC6 CImage 加载jpg png bmp
- Check图片类型[JPEG(.jpg 、.jpeg),TIF,GIF,BMP,PNG,PDF]
- easyWeb2Pic -- 在IE浏览器中,将整个网页保存为BMP, JPEG/JPG, GIF, PNG或者TIFF图片
- C语言实现的BMP和JPEG图片的解码
- BREW中将PNG转换成BMP的方法(解码转换)
- MFC 下给控件加载jpeg等非bmp图片的一种简单方法
- 文章标题 Java中io流的一些简单操作(包含文件复制,向硬盘中写入文本文件,以及io流高级应用序列化和反序列化)
- png/gif/jpeg/bmp图片格式的简易文档
- eVC中怎样显示JPEG,BMP,PNG等格式的图片
- wince下IImage接口的使用,处理jpeg、bmp、png等格式图片