imagbmp.cpp
来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 1,492 行 · 第 1/4 页
CPP
1,492 行
// wxCountingOutputStream::Ok() always returns true for now and this
// "if" provokes VC++ warnings in optimized build
#if 0
if ( !cStream.Ok() )
{
if ( verbose )
wxLogError(_("ICO: Error writing the image file!"));
return false;
}
#endif // 0
offset = offset + sizeof(ICONDIRENTRY);
icondirentry.bWidth = (wxUint8)image->GetWidth();
icondirentry.bHeight = (wxUint8)(2 * image->GetHeight());
icondirentry.bColorCount = 0;
icondirentry.bReserved = 0;
icondirentry.wPlanes = wxUINT16_SWAP_ON_BE(1);
icondirentry.wBitCount = wxUINT16_SWAP_ON_BE(wxBMP_8BPP);
if ( type == 2 /*CUR*/)
{
int hx = image->HasOption(wxIMAGE_OPTION_CUR_HOTSPOT_X) ?
image->GetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_X) :
image->GetWidth() / 2;
int hy = image->HasOption(wxIMAGE_OPTION_CUR_HOTSPOT_Y) ?
image->GetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_Y) :
image->GetHeight() / 2;
// actually write the values of the hot spot here:
icondirentry.wPlanes = wxUINT16_SWAP_ON_BE((wxUint16)hx);
icondirentry.wBitCount = wxUINT16_SWAP_ON_BE((wxUint16)hy);
}
icondirentry.dwBytesInRes = wxUINT32_SWAP_ON_BE(Size);
icondirentry.dwImageOffset = wxUINT32_SWAP_ON_BE(offset);
// increase size to allow for the data written:
offset += Size;
// write to stream:
stream.Write(&icondirentry.bWidth, sizeof(icondirentry.bWidth));
stream.Write(&icondirentry.bHeight, sizeof(icondirentry.bHeight));
stream.Write(&icondirentry.bColorCount, sizeof(icondirentry.bColorCount));
stream.Write(&icondirentry.bReserved, sizeof(icondirentry.bReserved));
stream.Write(&icondirentry.wPlanes, sizeof(icondirentry.wPlanes));
stream.Write(&icondirentry.wBitCount, sizeof(icondirentry.wBitCount));
stream.Write(&icondirentry.dwBytesInRes, sizeof(icondirentry.dwBytesInRes));
stream.Write(&icondirentry.dwImageOffset, sizeof(icondirentry.dwImageOffset));
if ( !stream.IsOk() )
{
if ( verbose )
wxLogError(_("ICO: Error writing the image file!"));
return false;
}
// actually save it:
IsMask = false;
bResult = SaveDib(image, stream, verbose, IsBmp, IsMask);
if ( !bResult )
{
if ( verbose )
wxLogError(_("ICO: Error writing the image file!"));
return false;
}
IsMask = true;
bResult = SaveDib(&mask, stream, verbose, IsBmp, IsMask);
if ( !bResult )
{
if ( verbose )
wxLogError(_("ICO: Error writing the image file!"));
return false;
}
} // end of for loop
return true;
}
bool wxICOHandler::LoadFile(wxImage *image, wxInputStream& stream,
bool verbose, int index)
{
stream.SeekI(0);
return DoLoadFile(image, stream, verbose, index);
}
bool wxICOHandler::DoLoadFile(wxImage *image, wxInputStream& stream,
bool WXUNUSED(verbose), int index)
{
bool bResult wxDUMMY_INITIALIZE(false);
bool IsBmp = false;
ICONDIR IconDir;
wxFileOffset iPos = stream.TellI();
stream.Read(&IconDir, sizeof(IconDir));
wxUint16 nIcons = wxUINT16_SWAP_ON_BE(IconDir.idCount);
// nType is 1 for Icons, 2 for Cursors:
wxUint16 nType = wxUINT16_SWAP_ON_BE(IconDir.idType);
// loop round the icons and choose the best one:
ICONDIRENTRY *pIconDirEntry = new ICONDIRENTRY[nIcons];
ICONDIRENTRY *pCurrentEntry = pIconDirEntry;
int wMax = 0;
int colmax = 0;
int iSel = wxNOT_FOUND;
for (int i = 0; i < nIcons; i++ )
{
stream.Read(pCurrentEntry, sizeof(ICONDIRENTRY));
// bHeight and bColorCount are wxUint8
if ( pCurrentEntry->bWidth >= wMax )
{
// see if we have more colors, ==0 indicates > 8bpp:
if ( pCurrentEntry->bColorCount == 0 )
pCurrentEntry->bColorCount = 255;
if ( pCurrentEntry->bColorCount >= colmax )
{
iSel = i;
wMax = pCurrentEntry->bWidth;
colmax = pCurrentEntry->bColorCount;
}
}
pCurrentEntry++;
}
if ( index != -1 )
{
// VS: Note that we *have* to run the loop above even if index != -1, because
// it reads ICONDIRENTRies.
iSel = index;
}
if ( iSel == wxNOT_FOUND || iSel < 0 || iSel >= nIcons )
{
wxLogError(_("ICO: Invalid icon index."));
bResult = false;
}
else
{
// seek to selected icon:
pCurrentEntry = pIconDirEntry + iSel;
stream.SeekI(iPos + wxUINT32_SWAP_ON_BE(pCurrentEntry->dwImageOffset), wxFromStart);
bResult = LoadDib(image, stream, true, IsBmp);
bool bIsCursorType = (this->GetType() == wxBITMAP_TYPE_CUR) || (this->GetType() == wxBITMAP_TYPE_ANI);
if ( bResult && bIsCursorType && nType == 2 )
{
// it is a cursor, so let's set the hotspot:
image->SetOption(wxIMAGE_OPTION_CUR_HOTSPOT_X, wxUINT16_SWAP_ON_BE(pCurrentEntry->wPlanes));
image->SetOption(wxIMAGE_OPTION_CUR_HOTSPOT_Y, wxUINT16_SWAP_ON_BE(pCurrentEntry->wBitCount));
}
}
delete[] pIconDirEntry;
return bResult;
}
int wxICOHandler::GetImageCount(wxInputStream& stream)
{
ICONDIR IconDir;
wxFileOffset iPos = stream.TellI();
stream.SeekI(0);
stream.Read(&IconDir, sizeof(IconDir));
wxUint16 nIcons = wxUINT16_SWAP_ON_BE(IconDir.idCount);
stream.SeekI(iPos);
return (int)nIcons;
}
bool wxICOHandler::DoCanRead(wxInputStream& stream)
{
stream.SeekI(0);
unsigned char hdr[4];
if ( !stream.Read(hdr, WXSIZEOF(hdr)) )
return false;
// hdr[2] is one for an icon and two for a cursor
return hdr[0] == '\0' && hdr[1] == '\0' && hdr[2] == '\1' && hdr[3] == '\0';
}
#endif // wxUSE_STREAMS
//-----------------------------------------------------------------------------
// wxCURHandler
//-----------------------------------------------------------------------------
IMPLEMENT_DYNAMIC_CLASS(wxCURHandler, wxICOHandler)
#if wxUSE_STREAMS
bool wxCURHandler::DoCanRead(wxInputStream& stream)
{
stream.SeekI(0);
unsigned char hdr[4];
if ( !stream.Read(hdr, WXSIZEOF(hdr)) )
return false;
// hdr[2] is one for an icon and two for a cursor
return hdr[0] == '\0' && hdr[1] == '\0' && hdr[2] == '\2' && hdr[3] == '\0';
}
#endif // wxUSE_STREAMS
//-----------------------------------------------------------------------------
// wxANIHandler
//-----------------------------------------------------------------------------
IMPLEMENT_DYNAMIC_CLASS(wxANIHandler, wxCURHandler)
#if wxUSE_STREAMS
bool wxANIHandler::LoadFile(wxImage *image, wxInputStream& stream,
bool verbose, int index)
{
wxInt32 FCC1, FCC2;
wxUint32 datalen;
wxInt32 riff32;
memcpy( &riff32, "RIFF", 4 );
wxInt32 list32;
memcpy( &list32, "LIST", 4 );
wxInt32 ico32;
memcpy( &ico32, "icon", 4 );
int iIcon = 0;
stream.SeekI(0);
stream.Read(&FCC1, 4);
if ( FCC1 != riff32 )
return false;
// we have a riff file:
while (stream.IsOk())
{
// we always have a data size
stream.Read(&datalen, 4);
datalen = wxINT32_SWAP_ON_BE(datalen) ;
//data should be padded to make even number of bytes
if (datalen % 2 == 1) datalen ++ ;
//now either data or a FCC
if ( (FCC1 == riff32) || (FCC1 == list32) )
{
stream.Read(&FCC2, 4);
}
else
{
if (FCC1 == ico32 && iIcon >= index)
{
return DoLoadFile(image, stream, verbose, -1);
}
else
{
stream.SeekI(stream.TellI() + datalen);
if ( FCC1 == ico32 )
iIcon ++;
}
}
// try to read next data chunk:
stream.Read(&FCC1, 4);
}
return false;
}
bool wxANIHandler::DoCanRead(wxInputStream& stream)
{
wxInt32 FCC1, FCC2;
wxUint32 datalen ;
wxInt32 riff32;
memcpy( &riff32, "RIFF", 4 );
wxInt32 list32;
memcpy( &list32, "LIST", 4 );
wxInt32 ico32;
memcpy( &ico32, "icon", 4 );
wxInt32 anih32;
memcpy( &anih32, "anih", 4 );
stream.SeekI(0);
if ( !stream.Read(&FCC1, 4) )
return false;
if ( FCC1 != riff32 )
return false;
// we have a riff file:
while ( stream.IsOk() )
{
if ( FCC1 == anih32 )
return true;
// we always have a data size:
stream.Read(&datalen, 4);
datalen = wxINT32_SWAP_ON_BE(datalen) ;
//data should be padded to make even number of bytes
if (datalen % 2 == 1) datalen ++ ;
// now either data or a FCC:
if ( (FCC1 == riff32) || (FCC1 == list32) )
{
stream.Read(&FCC2, 4);
}
else
{
stream.SeekI(stream.TellI() + datalen);
}
// try to read next data chunk:
if ( !stream.Read(&FCC1, 4) )
{
// reading failed -- either EOF or IO error, bail out anyhow
return false;
}
}
return false;
}
int wxANIHandler::GetImageCount(wxInputStream& stream)
{
wxInt32 FCC1, FCC2;
wxUint32 datalen ;
wxInt32 riff32;
memcpy( &riff32, "RIFF", 4 );
wxInt32 list32;
memcpy( &list32, "LIST", 4 );
wxInt32 ico32;
memcpy( &ico32, "icon", 4 );
wxInt32 anih32;
memcpy( &anih32, "anih", 4 );
stream.SeekI(0);
stream.Read(&FCC1, 4);
if ( FCC1 != riff32 )
return wxNOT_FOUND;
// we have a riff file:
while ( stream.IsOk() )
{
// we always have a data size:
stream.Read(&datalen, 4);
datalen = wxINT32_SWAP_ON_BE(datalen) ;
//data should be padded to make even number of bytes
if (datalen % 2 == 1) datalen ++ ;
// now either data or a FCC:
if ( (FCC1 == riff32) || (FCC1 == list32) )
{
stream.Read(&FCC2, 4);
}
else
{
if ( FCC1 == anih32 )
{
wxUint32 *pData = new wxUint32[datalen/4];
stream.Read(pData, datalen);
int nIcons = wxINT32_SWAP_ON_BE(*(pData + 1));
delete[] pData;
return nIcons;
}
else
stream.SeekI(stream.TellI() + datalen);
}
// try to read next data chunk:
stream.Read(&FCC1, 4);
}
return wxNOT_FOUND;
}
#endif // wxUSE_STREAMS
#endif // wxUSE_ICO_CUR
#endif // wxUSE_IMAGE
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?