-
-
-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
- wxUint16 wPlanes; // Color Planes
- wxUint16 wBitCount; // Bits per pixel
- 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)
- wxUint16 idCount; // how many images?
-} ;
-
-bool wxICOHandler::SaveFile(wxImage *image,
- wxOutputStream& stream,
- bool verbose)
-
-{
- bool bResult = FALSE ;
- //sanity check; icon must be less than 127 pixels high and 255 wide
- if (image -> GetHeight () > 127 )
- {
- if (verbose)
- wxLogError( _("ICO: Error Image too tall for an icon.") );
- return FALSE;
- }
- if (image -> GetWidth () > 255 )
- {
- if (verbose)
- wxLogError( _("ICO: Error Image too wide for an icon.") );
- return FALSE;
- }
-
- // only generate one image
- int m_images = 1 ;
-
- // write a header, (ICONDIR)
- // Calculate the header size
- wxUint32 m_offset = 3 * sizeof(wxUint16);
-
- ICONDIR m_IconDir ;
- m_IconDir.idReserved = 0 ;
- m_IconDir.idType = wxUINT16_SWAP_ON_BE (1);
- m_IconDir.idCount = wxUINT16_SWAP_ON_BE (m_images);
- stream.Write(&m_IconDir.idReserved, sizeof(m_IconDir.idReserved));
- stream.Write(&m_IconDir.idType, sizeof(m_IconDir.idType));
- stream.Write(&m_IconDir.idCount, sizeof(m_IconDir.idCount));
- if ( !stream.IsOk () )
- {
- if (verbose)
- wxLogError( _("ICO: Error writing ICONDIR header.") );
- return FALSE;
- }
-
- // for each iamage write a description ICONDIRENTRY
- ICONDIRENTRY m_icondirentry ;
- int i ;
- for ( i = 0; i < m_images; i++ )
- {
- 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 (wxBMP_FORMAT, wxBMP_8BPP);
- // monochome bitmap
- mask . SetOption (wxBMP_FORMAT, wxBMP_1BPP_BW);
- bool IsBmp = FALSE ;
- bool IsMask = FALSE ;
-
- //calculate size and offset of image and mask
- wxCountingOutputStream cStream ;
- bResult = SaveDib ( image, cStream, verbose, IsBmp, IsMask ) ;
- if (!bResult)
- {
- if (verbose)
- wxLogError( _("ICO: Error calculating size of XOR DIB .") );
- return FALSE;
- }
- IsMask = TRUE ;
- bResult = SaveDib ( &mask, cStream, verbose, IsBmp, IsMask ) ;
- if (!bResult)
- {
- if (verbose)
- wxLogError( _("ICO: Error calculating size of Mask DIB .") );
- return FALSE;
- }
- wxUint32 m_Size = cStream.GetSize();
-
- // 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 calculating size of DIB .") );
- return FALSE;
- }
-#endif // 0
-
- m_offset = m_offset + sizeof(ICONDIRENTRY) ;
-
- m_icondirentry. bWidth = image -> GetWidth () ;
- m_icondirentry. bHeight = 2 * image -> GetHeight () ;
- m_icondirentry. bColorCount = 0 ;
- m_icondirentry. bReserved = 0 ;
- m_icondirentry. wPlanes = wxUINT16_SWAP_ON_BE(1);
- m_icondirentry. wBitCount = wxUINT16_SWAP_ON_BE(wxBMP_8BPP) ;
- m_icondirentry. dwBytesInRes = wxUINT32_SWAP_ON_BE(m_Size);
- m_icondirentry. dwImageOffset = wxUINT32_SWAP_ON_BE(m_offset);
-
- //increase size to allow for the data wriitten
- m_offset = m_offset + m_Size ;
-
- //write to stream
- stream.Write(&m_icondirentry. bWidth, sizeof(m_icondirentry. bWidth) );
- stream.Write(&m_icondirentry. bHeight, sizeof(m_icondirentry. bHeight) );
- stream.Write(&m_icondirentry. bColorCount, sizeof(m_icondirentry. bColorCount) );
- stream.Write(&m_icondirentry. bReserved, sizeof(m_icondirentry. bReserved) );
- stream.Write(&m_icondirentry. wPlanes, sizeof(m_icondirentry. wPlanes) );
- stream.Write(&m_icondirentry. wBitCount, sizeof(m_icondirentry. wBitCount) );
- stream.Write(&m_icondirentry. dwBytesInRes, sizeof(m_icondirentry. dwBytesInRes) );
- stream.Write(&m_icondirentry. dwImageOffset, sizeof(m_icondirentry. dwImageOffset) );
- if ( !stream.IsOk () )
- {
- if (verbose)
- wxLogError( _("ICO: Error writing ICONDIRENTRY header.") );
- return FALSE;
- }
- //actually save it
- IsMask = FALSE ;
- bResult = SaveDib ( image, stream, verbose, IsBmp, IsMask ) ;
- if (!bResult)
- {
- if (verbose)
- wxLogError( _("ICO: Error writing XOR DIB .") );
- return FALSE;
- }
- IsMask = TRUE ;
- bResult = SaveDib ( &mask, stream, verbose, IsBmp, IsMask ) ;
- if (!bResult)
- {
- if (verbose)
- wxLogError( _("ICO: Error writing Mask DIB .") );
- return FALSE;
- }
-
- } // end of for loop
- return TRUE ;
-}
-
-