高级应用加载TGA BMP PNG JEPG ——包含JPEG解码

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)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值