if (stream->Read(imageMem, size.LowPart, NULL) == S_OK)
bmp = UnpackPckImage(imageMem, size.LowPart);
delete[] imageMem;
return bmp;
}
//---------------------------------------------------------------------------
typedef struct
// pcx文件头
{
BYTE flag;
// 标记
BYTE version;
// 版本号
BYTE encodeing;
// 编码方式
BYTE bitsPrePixel;
// 平面像素位数
WORD xMin;
// 最小X
WORD yMin;
// 最小Y
WORD xMax;
// 最大X
WORD yMax;
// 最大Y
WORD hRes;
// 水平分辨率
WORD vRes;
// 垂直分辨率
BYTE palette[48];
// 16色调色板
BYTE reserved;
// 保留
BYTE planes;
// 平面数
WORD bytesPreLine;
// 每行字节数
WORD paletteType;
// 调色板类型。1:彩色或黑白,2:灰度
BYTE filler[58];
}PcxFileHeader, *PPcxFileHeader;
//---------------------------------------------------------------------------
FORCEINLINE
LPBYTE UnpackPckLine(LPBYTE dest, LPBYTE source, INT bytes)
{
while (bytes > 0)
{
if (*source > 0xc0)
{
INT count = *source ++ & 0x3f;
BYTE c = *source ++;
bytes -= count;
for (; count > 0; *dest ++ = c, count --);
}
else
{
*dest ++ = *source ++;
bytes --;
}
}
return source;
}
//---------------------------------------------------------------------------
// 单色或256色
VOID UnpackPck(BitmapData *data, LPBYTE bitsMem, INT bytesPreLine)
{
LPBYTE p = (LPBYTE)data->Scan0;
LPBYTE m = bitsMem;
{
m = UnpackPckLine(p, m, bytesPreLine);
}
}
//---------------------------------------------------------------------------
// 16色
VOID UnpackPck4(BitmapData *data, LPBYTE bitsMem, INT bytesPreLine)
{
LPBYTE p = (LPBYTE)data->Scan0;
LPBYTE m = bitsMem;
INT datOffset = data->Stride -
((GetPixelFormatSize(data->PixelFormat) * data->Width + 7) >> 3);
if (data->Width & 1) datOffset ++;
INT bytes1 = bytesPreLine;
INT bytes2 = bytes1 << 1;
INT bytes3 = bytes2 + bytes1;
INT bytes = bytes1 << 2;
LPBYTE buffer = new BYTE[bytes];
for (UINT y = 0; y < data->Height; y ++, p += datOffset)
{
m = UnpackPckLine(buffer, m, bytes);
LPBYTE b = buffer;
BYTE mask = 0x80;
for (UINT x = 0; x < data->Width; x ++)
{
if (*b & mask) *p |= 1;
if (*(b + bytes1) & mask) *p |= 2;
if (*(b + bytes2) & mask) *p |= 4;
if (*(b + bytes3) & mask) *p |= 8;
if (x & 1) p ++;
else *p <<= 4;
mask >>= 1;
if (!mask)
{
mask = 0x80;
b ++;
}
}
}
delete[] buffer;
}
//---------------------------------------------------------------------------
// 24位真彩色
VOID UnpackPck24(BitmapData *data, LPBYTE bitsMem, INT bytesPreLine)
{
INT bytes1 = bytesPreLine;
INT bytes2 = bytes1 << 1;
INT bytes = bytes2 + bytes1;
INT width = (INT)data->Width > bytesPreLine bytesPreLine : data->Width;
INT datOffset = data->Stride - width * 3;
PRGBTriple p = (PRGBTriple)data->Scan0;
LPBYTE m = bitsMem;
LPBYTE buffer = new BYTE[bytes];
for (INT y = 0; y < (INT)data->Height; y ++, (LPBYTE)p += datOffset)
{
m = UnpackPckLine(buffer, m, bytes);
LPBYTE b = buffer;
for (INT x = 0; x < width; x ++, p ++, b ++)
{
p->rgbtRed
= *b;
p->rgbtGreen = *(b + bytes1);
p->rgbtBlue = *(b + bytes2);
}
}
delete[] buffer;
}
//---------------------------------------------------------------------------
Bitmap *UnpackPckImage(LPBYTE imageMem, INT imageBytes)
{
PcxFileHeader *header = (PcxFileHeader*)imageMem;