您的位置:首页 > 其它

高级应用加载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)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: