Applied Chris' patch for support for ICO loading.
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@12473 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -41,22 +41,58 @@ enum
|
|||||||
class WXDLLEXPORT wxBMPHandler : public wxImageHandler
|
class WXDLLEXPORT wxBMPHandler : public wxImageHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
wxBMPHandler()
|
wxBMPHandler()
|
||||||
{
|
{
|
||||||
m_name = _T("BMP file");
|
m_name = _T("BMP file");
|
||||||
m_extension = _T("bmp");
|
m_extension = _T("bmp");
|
||||||
m_type = wxBITMAP_TYPE_BMP;
|
m_type = wxBITMAP_TYPE_BMP;
|
||||||
m_mime = _T("image/bmp");
|
m_mime = _T("image/bmp");
|
||||||
};
|
};
|
||||||
|
|
||||||
#if wxUSE_STREAMS
|
#if wxUSE_STREAMS
|
||||||
virtual bool SaveFile( wxImage *image, wxOutputStream& stream, bool verbose=TRUE );
|
|
||||||
|
|
||||||
|
virtual bool SaveFile( wxImage *image, wxOutputStream& stream, bool verbose=TRUE );
|
||||||
virtual bool LoadFile( wxImage *image, wxInputStream& stream, bool verbose=TRUE, int index=0 );
|
virtual bool LoadFile( wxImage *image, wxInputStream& stream, bool verbose=TRUE, int index=0 );
|
||||||
virtual bool DoCanRead( wxInputStream& stream );
|
virtual bool DoCanRead( wxInputStream& stream );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool DoLoadDib (wxImage * image, int width, int height, int bpp, int ncolors, int comp,
|
||||||
|
off_t bmpOffset, wxInputStream& stream,
|
||||||
|
bool verbose, bool IsBmp, bool hasPalette ) ;
|
||||||
|
bool LoadDib( wxImage *image, wxInputStream& stream, bool verbose, bool IsBmp ) ;
|
||||||
|
|
||||||
#endif // wxUSE_STREAMS
|
#endif // wxUSE_STREAMS
|
||||||
|
|
||||||
DECLARE_DYNAMIC_CLASS(wxBMPHandler)
|
private:
|
||||||
|
DECLARE_DYNAMIC_CLASS(wxBMPHandler)
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// wxICOHandler
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class WXDLLEXPORT wxICOHandler : public wxBMPHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
wxICOHandler()
|
||||||
|
{
|
||||||
|
m_name = _T("ICO file");
|
||||||
|
m_extension = _T("ico");
|
||||||
|
m_type = wxBITMAP_TYPE_ICO;
|
||||||
|
m_mime = _T("image/icon");
|
||||||
|
};
|
||||||
|
|
||||||
|
#if wxUSE_STREAMS
|
||||||
|
|
||||||
|
virtual bool SaveFile( wxImage *image, wxOutputStream& stream, bool verbose=TRUE );
|
||||||
|
virtual bool LoadFile( wxImage *image, wxInputStream& stream, bool verbose=TRUE, int index=0 );
|
||||||
|
virtual bool DoCanRead( wxInputStream& stream );
|
||||||
|
|
||||||
|
#endif // wxUSE_STREAMS
|
||||||
|
|
||||||
|
private:
|
||||||
|
DECLARE_DYNAMIC_CLASS(wxBMPHandler)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@@ -151,6 +151,10 @@ public:
|
|||||||
unsigned char GetGreen( int x, int y ) const;
|
unsigned char GetGreen( int x, int y ) const;
|
||||||
unsigned char GetBlue( int x, int y ) const;
|
unsigned char GetBlue( int x, int y ) const;
|
||||||
|
|
||||||
|
// used to manipulate the icons while extracting from .ico files
|
||||||
|
bool GetUnusedColour( unsigned char *r, unsigned char *g, unsigned char *b );
|
||||||
|
bool ApplyMask( const wxImage & mask );
|
||||||
|
|
||||||
static bool CanRead( const wxString& name );
|
static bool CanRead( const wxString& name );
|
||||||
virtual bool LoadFile( const wxString& name, long type = wxBITMAP_TYPE_ANY );
|
virtual bool LoadFile( const wxString& name, long type = wxBITMAP_TYPE_ANY );
|
||||||
virtual bool LoadFile( const wxString& name, const wxString& mimetype );
|
virtual bool LoadFile( const wxString& name, const wxString& mimetype );
|
||||||
|
@@ -55,6 +55,7 @@ void wxInitAllImageHandlers()
|
|||||||
#if wxUSE_XPM
|
#if wxUSE_XPM
|
||||||
wxImage::AddHandler( new wxXPMHandler );
|
wxImage::AddHandler( new wxXPMHandler );
|
||||||
#endif
|
#endif
|
||||||
|
wxImage::AddHandler( new wxICOHandler );
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // wxUSE_IMAGE
|
#endif // wxUSE_IMAGE
|
||||||
|
@@ -409,111 +409,74 @@ bool wxBMPHandler::SaveFile(wxImage *image,
|
|||||||
|
|
||||||
#define poffset (line * width * 3 + column * 3)
|
#define poffset (line * width * 3 + column * 3)
|
||||||
|
|
||||||
bool wxBMPHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbose, int WXUNUSED(index) )
|
|
||||||
|
|
||||||
|
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 wxBMPHandler::DoLoadDib (wxImage * image, int width, int height, int bpp, int ncolors, int comp,
|
||||||
|
off_t bmpOffset, wxInputStream& stream,
|
||||||
|
bool verbose, bool IsBmp, bool hasPalette )
|
||||||
|
{
|
||||||
|
|
||||||
|
wxInt32 aDword, rmask = 0, gmask = 0, bmask = 0;
|
||||||
int rshift = 0, gshift = 0, bshift = 0;
|
int rshift = 0, gshift = 0, bshift = 0;
|
||||||
|
wxInt32 dbuf[4];
|
||||||
|
wxInt8 bbuf[4];
|
||||||
wxUint8 aByte;
|
wxUint8 aByte;
|
||||||
wxUint16 aWord;
|
wxUint16 aWord;
|
||||||
wxInt32 dbuf[4];
|
|
||||||
wxInt32 aDword, rmask = 0, gmask = 0, bmask = 0;
|
|
||||||
wxInt8 bbuf[4];
|
// allocate space for palette if needed
|
||||||
struct _cmap {
|
struct _cmap
|
||||||
|
{
|
||||||
unsigned char r, g, b;
|
unsigned char r, g, b;
|
||||||
} *cmap = NULL;
|
|
||||||
|
|
||||||
off_t start_offset = stream.TellI();
|
|
||||||
if (start_offset == wxInvalidOffset) start_offset = 0;
|
|
||||||
|
|
||||||
image->Destroy();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Read the BMP header
|
|
||||||
*/
|
|
||||||
|
|
||||||
stream.Read( bbuf, 2 );
|
|
||||||
stream.Read( dbuf, 4 * 4 );
|
|
||||||
|
|
||||||
#if 0 // unused
|
|
||||||
wxInt32 size = wxINT32_SWAP_ON_BE( dbuf[0] );
|
|
||||||
#endif
|
|
||||||
wxInt32 offset = wxINT32_SWAP_ON_BE( dbuf[2] );
|
|
||||||
|
|
||||||
stream.Read(dbuf, 4 * 2);
|
|
||||||
int width = (int)wxINT32_SWAP_ON_BE( dbuf[0] );
|
|
||||||
int height = (int)wxINT32_SWAP_ON_BE( dbuf[1] );
|
|
||||||
if (width > 32767)
|
|
||||||
{
|
|
||||||
if (verbose)
|
|
||||||
wxLogError( _("BMP: Image width > 32767 pixels for file.") );
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
if (height > 32767)
|
|
||||||
{
|
|
||||||
if (verbose)
|
|
||||||
wxLogError( _("BMP: Image height > 32767 pixels for file.") );
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
*cmap = NULL;
|
||||||
|
|
||||||
stream.Read( &aWord, 2 );
|
|
||||||
/*
|
|
||||||
TODO
|
|
||||||
int planes = (int)wxUINT16_SWAP_ON_BE( aWord );
|
|
||||||
*/
|
|
||||||
stream.Read( &aWord, 2 );
|
|
||||||
int bpp = (int)wxUINT16_SWAP_ON_BE( aWord );
|
|
||||||
if (bpp != 1 && bpp != 4 && bpp != 8 && bpp != 16 && bpp != 24 && bpp != 32)
|
|
||||||
{
|
|
||||||
if (verbose)
|
|
||||||
wxLogError( _("BMP: Unknown bitdepth in file.") );
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
stream.Read( dbuf, 4 * 4 );
|
|
||||||
int comp = (int)wxINT32_SWAP_ON_BE( dbuf[0] );
|
|
||||||
if (comp != BI_RGB && comp != BI_RLE4 && comp != BI_RLE8 && comp != BI_BITFIELDS)
|
|
||||||
{
|
|
||||||
if (verbose)
|
|
||||||
wxLogError( _("BMP: Unknown encoding in file.") );
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
stream.Read( dbuf, 4 * 2 );
|
|
||||||
int ncolors = (int)wxINT32_SWAP_ON_BE( 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( _("BMP: Encoding doesn't match bitdepth.") );
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
if (bpp < 16)
|
if (bpp < 16)
|
||||||
{
|
{
|
||||||
cmap = (struct _cmap *)malloc(sizeof(struct _cmap) * ncolors);
|
cmap = (struct _cmap *)malloc(sizeof(struct _cmap) * ncolors);
|
||||||
if (!cmap)
|
if (!cmap)
|
||||||
{
|
{
|
||||||
if (verbose)
|
if (verbose)
|
||||||
wxLogError( _("BMP: Couldn't allocate memory.") );
|
wxLogError( _("Loading DIB : Couldn't allocate memory.") );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
cmap = NULL;
|
cmap = NULL;
|
||||||
|
|
||||||
|
// destroy existing here instead of
|
||||||
|
image->Destroy();
|
||||||
image->Create( width, height );
|
image->Create( width, height );
|
||||||
unsigned char *ptr = image->GetData();
|
unsigned char *ptr = image->GetData();
|
||||||
if (!ptr)
|
if (!ptr)
|
||||||
{
|
{
|
||||||
if (verbose)
|
if (verbose)
|
||||||
wxLogError( _("BMP: Couldn't allocate memory.") );
|
wxLogError( _("Loading DIB : Couldn't allocate memory.") );
|
||||||
if (cmap)
|
if (cmap)
|
||||||
free(cmap);
|
free(cmap);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reading the palette, if it exists.
|
* Reading the palette, if it exists.
|
||||||
*/
|
*/
|
||||||
@@ -524,6 +487,8 @@ bool wxBMPHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbose
|
|||||||
unsigned char* b = new unsigned char[ncolors];
|
unsigned char* b = new unsigned char[ncolors];
|
||||||
for (int j = 0; j < ncolors; j++)
|
for (int j = 0; j < ncolors; j++)
|
||||||
{
|
{
|
||||||
|
if (hasPalette)
|
||||||
|
{
|
||||||
stream.Read( bbuf, 4 );
|
stream.Read( bbuf, 4 );
|
||||||
cmap[j].b = bbuf[0];
|
cmap[j].b = bbuf[0];
|
||||||
cmap[j].g = bbuf[1];
|
cmap[j].g = bbuf[1];
|
||||||
@@ -533,6 +498,14 @@ bool wxBMPHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbose
|
|||||||
g[j] = cmap[j].g;
|
g[j] = cmap[j].g;
|
||||||
b[j] = cmap[j].b;
|
b[j] = cmap[j].b;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//used in reading .ico file mask
|
||||||
|
r[j] = cmap[j].r = j * 255;
|
||||||
|
g[j] = cmap[j].g = j * 255;
|
||||||
|
b[j] = cmap[j].b = j * 255;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if wxUSE_PALETTE
|
#if wxUSE_PALETTE
|
||||||
// Set the palette for the wxImage
|
// Set the palette for the wxImage
|
||||||
@@ -586,7 +559,8 @@ bool wxBMPHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbose
|
|||||||
/*
|
/*
|
||||||
* Reading the image data
|
* Reading the image data
|
||||||
*/
|
*/
|
||||||
stream.SeekI( start_offset + offset );
|
if ( IsBmp ) stream.SeekI( bmpOffset ); // else icon, just carry on
|
||||||
|
|
||||||
unsigned char *data = ptr;
|
unsigned char *data = ptr;
|
||||||
|
|
||||||
/* set the whole image to the background color */
|
/* set the whole image to the background color */
|
||||||
@@ -633,7 +607,7 @@ bool wxBMPHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbose
|
|||||||
if (comp == BI_RLE4)
|
if (comp == BI_RLE4)
|
||||||
{
|
{
|
||||||
if (verbose)
|
if (verbose)
|
||||||
wxLogError( _("BMP: Cannot deal with 4bit encoded yet.") );
|
wxLogError( _("DIB Header: Cannot deal with 4bit encoded yet.") );
|
||||||
image->Destroy();
|
image->Destroy();
|
||||||
free(cmap);
|
free(cmap);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -768,9 +742,188 @@ bool wxBMPHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbose
|
|||||||
|
|
||||||
image->SetMask( FALSE );
|
image->SetMask( FALSE );
|
||||||
|
|
||||||
|
return stream.IsOk();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool wxBMPHandler::LoadDib( wxImage *image, wxInputStream& stream, bool verbose, bool IsBmp )
|
||||||
|
{
|
||||||
|
|
||||||
|
wxUint8 aByte;
|
||||||
|
wxUint16 aWord;
|
||||||
|
wxInt32 dbuf[4];
|
||||||
|
wxInt8 bbuf[4];
|
||||||
|
off_t offset;
|
||||||
|
|
||||||
|
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 = (int)wxINT32_SWAP_ON_BE( dbuf[0] );
|
||||||
|
int height = (int)wxINT32_SWAP_ON_BE( 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 = (int)wxUINT16_SWAP_ON_BE( 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 = (int)wxINT32_SWAP_ON_BE( 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 = (int)wxINT32_SWAP_ON_BE( 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 -> ApplyMask ( &mask );
|
||||||
|
|
||||||
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool wxBMPHandler::LoadFile ( wxImage *image, wxInputStream& stream, bool verbose, int WXUNUSED(index) )
|
||||||
|
{
|
||||||
|
bool IsBmp = TRUE;
|
||||||
|
//Read a single DIB fom the file
|
||||||
|
return LoadDib ( image, stream, verbose, IsBmp ) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool wxICOHandler::LoadFile ( wxImage *image, wxInputStream& stream, bool verbose, int WXUNUSED(index) )
|
||||||
|
{
|
||||||
|
bool bResult = FALSE ;
|
||||||
|
bool IsBmp = FALSE;
|
||||||
|
|
||||||
|
ICONDIR m_IconDir ;
|
||||||
|
stream.Read (&m_IconDir, sizeof(m_IconDir));
|
||||||
|
wxUint16 nIcons = wxUINT16_SWAP_ON_BE ( m_IconDir.idCount ) ;
|
||||||
|
|
||||||
|
//loop round the icons and choose the best one
|
||||||
|
ICONDIRENTRY * pIconDirEntry = new ICONDIRENTRY [nIcons];
|
||||||
|
ICONDIRENTRY * pCurrentEntry = pIconDirEntry ;
|
||||||
|
int i ;
|
||||||
|
int wMax = 0 ;
|
||||||
|
int colmax = 0 ;
|
||||||
|
int iSel = wxNOT_FOUND ;
|
||||||
|
for (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 (iSel == wxNOT_FOUND)
|
||||||
|
{
|
||||||
|
bResult = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//seek to selected icon
|
||||||
|
pCurrentEntry = pIconDirEntry + iSel ;
|
||||||
|
stream.SeekI (wxUINT32_SWAP_ON_BE ( pCurrentEntry -> dwImageOffset ), wxFromStart ) ;
|
||||||
|
bResult = LoadDib ( image, stream, TRUE, IsBmp );
|
||||||
|
}
|
||||||
|
delete [] pIconDirEntry ;
|
||||||
|
return bResult
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxICOHandler::SaveFile(wxImage *image,
|
||||||
|
wxOutputStream& stream,
|
||||||
|
bool verbose)
|
||||||
|
{
|
||||||
|
return FALSE ;
|
||||||
|
}
|
||||||
|
|
||||||
bool wxBMPHandler::DoCanRead( wxInputStream& stream )
|
bool wxBMPHandler::DoCanRead( wxInputStream& stream )
|
||||||
{
|
{
|
||||||
unsigned char hdr[2];
|
unsigned char hdr[2];
|
||||||
@@ -780,6 +933,15 @@ bool wxBMPHandler::DoCanRead( wxInputStream& stream )
|
|||||||
return (hdr[0] == 'B' && hdr[1] == 'M');
|
return (hdr[0] == 'B' && hdr[1] == 'M');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool wxICOHandler::DoCanRead( wxInputStream& stream )
|
||||||
|
{
|
||||||
|
unsigned char hdr[4];
|
||||||
|
|
||||||
|
stream.Read(hdr, 4);
|
||||||
|
stream.SeekI(-4, wxFromCurrent);
|
||||||
|
return (hdr[0] == '\0' && hdr[1] == '\0' && hdr[2] == '\1' && hdr[3] == '\0');
|
||||||
|
}
|
||||||
|
|
||||||
#endif // wxUSE_STREAMS
|
#endif // wxUSE_STREAMS
|
||||||
|
|
||||||
#endif // wxUSE_IMAGE
|
#endif // wxUSE_IMAGE
|
||||||
|
@@ -720,6 +720,100 @@ int wxImage::GetHeight() const
|
|||||||
return M_IMGDATA->m_height;
|
return M_IMGDATA->m_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool wxImage::GetUnusedColour ( unsigned char * r, unsigned char * g, unsigned char * b )
|
||||||
|
{
|
||||||
|
wxHashTable hTable;
|
||||||
|
unsigned long key;
|
||||||
|
|
||||||
|
ComputeHistogram( hTable );
|
||||||
|
|
||||||
|
// start with blackest color and work to lightest
|
||||||
|
// 0,0,0 is quite likely to be a used color
|
||||||
|
unsigned char r2 = 1;
|
||||||
|
unsigned char g2 = 0;
|
||||||
|
unsigned char b2 = 0;
|
||||||
|
|
||||||
|
key = (r2 << 16) | (g2 << 8) | b2;
|
||||||
|
|
||||||
|
while ( (wxHNode *) hTable.Get(key) )
|
||||||
|
{
|
||||||
|
// color already used
|
||||||
|
r2 ++ ;
|
||||||
|
if ( r2 >= 255 )
|
||||||
|
{
|
||||||
|
r2 = 0;
|
||||||
|
g2 ++ ;
|
||||||
|
if ( g2 >= 255 )
|
||||||
|
{
|
||||||
|
g2 = 0 ;
|
||||||
|
b2 ++ ;
|
||||||
|
if ( b2 >= 255 )
|
||||||
|
{
|
||||||
|
wxLogError( _("GetUnusedColour:: No Unused Color in image ") );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
key = (r2 << 16) | (g2 << 8) | b2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool wxImage::ApplyMask ( const wxImage & mask )
|
||||||
|
{
|
||||||
|
// what to do if we already have a mask ??
|
||||||
|
if (M_IMGDATA->m_hasMask || mask.HasMask() )
|
||||||
|
{
|
||||||
|
wxLogError( _("Image already masked") );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check that the images are the same size
|
||||||
|
if ( (M_IMGDATA->m_height != mask.GetHeight() ) || (M_IMGDATA->m_width != mask.GetWidth () ) )
|
||||||
|
{
|
||||||
|
wxLogError( _("Image and Mask have different sizes") );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// find unused colour
|
||||||
|
unsigned char r,g,b ;
|
||||||
|
if (!GetUnusedColour (&r, &g, &b))
|
||||||
|
{
|
||||||
|
wxLogError( _("No Unused Color in image being masked") );
|
||||||
|
return FALSE ;
|
||||||
|
}
|
||||||
|
|
||||||
|
char unsigned *imgdata = GetData();
|
||||||
|
char unsigned *maskdata = mask.GetData();
|
||||||
|
|
||||||
|
const int w = GetWidth();
|
||||||
|
const int h = GetHeight();
|
||||||
|
|
||||||
|
for (int j = 0; j < h; j++)
|
||||||
|
for (int i = 0; i < w; i++)
|
||||||
|
{
|
||||||
|
if ((maskdata[0] > 128) && (maskdata[1] > 128) && (maskdata[2] > 128 ))
|
||||||
|
{
|
||||||
|
imgdata[0] = r;
|
||||||
|
imgdata[1] = g;
|
||||||
|
imgdata[2] = b;
|
||||||
|
}
|
||||||
|
imgdata += 3;
|
||||||
|
maskdata += 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
M_IMGDATA->m_maskRed = r;
|
||||||
|
M_IMGDATA->m_maskGreen = g;
|
||||||
|
M_IMGDATA->m_maskBlue = b;
|
||||||
|
M_IMGDATA->m_hasMask = TRUE;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
#if wxUSE_PALETTE
|
#if wxUSE_PALETTE
|
||||||
|
|
||||||
// Palette functions
|
// Palette functions
|
||||||
|
Reference in New Issue
Block a user