X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/f001799009630c46bc87aff5a84dbd2523005505..f1e269209afbcbec4e46ab5df4ba43d902a6bf2f:/src/common/xpmdecod.cpp diff --git a/src/common/xpmdecod.cpp b/src/common/xpmdecod.cpp index 1112b5123f..c6e10441c9 100644 --- a/src/common/xpmdecod.cpp +++ b/src/common/xpmdecod.cpp @@ -90,7 +90,7 @@ license is as follows: * in this Software without prior written authorization from GROUPE BULL. */ -#ifdef __GNUG__ +#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) #pragma implementation "xpmdecod.h" #endif @@ -111,9 +111,12 @@ license is as follows: #include "wx/image.h" #include "wx/utils.h" #include "wx/log.h" +#include "wx/hashmap.h" #include "wx/intl.h" #include +#include + #include "wx/xpmdecod.h" #if wxUSE_STREAMS @@ -121,28 +124,33 @@ bool wxXPMDecoder::CanRead(wxInputStream& stream) { unsigned char buf[9]; - stream.Read(buf, 9); - stream.SeekI(-9, wxFromCurrent); + if ( !stream.Read(buf, WXSIZEOF(buf)) ) + return FALSE; + + stream.SeekI(-(off_t)WXSIZEOF(buf), wxFromCurrent); - return (memcmp(buf, "/* XPM */", 9) == 0); + return memcmp(buf, "/* XPM */", WXSIZEOF(buf)) == 0; } wxImage wxXPMDecoder::ReadFile(wxInputStream& stream) { size_t length = stream.GetSize(); - wxCHECK_MSG(length != 0, wxNullImage, wxT("Cannot read XPM from stream of unknown size")); + wxCHECK_MSG( length != 0, wxNullImage, + wxT("Cannot read XPM from stream of unknown size") ); - char *xpm_buffer = new char[length+1]; - char *p, *q; - size_t i; + // use a smart buffer to be sure to free memory even when we return on + // error + wxCharBuffer buffer(length); - if ( stream.Read(xpm_buffer, length).LastError() == wxSTREAM_READ_ERROR ) + char *xpm_buffer = (char *)buffer.data(); + if ( stream.Read(xpm_buffer, length).GetLastError() == wxSTREAM_READ_ERROR ) return wxNullImage; xpm_buffer[length] = '\0'; /* * Remove comments from the file: */ + char *p, *q; for (p = xpm_buffer; *p != '\0'; p++) { if ( (*p == '"') || (*p == '\'') ) @@ -176,7 +184,7 @@ wxImage wxXPMDecoder::ReadFile(wxInputStream& stream) /* * Remove unquoted characters: */ - i = 0; + size_t i = 0; for (p = xpm_buffer; *p != '\0'; p++) { if ( *p != '"' ) @@ -228,12 +236,12 @@ wxImage wxXPMDecoder::ReadFile(wxInputStream& stream) */ wxImage img = ReadData(xpm_lines); - delete[] xpm_buffer; #ifdef __WIN16__ delete[] (char**) xpm_lines; #else delete[] xpm_lines; #endif + return img; } #endif // wxUSE_STREAMS @@ -256,7 +264,7 @@ wxImage wxXPMDecoder::ReadFile(wxInputStream& stream) typedef struct { - char *name; + const char *name; wxUint32 rgb; } rgbRecord; @@ -480,6 +488,7 @@ static rgbRecord theRGBRecords[] = {"seagreen", myRGB(82, 149, 132)}, {"seashell", myRGB(255, 245, 238)}, {"sienna", myRGB(150, 82, 45)}, + {"silver", myRGB(192, 192, 192)}, {"skyblue", myRGB(114, 159, 255)}, {"slateblue", myRGB(126, 136, 171)}, {"slategray", myRGB(112, 128, 144)}, @@ -500,7 +509,7 @@ static rgbRecord theRGBRecords[] = {"yellowgreen", myRGB(50, 216, 56)}, {NULL, myRGB(0, 0, 0)} }; -static int numTheRGBRecords = 234; +static int numTheRGBRecords = 235; static unsigned char ParseHexadecimal(char digit1, char digit2) { @@ -645,11 +654,11 @@ static const char *ParseColor(const char *data) return NULL; } -class wxXPMColourMapData : public wxObject +struct wxXPMColourMapData { - public: - unsigned char R,G,B; + unsigned char R,G,B; }; +WX_DECLARE_STRING_HASH_MAP(wxXPMColourMapData, wxXPMColourMap); wxImage wxXPMDecoder::ReadData(const char **xpm_data) { @@ -660,8 +669,8 @@ wxImage wxXPMDecoder::ReadData(const char **xpm_data) wxChar key[64]; const char *clr_def; bool hasMask; - wxXPMColourMapData *clr_data; - wxHashTable clr_tbl(wxKEY_STRING); + wxXPMColourMapData clr_data; + wxXPMColourMap clr_tbl; /* * Read hints and initialize structures: @@ -686,7 +695,6 @@ wxImage wxXPMDecoder::ReadData(const char **xpm_data) img.SetMask(FALSE); key[chars_per_pixel] = wxT('\0'); hasMask = FALSE; - clr_tbl.DeleteContents(TRUE); /* * Create colour map: @@ -695,22 +703,21 @@ wxImage wxXPMDecoder::ReadData(const char **xpm_data) { for (i_key = 0; i_key < chars_per_pixel; i_key++) key[i_key] = (wxChar)xpm_data[1 + i][i_key]; - clr_def = ParseColor(xpm_data[1 + i]); - clr_data = new wxXPMColourMapData; + clr_def = ParseColor(xpm_data[1 + i] + chars_per_pixel); if ( clr_def == NULL ) { wxLogError(_("XPM: malformed colour definition '%s'!"), xpm_data[1+i]); - clr_data->R = 255, clr_data->G = 0, clr_data->B = 255; + clr_data.R = 255, clr_data.G = 0, clr_data.B = 255; } else { bool isNone; if ( !GetRGBFromName(clr_def, &isNone, - &clr_data->R, &clr_data->G, &clr_data->B) ) + &clr_data.R, &clr_data.G, &clr_data.B) ) { wxLogError(_("XPM: malformed colour definition '%s'!"), xpm_data[1+i]); - clr_data->R = 255, clr_data->G = 0, clr_data->B = 255; + clr_data.R = 255, clr_data.G = 0, clr_data.B = 255; } else { @@ -719,17 +726,17 @@ wxImage wxXPMDecoder::ReadData(const char **xpm_data) img.SetMask(TRUE); img.SetMaskColour(255, 0, 255); hasMask = TRUE; - clr_data->R = 255, clr_data->G = 0, clr_data->B = 255; + clr_data.R = 255, clr_data.G = 0, clr_data.B = 255; } else { - if ( hasMask && clr_data->R == 255 && - clr_data->G == 0 && clr_data->B == 255 ) - clr_data->B = 254; + if ( hasMask && clr_data.R == 255 && + clr_data.G == 0 && clr_data.B == 255 ) + clr_data.B = 254; } } } - clr_tbl.Put(key, clr_data); + clr_tbl[key] = clr_data; } /* @@ -737,6 +744,9 @@ wxImage wxXPMDecoder::ReadData(const char **xpm_data) */ unsigned char *img_data = img.GetData(); + wxXPMColourMap::iterator entry; + wxXPMColourMap::iterator end = clr_tbl.end(); + for (j = 0; j < height; j++) { for (i = 0; i < width; i++, img_data += 3) @@ -744,16 +754,22 @@ wxImage wxXPMDecoder::ReadData(const char **xpm_data) for (i_key = 0; i_key < chars_per_pixel; i_key++) key[i_key] = (wxChar)xpm_data[1 + colors_cnt + j] [chars_per_pixel * i + i_key]; - clr_data = (wxXPMColourMapData*) clr_tbl.Get(key); - if ( clr_data == NULL ) + entry = clr_tbl.find(key); + if ( entry == end ) { wxLogError(_("XPM: Malformed pixel data!")); + + // better return right now as otherwise we risk to flood the + // user with error messages as something seems to be seriously + // wrong with the file and so we could give this message for + // each remaining pixel if we don't bail out + return wxNullImage; } else { - img_data[0] = clr_data->R; - img_data[1] = clr_data->G; - img_data[2] = clr_data->B; + img_data[0] = entry->second.R; + img_data[1] = entry->second.G; + img_data[2] = entry->second.B; } } }