imagbmp.cpp
来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 1,492 行 · 第 1/4 页
CPP
1,492 行
for (int k = 0; k < absolute; k++)
{
linepos++;
aByte = stream.GetC();
ptr[poffset ] = cmap[aByte].r;
ptr[poffset + 1] = cmap[aByte].g;
ptr[poffset + 2] = cmap[aByte].b;
column++;
}
if ( absolute & 0x01 )
aByte = stream.GetC();
}
}
else
{
for ( int l = 0; l < first && column < width; l++ )
{
ptr[poffset ] = cmap[aByte].r;
ptr[poffset + 1] = cmap[aByte].g;
ptr[poffset + 2] = cmap[aByte].b;
column++;
linepos++;
}
}
}
else
{
ptr[poffset ] = cmap[aByte].r;
ptr[poffset + 1] = cmap[aByte].g;
ptr[poffset + 2] = cmap[aByte].b;
column++;
// linepos += size; seems to be wrong, RR
}
}
}
else if ( bpp == 24 )
{
stream.Read(bbuf, 3);
linepos += 3;
ptr[poffset ] = (unsigned char)bbuf[2];
ptr[poffset + 1] = (unsigned char)bbuf[1];
ptr[poffset + 2] = (unsigned char)bbuf[0];
column++;
}
else if ( bpp == 16 )
{
unsigned char temp;
stream.Read(&aWord, 2);
aWord = wxUINT16_SWAP_ON_BE(aWord);
linepos += 2;
/* use the masks and calculated amonut of shift
to retrieve the color data out of the word. Then
shift it left by (8 - number of bits) such that
the image has the proper dynamic range */
temp = (unsigned char)((aWord & rmask) >> rshift << (8-rbits));
ptr[poffset] = temp;
temp = (unsigned char)((aWord & gmask) >> gshift << (8-gbits));
ptr[poffset + 1] = temp;
temp = (unsigned char)((aWord & bmask) >> bshift << (8-bbits));
ptr[poffset + 2] = temp;
column++;
}
else
{
unsigned char temp;
stream.Read(&aDword, 4);
aDword = wxINT32_SWAP_ON_BE(aDword);
linepos += 4;
temp = (unsigned char)((aDword & rmask) >> rshift);
ptr[poffset] = temp;
temp = (unsigned char)((aDword & gmask) >> gshift);
ptr[poffset + 1] = temp;
temp = (unsigned char)((aDword & bmask) >> bshift);
ptr[poffset + 2] = temp;
column++;
}
}
while ( (linepos < linesize) && (comp != 1) && (comp != 2) )
{
stream.Read(&aByte, 1);
linepos += 1;
if ( !stream )
break;
}
}
delete[] cmap;
image->SetMask(false);
const wxStreamError err = stream.GetLastError();
return err == wxSTREAM_NO_ERROR || err == wxSTREAM_EOF;
}
bool wxBMPHandler::LoadDib(wxImage *image, wxInputStream& stream,
bool verbose, bool IsBmp)
{
wxUint16 aWord;
wxInt32 dbuf[4];
wxInt8 bbuf[4];
wxFileOffset offset = 0; // keep gcc quiet
if ( IsBmp )
{
// read the header off the .BMP format file
offset = stream.TellI();
if (offset == wxInvalidOffset)
offset = 0;
stream.Read(bbuf, 2);
stream.Read(dbuf, 16);
}
else
{
stream.Read(dbuf, 4);
}
#if 0 // unused
wxInt32 size = wxINT32_SWAP_ON_BE(dbuf[0]);
#endif
offset = offset + wxINT32_SWAP_ON_BE(dbuf[2]);
stream.Read(dbuf, 4 * 2);
int width = wxINT32_SWAP_ON_BE((int)dbuf[0]);
int height = wxINT32_SWAP_ON_BE((int)dbuf[1]);
if ( !IsBmp)height = height / 2; // for icons divide by 2
if ( width > 32767 )
{
if (verbose)
wxLogError( _("DIB Header: Image width > 32767 pixels for file.") );
return false;
}
if ( height > 32767 )
{
if (verbose)
wxLogError( _("DIB Header: Image height > 32767 pixels for file.") );
return false;
}
stream.Read(&aWord, 2);
/*
TODO
int planes = (int)wxUINT16_SWAP_ON_BE( aWord );
*/
stream.Read(&aWord, 2);
int bpp = wxUINT16_SWAP_ON_BE((int)aWord);
if ( bpp != 1 && bpp != 4 && bpp != 8 && bpp != 16 && bpp != 24 && bpp != 32 )
{
if (verbose)
wxLogError( _("DIB Header: Unknown bitdepth in file.") );
return false;
}
stream.Read(dbuf, 4 * 4);
int comp = wxINT32_SWAP_ON_BE((int)dbuf[0]);
if ( comp != BI_RGB && comp != BI_RLE4 && comp != BI_RLE8 &&
comp != BI_BITFIELDS )
{
if (verbose)
wxLogError( _("DIB Header: Unknown encoding in file.") );
return false;
}
stream.Read(dbuf, 4 * 2);
int ncolors = wxINT32_SWAP_ON_BE( (int)dbuf[0] );
if (ncolors == 0)
ncolors = 1 << bpp;
/* some more sanity checks */
if (((comp == BI_RLE4) && (bpp != 4)) ||
((comp == BI_RLE8) && (bpp != 8)) ||
((comp == BI_BITFIELDS) && (bpp != 16 && bpp != 32)))
{
if (verbose)
wxLogError( _("DIB Header: Encoding doesn't match bitdepth.") );
return false;
}
//read DIB; this is the BMP image or the XOR part of an icon image
if ( !DoLoadDib(image, width, height, bpp, ncolors, comp, offset, stream,
verbose, IsBmp, true) )
{
if (verbose)
wxLogError( _("Error in reading image DIB .") );
return false;
}
if ( !IsBmp )
{
//read Icon mask which is monochrome
//there is no palette, so we will create one
wxImage mask;
if ( !DoLoadDib(&mask, width, height, 1, 2, BI_RGB, offset, stream,
verbose, IsBmp, false) )
{
if (verbose)
wxLogError( _("ICO: Error in reading mask DIB.") );
return false;
}
image->SetMaskFromImage(mask, 255, 255, 255);
}
return true;
}
bool wxBMPHandler::LoadFile(wxImage *image, wxInputStream& stream,
bool verbose, int WXUNUSED(index))
{
// Read a single DIB fom the file:
return LoadDib(image, stream, verbose, true/*isBmp*/);
}
bool wxBMPHandler::DoCanRead(wxInputStream& stream)
{
unsigned char hdr[2];
if ( !stream.Read(hdr, WXSIZEOF(hdr)) )
return false;
// do we have the BMP file signature?
return hdr[0] == 'B' && hdr[1] == 'M';
}
#endif // wxUSE_STREAMS
#if wxUSE_ICO_CUR
//-----------------------------------------------------------------------------
// wxICOHandler
//-----------------------------------------------------------------------------
IMPLEMENT_DYNAMIC_CLASS(wxICOHandler, wxBMPHandler)
#if wxUSE_STREAMS
struct ICONDIRENTRY
{
wxUint8 bWidth; // Width of the image
wxUint8 bHeight; // Height of the image (times 2)
wxUint8 bColorCount; // Number of colors in image (0 if >=8bpp)
wxUint8 bReserved; // Reserved
// these two are different in icons and cursors:
// icon or cursor
wxUint16 wPlanes; // Color Planes or XHotSpot
wxUint16 wBitCount; // Bits per pixel or YHotSpot
wxUint32 dwBytesInRes; // how many bytes in this resource?
wxUint32 dwImageOffset; // where in the file is this image
};
struct ICONDIR
{
wxUint16 idReserved; // Reserved
wxUint16 idType; // resource type (1 for icons, 2 for cursors)
wxUint16 idCount; // how many images?
};
bool wxICOHandler::SaveFile(wxImage *image,
wxOutputStream& stream,
bool verbose)
{
//sanity check; icon must be less than 127 pixels high and 255 wide
if ( image->GetHeight () > 127 )
{
if ( verbose )
wxLogError(_("ICO: Image too tall for an icon."));
return false;
}
if ( image->GetWidth () > 255 )
{
if ( verbose )
wxLogError(_("ICO: Image too wide for an icon."));
return false;
}
const int images = 1; // only generate one image
// VS: This is a hack of sort - since ICO and CUR files are almost
// identical, we have all the meat in wxICOHandler and check for
// the actual (handler) type when the code has to distinguish between
// the two formats
int type = (this->GetType() == wxBITMAP_TYPE_CUR) ? 2 : 1;
// write a header, (ICONDIR)
// Calculate the header size
wxUint32 offset = 3 * sizeof(wxUint16);
ICONDIR IconDir;
IconDir.idReserved = 0;
IconDir.idType = wxUINT16_SWAP_ON_BE((wxUint16)type);
IconDir.idCount = wxUINT16_SWAP_ON_BE((wxUint16)images);
stream.Write(&IconDir.idReserved, sizeof(IconDir.idReserved));
stream.Write(&IconDir.idType, sizeof(IconDir.idType));
stream.Write(&IconDir.idCount, sizeof(IconDir.idCount));
if ( !stream.IsOk() )
{
if ( verbose )
wxLogError(_("ICO: Error writing the image file!"));
return false;
}
// for each iamage write a description ICONDIRENTRY:
ICONDIRENTRY icondirentry;
for (int img = 0; img < images; img++)
{
wxImage mask;
if ( image->HasMask() )
{
// make another image with black/white:
mask = image->ConvertToMono (image->GetMaskRed(), image->GetMaskGreen(), image->GetMaskBlue() );
// now we need to change the masked regions to black:
unsigned char r = image->GetMaskRed();
unsigned char g = image->GetMaskGreen();
unsigned char b = image->GetMaskBlue();
if ( (r != 0) || (g != 0) || (b != 0) )
{
// Go round and apply black to the masked bits:
int i, j;
for (i = 0; i < mask.GetWidth(); i++)
{
for (j = 0; j < mask.GetHeight(); j++)
{
if ((r == mask.GetRed(i, j)) &&
(g == mask.GetGreen(i, j))&&
(b == mask.GetBlue(i, j)) )
image->SetRGB(i, j, 0, 0, 0 );
}
}
}
}
else
{
// just make a black mask all over:
mask = image->Copy();
int i, j;
for (i = 0; i < mask.GetWidth(); i++)
for (j = 0; j < mask.GetHeight(); j++)
mask.SetRGB(i, j, 0, 0, 0 );
}
// Set the formats for image and mask
// (Windows never saves with more than 8 colors):
image->SetOption(wxIMAGE_OPTION_BMP_FORMAT, wxBMP_8BPP);
// monochome bitmap:
mask.SetOption(wxIMAGE_OPTION_BMP_FORMAT, wxBMP_1BPP_BW);
bool IsBmp = false;
bool IsMask = false;
//calculate size and offset of image and mask
wxCountingOutputStream cStream;
bool bResult = SaveDib(image, cStream, verbose, IsBmp, IsMask);
if ( !bResult )
{
if ( verbose )
wxLogError(_("ICO: Error writing the image file!"));
return false;
}
IsMask = true;
bResult = SaveDib(&mask, cStream, verbose, IsBmp, IsMask);
if ( !bResult )
{
if ( verbose )
wxLogError(_("ICO: Error writing the image file!"));
return false;
}
wxUint32 Size = cStream.GetSize();
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?