C++图像处理 -- PCX格式图像(下) (一)

2014-11-24 08:19:01 · 作者: · 浏览: 0
本文则介绍将GDI+位图转换为PCX格式图像。
下面是GDI+位图转换为PCX格式图像代码:
[cpp]
INT PackPcxLine(LPBYTE dest, LPBYTE source, INT bytesPreLine, INT planes)
{
LPBYTE pd = dest;
INT delta = planes --;
LPBYTE ps = source + planes;
INT bytes = bytesPreLine;
while(planes >= 0)
{
INT count = 0;
BYTE c = *ps;
do
{
count ++;
if (-- bytes == 0)
{
if (-- planes < 0) break;
bytes = bytesPreLine;
ps = source + planes;
}
else ps += delta;
} while(c == *ps && count < 0x3f);
if (c >= 0xc0 || count > 1)
*pd ++ = count | 0xc0;
*pd ++ = c;
}
return pd - dest;
}
//---------------------------------------------------------------------------
typedef union
{
WORD value;
struct
{
BYTE low;
BYTE high;
};
}testMask;
INT PackPcx4Line(LPBYTE dest, LPBYTE source, INT bytesPreLine, INT width)
{
INT bytes = bytesPreLine << 2;
LPBYTE buf = dest + bytes;
testMask mask;
mask.value = 0x1001;
width = (width + 1) >> 1;
while(mask.high)
{
BYTE c = 0;
BYTE bit = 0x80;
LPBYTE pb = buf;
for (INT i = 0; i < width; i ++)
{
if (source[i] & mask.high) c |= bit;
bit >>= 1;
if (source[i] & mask.low) c |= bit;
bit >>= 1;
if (bit == 0)
{
*pb ++ = c;
c = 0;
bit = 0x80;
}
}
buf += bytesPreLine;
mask.value <<= 1;
}
return PackPcxLine(dest, dest + bytes, bytes, 1);
}
//---------------------------------------------------------------------------
VOID ARGBQuadToRGBTriple(PRGBTriple dest, PRGBQuad source, INT count)
{
for (INT i = 0; i < count; i++)
{
dest[i].rgbtBlue = source[i].rgbRed;
dest[i].rgbtGreen = source[i].rgbGreen;
dest[i].rgbtRed = source[i].rgbBlue;
}
}
//---------------------------------------------------------------------------
BOOL SavePcxImageToStream(IStream *stream, Bitmap *bmp)
{
PixelFormat format = bmp->GetPixelFormat();
if (format == PixelFormatUndefined)
return FALSE;
PcxFileHeader header;
ColorPalette *pal = NULL;
BYTE palette[256 * 3 + 1];
ZeroMemory(&header, sizeof(PcxFileHeader));
header.bitsPrePixel = GetPixelFormatSize(format);
header.planes = 1;
if (header.bitsPrePixel > 8)
{
format = PixelFormat24bppRGB;
header.planes = 3;
header.bitsPrePixel = 8;
}
else //if (header.bitsPrePixel > 1)
{
pal = (ColorPalette*)new BYTE[256 * sizeof(ARGB) + sizeof(ColorPalette)];
bmp->GetPalette(pal, bmp->GetPaletteSize());
PRGBTriple ppal = (PRGBTriple)&palette[1];
// 如果是16色位图,调色板保存到文件头
if (format == PixelFormat4bppIndexed)
{
header.planes = header.bitsPrePixel;
header.bitsPrePixel = 1;
ppal = (PRGBTriple)header.palette;
}
ARGBQuadToRGBTriple(ppal, (PRGBQuad)pal->Entries, pal->Count);
delete[] pal;
}
Gdiplus::Rect r(0, 0, bmp->GetWidth(), bmp->GetHeight());
header.flag = 0x0A;
header.version = 5;