Alien-FreeImage
view release on metacpan or search on metacpan
src/Source/FreeImage/PluginICO.cpp view on Meta::CPAN
page = 0;
}
// get the icon header
icon_header = (ICONHEADER*)data;
try {
FIBITMAP *icon_dib = NULL;
// load all icons
for(k = 0; k < icon_header->idCount; k++) {
icon_dib = Load(io, handle, k, flags, data);
if(!icon_dib) {
throw FI_MSG_ERROR_DIB_MEMORY;
}
vPages.push_back(icon_dib);
}
// add the page
icon_dib = FreeImage_Clone(dib);
vPages.push_back(icon_dib);
icon_header->idCount++;
// write the header
io->seek_proc(handle, 0, SEEK_SET);
#ifdef FREEIMAGE_BIGENDIAN
SwapIconHeader(icon_header);
#endif
io->write_proc(icon_header, sizeof(ICONHEADER), 1, handle);
#ifdef FREEIMAGE_BIGENDIAN
SwapIconHeader(icon_header);
#endif
// write all icons
// ...
// save the icon descriptions
ICONDIRENTRY *icon_list = (ICONDIRENTRY *)malloc(icon_header->idCount * sizeof(ICONDIRENTRY));
if(!icon_list) {
throw FI_MSG_ERROR_MEMORY;
}
memset(icon_list, 0, icon_header->idCount * sizeof(ICONDIRENTRY));
for(k = 0; k < icon_header->idCount; k++) {
icon_dib = (FIBITMAP*)vPages[k];
// convert internal format to ICONDIRENTRY
// take into account Vista icons whose size is 256x256
const BITMAPINFOHEADER *bmih = FreeImage_GetInfoHeader(icon_dib);
icon_list[k].bWidth = (bmih->biWidth > 255) ? 0 : (BYTE)bmih->biWidth;
icon_list[k].bHeight = (bmih->biHeight > 255) ? 0 : (BYTE)bmih->biHeight;
icon_list[k].bReserved = 0;
icon_list[k].wPlanes = bmih->biPlanes;
icon_list[k].wBitCount = bmih->biBitCount;
if( (icon_list[k].wPlanes * icon_list[k].wBitCount) >= 8 ) {
icon_list[k].bColorCount = 0;
} else {
icon_list[k].bColorCount = (BYTE)(1 << (icon_list[k].wPlanes * icon_list[k].wBitCount));
}
// initial guess (correct only for standard icons)
icon_list[k].dwBytesInRes = CalculateImageSize(icon_dib);
icon_list[k].dwImageOffset = CalculateImageOffset(vPages, k);
}
// make a room for icon dir entries, until later update
const long directory_start = io->tell_proc(handle);
io->write_proc(icon_list, sizeof(ICONDIRENTRY) * icon_header->idCount, 1, handle);
// write the image bits for each image
DWORD dwImageOffset = (DWORD)io->tell_proc(handle);
for(k = 0; k < icon_header->idCount; k++) {
icon_dib = (FIBITMAP*)vPages[k];
if((icon_list[k].bWidth == 0) && (icon_list[k].bHeight == 0)) {
// Vista icon support
FreeImage_SaveToHandle(FIF_PNG, icon_dib, io, handle, PNG_DEFAULT);
}
else {
// standard icon support
// see http://msdn.microsoft.com/en-us/library/ms997538.aspx
SaveStandardIcon(io, icon_dib, handle);
}
// update ICONDIRENTRY members
DWORD dwBytesInRes = (DWORD)io->tell_proc(handle) - dwImageOffset;
icon_list[k].dwImageOffset = dwImageOffset;
icon_list[k].dwBytesInRes = dwBytesInRes;
dwImageOffset += dwBytesInRes;
}
// update the icon descriptions
const long current_pos = io->tell_proc(handle);
io->seek_proc(handle, directory_start, SEEK_SET);
#ifdef FREEIMAGE_BIGENDIAN
SwapIconDirEntries(icon_list, icon_header->idCount);
#endif
io->write_proc(icon_list, sizeof(ICONDIRENTRY) * icon_header->idCount, 1, handle);
io->seek_proc(handle, current_pos, SEEK_SET);
free(icon_list);
// free the vector class
for(k = 0; k < icon_header->idCount; k++) {
icon_dib = (FIBITMAP*)vPages[k];
FreeImage_Unload(icon_dib);
}
return TRUE;
} catch(const char *text) {
// free the vector class
for(size_t k = 0; k < vPages.size(); k++) {
FIBITMAP *icon_dib = (FIBITMAP*)vPages[k];
FreeImage_Unload(icon_dib);
}
FreeImage_OutputMessageProc(s_format_id, text);
return FALSE;
}
( run in 0.591 second using v1.01-cache-2.11-cpan-411bb0df24b )