📄 graphics.cxx
字号:
colourCount = (PINDEX)(DWORD)bmih.biClrUsed;
for (PINDEX i = 0; i < colourCount; i++) {
P_RGBQUAD rgb(stream);
palette.SetColour(i, rgb);
}
break;
}
case 12 : {
P_BITMAPCOREHEADER bmch(stream);
if (!stream.good())
return;
width = (WORD)bmch.bcWidth;
height = (WORD)bmch.bcHeight;
bitCount = (WORD)bmch.bcBitCount;
imageSize = (width*bitCount+31)/32*height*4;
colourCount = 1 << bitCount;
for (PINDEX i = 0; i < colourCount; i++) {
P_RGBTRIPLE rgb(stream);
palette.SetColour(i, rgb);
}
break;
}
default :
return;
}
if (!stream.good())
return;
if (colourCount == 0) {
for (PINDEX i = 0; i < 256; i++) {
PColour col((BYTE)(i&0xe0), (BYTE)((i<<3)&0xe0), (BYTE)(i<<6));
palette.SetColour(i, col);
}
}
image = PPixelImage((PDIMENSION)width, (PDIMENSION)height, (BYTE)bitCount);
image->SetPalette(palette);
#if defined(_WINDOWS) && !defined(_WIN32)
PPixelDataPtr pixPtr = image->GetPixelDataPtr();
while (imageSize > 0x4000) {
stream.read(pixPtr, 0x4000);
imageSize -= 0x4000;
pixPtr += 0x4000;
}
stream.read(pixPtr, (int)imageSize);
#else
stream.read(image->GetPixelDataPtr(), imageSize);
#endif
}
static int PPM_read_number(istream & stream)
{
while (isspace(stream.peek()))
stream.get();
while (stream.peek() == '#') { // if the line is a comment, then ignore it
stream.ignore(P_MAX_INDEX, '\n');
while (isspace(stream.peek()))
stream.get();
}
// Read number
int num;
stream >> num;
return num;
}
#if 0
void PPixelImage::ReadPPM(istream & stream, BYTE format)
{
// get the width and height
PDIMENSION width = PPM_read_number(stream);
PDIMENSION height = PPM_read_number(stream);
PPalette palette;
BYTE bitCount;
// for each image type, we have to set depth and pixelData
int black, white, max_value;
switch (format) {
case '1':
case '4':
bitCount = 1;
max_value = -1;
black = palette.AddColour(PColour::Black);
white = palette.AddColour(PColour::White);
break;
case '2':
case '5':
bitCount = 8;
max_value = PPM_read_number(stream);
for (int i = 0; i < 128; i++)
palette.AddColour(PColour(i*2, i*2, i*2));
break;
case '3':
case '6':
bitCount = 24;
max_value = PPM_read_number(stream);
break;
}
PPixelImage pix(width, height, bitCount);
// calculate the shift for max_value
int shift;
if (max_value > 0) {
shift = 0;
while ((max_value << (shift+1)) < 255)
shift++;
}
// remove single whitespace after header if in raw format
if (format == '2' || format == '4' || format == '6')
stream.ignore();
int x, y;
// declare a line buffer when needed
PBYTEArray line(width * 3);
BYTE * linePtr = line.GetPointer();
switch (format) {
// PBM ASCII
case '1':
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++)
line[x] = PPM_read_number(stream);
operator->()->SetRaster(y, line, width);
}
break;
// PGM ASCII
case '2':
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++)
line[x] = PPM_read_number(stream);
operator->()->SetRaster(y, line, width);
}
break;
// PPM ASCII
case '3':
for (y = 0; y < height; y++) {
for (x = 0; x < width*3; x++)
line[x] = PPM_read_number(stream);
operator->()->SetRaster(y, line, width);
}
break;
// PBM binary
case '4':
break;
// PGM binary
case '5':
break;
// PPM binary
case '6':
for (y = 0; y < height; y++) {
if (shift == 0)
file.Read (operator->()->GetRasterDataPtr(y), width*3);
else {
file.Read (linePtr, width*3);
BYTE * ptr = linePtr;
BYTE * optr = operator->()->GetRasterDataPtr(y);
for (PINDEX x = width; x > 0; x--)
*optr++ = *ptr++ << shift;
}
}
break;
}
}
#endif
static void ReadPBMa(istream & stream, PPixelImage & image)
{
PDIMENSION width = PPM_read_number(stream);
PDIMENSION height = PPM_read_number(stream);
image = PPixelImage(width, height, 1);
PPalette pal;
pal.AddColour(PColour::Black);
pal.AddColour(PColour::White);
image->SetPalette(pal);
for (PDIMENSION y = 0; y < height; y++)
for (PDIMENSION x = 0; x < width; x++)
image->SetPixel(x, y, (BYTE)PPM_read_number(stream));
}
static void ReadPBMb(istream & stream, PPixelImage & image)
{
PDIMENSION width = PPM_read_number(stream);
PDIMENSION height = PPM_read_number(stream);
image = PPixelImage(width, height, 1);
PPalette pal;
pal.AddColour(PColour::Black);
pal.AddColour(PColour::White);
image->SetPalette(pal);
stream.ignore(); // Skip blank before binary data
for (PDIMENSION y = 0; y < height; y++)
stream.read(image->GetRasterDataPtr(y), width);
}
static void ReadPGMa(istream & stream, PPixelImage & image)
{
PDIMENSION width = PPM_read_number(stream);
PDIMENSION height = PPM_read_number(stream);
/*int max_value =*/ PPM_read_number(stream);
image = PPixelImage(width, height, 8);
PPalette pal;
for (BYTE i = 0; i < 256; i += 2)
pal.AddColour(PColour(i, i, i));
image->SetPalette(pal);
for (PDIMENSION y = 0; y < height; y++)
for (PDIMENSION x = 0; x < width; x++)
image->SetPixel(x, y, (BYTE)PPM_read_number(stream));
}
static void ReadPGMb(istream & stream, PPixelImage & image)
{
PDIMENSION width = PPM_read_number(stream);
PDIMENSION height = PPM_read_number(stream);
int max_value = PPM_read_number(stream);
// calculate the shift for max_value
int shift = 0;
if (max_value > 0) {
while ((max_value << (shift+1)) < 255)
shift++;
}
image = PPixelImage(width, height, 8);
PPalette pal;
for (BYTE i = 0; i < 256; i += 2)
pal.AddColour(PColour(i, i, i));
image->SetPalette(pal);
stream.ignore(); // Skip blank before binary data
for (PDIMENSION y = 0; y < height; y++) {
BYTE * line = image->GetRasterDataPtr(y);
stream.read(line, width*3);
if (shift != 0) {
for (PINDEX x = width; x > 0; x--)
*line++ <<= shift;
}
}
}
static void ReadPPMa(istream & stream, PPixelImage & image)
{
PDIMENSION width = PPM_read_number(stream);
PDIMENSION height = PPM_read_number(stream);
/*int max_value =*/ PPM_read_number(stream);
image = PPixelImage(width, height, 24);
for (PDIMENSION y = 0; y < height; y++) {
BYTE * line = image->GetRasterDataPtr(y);
for (PDIMENSION x = 0; x < width*3; x++)
*line++ = (BYTE)PPM_read_number(stream);
}
}
static void ReadPPMb(istream & stream, PPixelImage & image)
{
PDIMENSION width = PPM_read_number(stream);
PDIMENSION height = PPM_read_number(stream);
int max_value = PPM_read_number(stream);
// calculate the shift for max_value
int shift = 0;
if (max_value > 0) {
while ((max_value << (shift+1)) < 255)
shift++;
}
image = PPixelImage(width, height, 24);
stream.ignore(); // Skip blank before binary data
for (PDIMENSION y = 0; y < height; y++) {
BYTE * line = image->GetRasterDataPtr(y);
stream.read(line, width*3);
if (shift != 0) {
for (PDIMENSION x = width; x > 0; x--)
*line++ <<= shift;
}
}
}
PPixelImage::PPixelImage(istream & stream)
{
// read the magic number
char magic[2];
stream.read(magic, 2);
if (!stream.good())
return;
// determine the format
if (magic[0] == 'B' && magic[1] == 'M')
ReadBMP(stream, *this);
else if (magic[0] == 'P')
switch (magic[1]) {
case '1': // PBM ASCII
ReadPBMa(stream, *this);
break;
case '2': // PGM ASCII
ReadPGMa(stream, *this);
break;
case '3': // PPM ASCII
ReadPPMa(stream, *this);
break;
case '4': // PBM binary
ReadPBMb(stream, *this);
break;
case '5': // PGM binary
ReadPGMb(stream, *this);
break;
case '6': // PPM binary
ReadPPMb(stream, *this);
}
}
void PPixelBase::SetDirtyArea(PORDINATE x, PORDINATE y, PDIMENSION width)
{
PAssert(x >= 0 && (PDIMENSION)x < Width(), "Pixel out of bounds");
if (x < dirtyArea.Left())
dirtyArea.SetLeft(x);
if (x+(PORDINATE)width > dirtyArea.Right())
dirtyArea.SetRight(x+width);
if (y < dirtyArea.Top())
dirtyArea.SetTop(y);
if (y > dirtyArea.Bottom())
dirtyArea.SetBottom(y);
}
void PPixelBase::SetPixelColour(PORDINATE x,PORDINATE y,const PColour & colour)
{
SetPixel(x, y, (BYTE)palette.GetIndex(colour));
}
void PPixels24::SetPixelColour(PORDINATE x,PORDINATE y,const PColour & colour)
{
SetDirtyArea(x, y);
PPixelDataPtr pixel = GetRasterDataPtr(y) + x*3;
*pixel++ = colour.GetRed();
*pixel++ = colour.GetGreen();
*pixel = colour.GetBlue();
}
void PPixels32::SetPixelColour(PORDINATE x,PORDINATE y,const PColour & colour)
{
SetDirtyArea(x, y);
PPixelDataPtr pixel = GetRasterDataPtr(y) + x*4;
*pixel++ = colour.GetRed();
*pixel++ = colour.GetGreen();
*pixel++ = colour.GetBlue();
*pixel = colour.GetAlpha();
}
void PPixels1::SetPixel(PORDINATE x, PORDINATE y, BYTE val)
{
SetDirtyArea(x, y);
PPixelDataPtr pixel = GetRasterDataPtr(y) + (x >> 3);
x &= 7;
*pixel = (BYTE)((*pixel & ~(1 << x)) | (val << x));
}
void PPixels2::SetPixel(PORDINATE x, PORDINATE y, BYTE val)
{
SetDirtyArea(x, y);
PPixelDataPtr pixel = GetRasterDataPtr(y) + (x >> 2);
x &= 3;
*pixel = (BYTE)((*pixel & ~(3 << x)) | (val << (x << 1)));
}
void PPixels4::SetPixel(PORDINATE x, PORDINATE y, BYTE val)
{
SetDirtyArea(x, y);
PPixelDataPtr pixel = GetRasterDataPtr(y) + (x >> 1);
x &= 1;
*pixel = (BYTE)((*pixel & ~(0xf << x)) | (val << (x << 2)));
}
void PPixels8::SetPixel(PORDINATE x, PORDINATE y, BYTE val)
{
SetDirtyArea(x, y);
PPixelDataPtr pixel = GetRasterDataPtr(y) + x;
*pixel = val;
}
void PPixels24::SetPixel(PORDINATE x, PORDINATE y, BYTE val)
{
SetDirtyArea(x, y);
PPixelDataPtr pixel = GetRasterDataPtr(y) + x*3;
*pixel++ = val;
*pixel++ = val;
*pixel = val;
}
void PPixels32::SetPixel(PORDINATE x, PORDINATE y, BYTE val)
{
SetDirtyArea(x, y);
PPixelDataPtr pixel = GetRasterDataPtr(y) + x*4;
*pixel++ = val;
*pixel++ = val;
*pixel++ = val;
*pixel = 0;
}
PColour PPixelBase::GetPixelColour(PORDINATE x, PORDINATE y) const
{
return palette.GetColour(GetPixel(x, y));
}
PColour PPixels24::GetPixelColour(PORDINATE x, PORDINATE y) const
{
PAssert(x >= 0 && (PDIMENSION)x < Width(), "Pixel out of bounds");
PPixelDataPtr pixel = GetRasterDataPtr(y) + x*3;
return PColour(pixel[0], pixel[1], pixel[2]);
}
PColour PPixels32::GetPixelColour(PORDINATE x, PORDINATE y) const
{
PAssert(x >= 0 && (PDIMENSION)x < Width(), "Pixel out of bounds");
PPixelDataPtr pixel = GetRasterDataPtr(y) + x*4;
return PColour(pixel[0], pixel[1], pixel[2], pixel[3]);
}
BYTE PPixels1::GetPixel(PORDINATE x, PORDINATE y) const
{
PAssert(x >= 0 && (PDIMENSION)x < Width(), "Pixel out of bounds");
PPixelDataPtr pixel = GetRasterDataPtr(y) + (x >> 3);
return (BYTE)((*pixel >> (x&7))&1);
}
BYTE PPixels2::GetPixel(PORDINATE x, PORDINATE y) const
{
PAssert(x >= 0 && (PDIMENSION)x < Width(), "Pixel out of bounds");
PPixelDataPtr pixel = GetRasterDataPtr(y) + (x >> 2);
return (BYTE)((*pixel >> ((x&3) << 1))&3);
}
BYTE PPixels4::GetPixel(PORDINATE x, PORDINATE y) const
{
PAssert(x >= 0 && (PDIMENSION)x < Width(), "Pixel out of bounds");
PPixelDataPtr pixel = GetRasterDataPtr(y) + (x >> 1);
return (BYTE)((*pixel >> ((x&1) << 2))&0xf);
}
BYTE PPixels8::GetPixel(PORDINATE x, PORDINATE y) const
{
PAssert(x >= 0 && (PDIMENSION)x < Width(), "Pixel out of bounds");
PPixelDataPtr pixel = GetRasterDataPtr(y) + x;
return *pixel;
}
BYTE PPixels24::GetPixel(PORDINATE x, PORDINATE y) const
{
PAssert(x >= 0 && (PDIMENSION)x < Width(), "Pixel out of bounds");
PPixelDataPtr pixel = GetRasterDataPtr(y) + x*3;
return (BYTE)((pixel[0]*30 + pixel[1]*59 + pixel[2]*11)/100);
}
BYTE PPixels32::GetPixel(PORDINATE x, PORDINATE y) const
{
PAssert(x >= 0 && (PDIMENSION)x < Width(), "Pixel out of bounds");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -