『PCX』與『BMP』同樣支持『RLE編碼』,而且支持8Bit和24Bit的『RLE編碼』渲染演示程式下載:
先講解8Bit (256色)『RLE編碼』算法:
- 首字節把『重複』像素的個數的最高兩BIT設為1保存, 0xC0&length
- 解碼時只要把首字節減192即等於『重複』個數,或者data& 0x3F提取最低六位.
- 次字節寫入重複的像素值
- 並且『重複』像素的最大長度為63,因為255(0xff)-192(0xc0)=63
- 如果像素大於192,把像數當成『不重複』的像素直接保存
- 『不重複』的像素直接保存
PCX的24BIT圖檔同樣使用『RLE編碼』,但網絡上PCX的24Bit『RLE解碼』算法大多都是不正確,
24Bit『RLE編碼』算法:
- 24BIT算法8Bit基本一致.最大分別是它對每行像素的RGB值進行分解後再進行RLE編碼
- 數據:RGB RGB RGB
- 分解:RRR GGG BBB
- 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;
}