imagpcx.cpp
来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 508 行 · 第 1/2 页
CPP
508 行
for (i = 0; i < width; i++)
{
*(dst++) = p[i];
*(dst++) = p[i + bytesperline];
*(dst++) = p[i + 2 * bytesperline];
}
break;
}
}
}
free(p);
// For 8 bit images, we read the palette, and then do a second
// pass replacing indexes with their RGB values;
if (format == wxPCX_8BIT)
{
unsigned char index;
if (stream.GetC() != 12)
return wxPCX_INVFORMAT;
stream.Read(pal, 768);
p = image->GetData();
for (unsigned long k = height * width; k; k--)
{
index = *p;
*(p++) = pal[3 * index];
*(p++) = pal[3 * index + 1];
*(p++) = pal[3 * index + 2];
}
#if wxUSE_PALETTE
unsigned char r[256];
unsigned char g[256];
unsigned char b[256];
for (i = 0; i < 256; i++)
{
r[i] = pal[3*i + 0];
g[i] = pal[3*i + 1];
b[i] = pal[3*i + 2];
}
image->SetPalette(wxPalette(256, r, g, b));
#endif // wxUSE_PALETTE
}
return wxPCX_OK;
}
// SavePCX:
// Saves a PCX file into the wxImage object pointed by image.
// Returns wxPCX_OK on success, or an error code otherwise
// (see above for error codes). Will try to save as 8-bit
// PCX if possible, and then fall back to 24-bit if there
// are more than 256 different colours.
//
int SavePCX(wxImage *image, wxOutputStream& stream)
{
unsigned char hdr[128]; // PCX header
unsigned char pal[768]; // palette for 8 bit images
unsigned char *p; // space to store one scanline
unsigned char *src; // pointer into wxImage data
unsigned int width, height; // size of the image
unsigned int bytesperline; // bytes per line (each plane)
unsigned char nplanes = 3; // number of planes
int format = wxPCX_24BIT; // image format (8 bit, 24 bit)
wxImageHistogram histogram; // image histogram
unsigned long key; // key in the hashtable
unsigned int i;
// See if we can save as 8 bit.
if (image->CountColours(256) <= 256)
{
image->ComputeHistogram(histogram);
format = wxPCX_8BIT;
nplanes = 1;
}
// Get image dimensions, calculate bytesperline (must be even,
// according to PCX specs) and allocate space for one complete
// scanline.
if (!image->Ok())
return wxPCX_INVFORMAT;
width = image->GetWidth();
height = image->GetHeight();
bytesperline = width;
if (bytesperline % 2)
bytesperline++;
if ((p = (unsigned char *) malloc(bytesperline * nplanes)) == NULL)
return wxPCX_MEMERR;
// Build header data and write it to the stream. Initially,
// set all bytes to zero (most values default to zero).
memset(hdr, 0, sizeof(hdr));
hdr[HDR_MANUFACTURER] = 10;
hdr[HDR_VERSION] = 5;
hdr[HDR_ENCODING] = 1;
hdr[HDR_NPLANES] = nplanes;
hdr[HDR_BITSPERPIXEL] = 8;
hdr[HDR_BYTESPERLINE] = (unsigned char)(bytesperline % 256);
hdr[HDR_BYTESPERLINE + 1] = (unsigned char)(bytesperline / 256);
hdr[HDR_XMAX] = (unsigned char)((width - 1) % 256);
hdr[HDR_XMAX + 1] = (unsigned char)((width - 1) / 256);
hdr[HDR_YMAX] = (unsigned char)((height - 1) % 256);
hdr[HDR_YMAX + 1] = (unsigned char)((height - 1) / 256);
hdr[HDR_PALETTEINFO] = 1;
stream.Write(hdr, 128);
// Encode image data line by line and write it to the stream
src = image->GetData();
for (; height; height--)
{
switch (format)
{
case wxPCX_8BIT:
{
unsigned char r, g, b;
for (i = 0; i < width; i++)
{
r = *(src++);
g = *(src++);
b = *(src++);
key = (r << 16) | (g << 8) | b;
p[i] = (unsigned char)histogram[key].index;
}
break;
}
case wxPCX_24BIT:
{
for (i = 0; i < width; i++)
{
p[i] = *(src++);
p[i + bytesperline] = *(src++);
p[i + 2 * bytesperline] = *(src++);
}
break;
}
}
RLEencode(p, bytesperline * nplanes, stream);
}
free(p);
// For 8 bit images, build the palette and write it to the stream:
if (format == wxPCX_8BIT)
{
// zero unused colours
memset(pal, 0, sizeof(pal));
unsigned long index;
for (wxImageHistogram::iterator entry = histogram.begin();
entry != histogram.end(); ++entry )
{
key = entry->first;
index = entry->second.index;
pal[3 * index] = (unsigned char)(key >> 16);
pal[3 * index + 1] = (unsigned char)(key >> 8);
pal[3 * index + 2] = (unsigned char)(key);
}
stream.PutC(12);
stream.Write(pal, 768);
}
return wxPCX_OK;
}
//-----------------------------------------------------------------------------
// wxPCXHandler
//-----------------------------------------------------------------------------
bool wxPCXHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbose, int WXUNUSED(index) )
{
int error;
if (!CanRead(stream))
{
if (verbose)
wxLogError(_("PCX: this is not a PCX file."));
return false;
}
image->Destroy();
if ((error = ReadPCX(image, stream)) != wxPCX_OK)
{
if (verbose)
{
switch (error)
{
case wxPCX_INVFORMAT: wxLogError(_("PCX: image format unsupported")); break;
case wxPCX_MEMERR: wxLogError(_("PCX: couldn't allocate memory")); break;
case wxPCX_VERERR: wxLogError(_("PCX: version number too low")); break;
default: wxLogError(_("PCX: unknown error !!!"));
}
}
image->Destroy();
return false;
}
return true;
}
bool wxPCXHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbose )
{
int error;
if ((error = SavePCX(image, stream)) != wxPCX_OK)
{
if (verbose)
{
switch (error)
{
case wxPCX_INVFORMAT: wxLogError(_("PCX: invalid image")); break;
case wxPCX_MEMERR: wxLogError(_("PCX: couldn't allocate memory")); break;
default: wxLogError(_("PCX: unknown error !!!"));
}
}
}
return (error == wxPCX_OK);
}
bool wxPCXHandler::DoCanRead( wxInputStream& stream )
{
unsigned char c = stream.GetC();
if ( !stream )
return false;
// not very safe, but this is all we can get from PCX header :-(
return c == 10;
}
#endif // wxUSE_STREAMS
#endif // wxUSE_IMAGE && wxUSE_PCX
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?