OpenGL之讀取PCX文檔-RLE解碼

OpenGL之讀取PCX文檔-RLE解碼

『PCX』與『BMP』同樣支持『RLE編碼』,而且支持8Bit和24Bit的『RLE編碼』渲染演示程式下載:

先講解8Bit (256色)『RLE編碼』算法:

  1. 首字節把『重複』像素的個數的最高兩BIT設為1保存, 0xC0&length
  2. 解碼時只要把首字節減192即等於『重複』個數,或者data& 0x3F提取最低六位.
  3. 次字節寫入重複的像素值
  4. 並且『重複』像素的最大長度為63,因為255(0xff)-192(0xc0)=63
  5. 如果像素大於192,把像數當成『不重複』的像素直接保存
  6. 『不重複』的像素直接保存

PCX的24BIT圖檔同樣使用『RLE編碼』,但網絡上PCX的24Bit『RLE解碼』算法大多都是不正確,

24Bit『RLE編碼』算法:

  1. 24BIT算法8Bit基本一致.最大分別是它對每行像素的RGB值進行分解後再進行RLE編碼
  2. 數據:RGB RGB RGB
  3. 分解:RRR GGG BBB
  4. RLE:3R 3G 3B

 

8Bit (256色)『RLE解碼』C代碼:

void Load_RLE_PCX(PBYTE image, PBYTE data, int width,int height)

{

BYTE value;

int length;// 像素個數

int data_index = 0;// RLE索引

int image_index = 0;// 圖像索引

int image_size = width * height;

while (image_index < image_size)// 遍歷壓縮後數據

{// 判斷是否RLE編碼

if (data[data_index] >= 192 && data[data_index] <= 255)

{// 重複的數據

length = data[data_index] – 192;// 長度

value  = data[data_index + 1];// 索引值

while (length > 0)

{

image[image_index] = value;

++image_index;

–length;

}

data_index = data_index + 2;

}

else

{// 不重的數據

image[image_index] = data[data_index];

++image_index;

++data_index;

}

}

}

 

24Bit『RLE解碼』C代碼:

void Load_RLE24_PCX(PBYTE image, PBYTE data, int width, int height)

{

BYTE value;

int length = 0;// 像素個數

int data_index = 0; // RLE索引

int image_index = 0; // 圖像索引

int image_size = width * height;

for (image_index = 0; image_index < image_size; image_index = image_index + width)// 遍歷RLE編碼數據

{

for (int i = 0, x = 0; i < 3 && x < width; )

{// 判斷是否RLE編碼

if (data[data_index] >= 192 && data[data_index] <= 255)

{// 讀取重複的數據

length = data[data_index] – 192;// 數據的長度

//length = data[data_index] & 0x3F;

value = data[data_index + 1];// 數值

data_index = data_index + 2; // RLE編碼索引

while (length > 0)

{

if (x >= width)

{

++i;

x = 0;// 以達到行尾跳轉 i加1 x設0

}

image[(image_index + x) * 3 + i] = value;//寫入重複數據

++x;// x座標索引加一

–length;// 重複數據量減一

}

}

else

{// 無壓縮的數據

image[(image_index + x) * 3 + i] = data[data_index];// 寫入

++data_index; // RLE編碼索引

++x;

}

if (x >= width)

{

++i;

x = 0;

}

}

}

return;

}

 

評論