C++图像处理 -- PCX格式图像(上) (二)
Line)
{
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;
if (header->flag != 0x0a) return NULL;
PRGBTriple ppal = NULL;
PixelFormat format = PixelFormatUndefined;
if (header->bitsPrePixel == 1)
{
if (header->planes == 4)
{
format = PixelFormat4bppIndexed;
ppal = (PRGBTriple)header->palette;
}
else format = PixelFormat1bppIndexed;
}
else
{
if (header->planes == 3)
format = PixelFormat24bppRGB;
else if (header->planes == 1)
{
ppal = (PRGBTriple)(imageMem + imageBytes - 256 * 3);
if (*((LPBYTE)ppal - 1) == 0x0c)
format = PixelFormat8bppIndexed;
}
}
if (format == PixelFormatUndefined) return NULL;
Bitmap *bmp = new Bitmap(header->
xMax - header->xMin + 1,
header->yMax - header->yMin + 1, format);
if (ppal)
{
INT count = 1 << (header->bitsPrePixel * header->planes);
ColorPalette *pal = (ColorPalette*)new BYTE[count * sizeof(ARGB) + sizeof(ColorPalette)];
PRGBQuad pp = (PRGBQuad)pal->Entries;
for (INT i = 0; i < count; i ++)
{
pp[i].rgbBlue = ppal[i].rgbtRed;
pp[i].rgbGreen = ppal[i].rgbtGreen;
pp[i].rgbRed = ppal[i].rgbtBlue;
pp[i].rgbReserved = 255;
}
pal->Flags = 0;
pal->Count = count;
bmp->SetPalette(pal);
delete[] pal;
}
LPBYTE bitsMem = imageMem + sizeof(PcxFileHeader);
BitmapData data;
Gdiplus::Rect r(0, 0, bmp->GetWidth(), bmp->GetHeight());
bmp->LockBits(&r, ImageLockModeRead | ImageLockModeWrite, format, &data);
switch (format)
{
case PixelFormat4bppIndexed:
UnpackPck4(&data, bitsMem, header->bytesPreLine);
break;
case PixelFormat24bppRGB:
UnpackPck24(&data, bitsMem, header->bytesPreLine);
break;
default:
UnpackPck(&data, bitsMem, header->bytesPreLine);
}
bmp->UnlockBits(&data);
return bmp;
}
//---------------------------------------------------------------------------
Bitmap *LoadPcxImageFromStream(IStream *stream)
{
LARGE_INTEGER move;
ULARGE_INTEGER size;
move.QuadPart = 0;
if (stream->Seek(move, STREAM_SEEK_END, &size) != S_OK)
return NULL;
stream->Seek(move, STREAM_SEEK_SET, NULL);
LPBYTE imageMem = new BYTE[size.LowPart];
Bitmap *bmp = NULL;