OpenGL之讀取PCX圖檔

OpenGL之讀取PCX圖檔

PCX圖檔較常用於3D紋理,你的3D遊戲引擎無任何理由拒絕支持PCX格式的圖檔.幸好PCX格式非常簡單.渲染演示程式下載:

它主要由三部份組成:

  1. 文檔頭部
  2. 經RLE編碼的圖像數據
  3. 調色板,只用於256色
PCX文檔頭部結構 簡介
typedef struct PCX_HEADER_TAG{  
UCHAR  manufacturer; PCX標記:總是 0x0A
UCHAR  version; 版本號
UCHAR  encoding; 編碼:總為 1,使用RLE編碼
UCHAR  bits_per_pixel; 每像數所占的位數 1,2,4,8
USHORT xmin, ymin; 圖像的左下角邊界
USHORT xmax, ymax; 圖像的右上角邊界
USHORT hres; 水平分辨率
USHORT yres; 垂直分辨率
UCHAR  EGAcolors[48]; EGA(16色)調色板,這種圖檔以較小式用
UCHAR  reserved; 保留字節
UCHAR  color_planes; 色彩平面量 (24Bit圖檔為3)
USHORT bytes_per_line; 每行字節數(單個顏色分量)
USHORT palette_type; 1為灰度,2為彩色調色板
USHORT scrnw; 屏幕水平像素
USHORT scrnh; 屏幕垂直像素
UCHAR  filler[54]; 54BYTE全零
} PCX_HEADER, *PCX_HEADER_PTR;  

你需要定義新的PCX結構用於保存PCX信息.

PCX 結構
typedef struct PCX_TAG{  
int               width; 圖寬=xmax – xmin + 1
int               height; 圖高=ymax – ymin + 1
int               bitCount; 位圖像素的bits 8位,16位,24位,32位

bitCount=color_planes*bytes_per_line

PCX_PALETTEENTRY  palette[256]; 調色板,當圖檔為256色時出現
PBYTE             buffer; 圖像數據
} PCX, *PCX_PTR;  

我實現PCX解釋器支持『256色』『16BIT』兩種常見格式:

bool Load_PCX(PCX_PTR pcx,PBYTE data,int size)

{

int      index;              // 循环变量

PBYTE   image;// 图像数据

int     image_size;// 像数个数

PBYTE          RLE;//  RLE编码图像数据

PCX_HEADER_PTR  header;// 文档的头部

PCX_PALETTEENTRY_PTR  palette;// 读取PCX的调色版

header = (PCX_HEADER_PTR)data; // 文档的头部

pcx->width  = (header->xmax – header->xmin) + 1;// 图像宽度(像数)

pcx->height = (header->ymax – header->ymin) + 1;// 图像高度(像数)

pcx->bitCount = header->bits_per_pixel * header->color_planes;// 计算每像数所占的位数

RLE = data + sizeof(PCX_HEADER);

if (pcx->bitCount == 8)

{         // 分配图像记忆体

pcx->buffer = (PBYTE)malloc(pcx->width*pcx->height * 3);

image = (PBYTE)malloc(pcx->width*pcx->height);

image_size = pcx->width * pcx->height;// 图像的像素

Load_RLE_PCX(image, RLE, pcx->width, pcx->height);// RLE解码

// 读取PCX的调色版

palette = (PCX_PALETTEENTRY_PTR)(data + size – 768);// 在文件的结束的位置前移768字节即移动到调色板的开始位置

for (int i = 0; i < image_size; ++i)

{//掉转红色和绿色

index = image[i];

pcx->buffer[i*3 + 0] = palette[index].red;// 红色部分

pcx->buffer[i*3 + 1] = palette[index].green;// 取的绿色部分

pcx->buffer[i*3 + 2] = palette[index].blue;// 取的蓝色部分

}

pcx->bitCount = 24;

free(image);// 释放记忆体

}

else

if (pcx->bitCount == 24)

{// 分配图像记忆体

pcx->buffer = (PBYTE)malloc(pcx->widthpcx->height3);

Load_RLE24_PCX(pcx->buffer, RLE, pcx->width, pcx->height);// RLE解码

}

return true;

}

評論