X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/73ef393701bd6c2c689a05d5637cc701e2f5cc2f..172541f64be8fcddb08f1c121da256d08c24a70b:/src/common/xpmdecod.cpp diff --git a/src/common/xpmdecod.cpp b/src/common/xpmdecod.cpp index 73ce1f5d4b..e30022e8c7 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 @@ -115,9 +115,7 @@ license is as follows: #include "wx/intl.h" #include -#ifdef __VISUALC__ #include -#endif #include "wx/xpmdecod.h" @@ -126,10 +124,12 @@ 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(-(wxFileOffset)WXSIZEOF(buf), wxFromCurrent); - return (memcmp(buf, "/* XPM */", 9) == 0); + return memcmp(buf, "/* XPM */", WXSIZEOF(buf)) == 0; } wxImage wxXPMDecoder::ReadFile(wxInputStream& stream) @@ -143,7 +143,7 @@ wxImage wxXPMDecoder::ReadFile(wxInputStream& stream) wxCharBuffer buffer(length); char *xpm_buffer = (char *)buffer.data(); - if ( stream.Read(xpm_buffer, length).LastError() == wxSTREAM_READ_ERROR ) + if ( stream.Read(xpm_buffer, length).GetLastError() == wxSTREAM_READ_ERROR ) return wxNullImage; xpm_buffer[length] = '\0'; @@ -178,7 +178,10 @@ wxImage wxXPMDecoder::ReadFile(wxInputStream& stream) if ( (*q == '*') && (*(q + 1) == '/') ) break; } - strcpy(p, q + 2); + + // memmove allows overlaps (unlike strcpy): + size_t cpylen = strlen(q + 2) + 1; + memmove(p, q + 2, cpylen); } /* @@ -236,11 +239,7 @@ wxImage wxXPMDecoder::ReadFile(wxInputStream& stream) */ wxImage img = ReadData(xpm_lines); -#ifdef __WIN16__ - delete[] (char**) xpm_lines; -#else delete[] xpm_lines; -#endif return img; } @@ -488,6 +487,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)}, @@ -508,25 +508,25 @@ 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) { unsigned char i1, i2; if (digit1 >= 'a') - i1 = digit1 - 'a' + 0x0A; + i1 = (unsigned char)(digit1 - 'a' + 0x0A); else if (digit1 >= 'A') - i1 = digit1 - 'A' + 0x0A; + i1 = (unsigned char)(digit1 - 'A' + 0x0A); else - i1 = digit1 - '0'; + i1 = (unsigned char)(digit1 - '0'); if (digit2 >= 'a') - i2 = digit2 - 'a' + 0x0A; + i2 = (unsigned char)(digit2 - 'a' + 0x0A); else if (digit2 >= 'A') - i2 = digit2 - 'A' + 0x0A; + i2 = (unsigned char)(digit2 - 'A' + 0x0A); else - i2 = digit2 - '0'; - return (0x10 * i1 + i2); + i2 = (unsigned char)(digit2 - '0'); + return (unsigned char)(0x10 * i1 + i2); } static bool GetRGBFromName(const char *inname, bool *isNone, @@ -546,11 +546,11 @@ static bool GetRGBFromName(const char *inname, bool *isNone, *r = ParseHexadecimal(inname[1], inname[2]); *g = ParseHexadecimal(inname[1*ofs+1], inname[1*ofs+2]); *b = ParseHexadecimal(inname[2*ofs+1], inname[2*ofs+2]); - *isNone = FALSE; - return TRUE; + *isNone = false; + return true; } - name = strdup(inname); + name = wxStrdupA(inname); // theRGBRecords[] has no names with spaces, and no grey, but a // lot of gray... @@ -568,7 +568,7 @@ static bool GetRGBFromName(const char *inname, bool *isNone, p = name; while (*p) { - *p = tolower(*p); + *p = (char)tolower(*p); p++; } @@ -581,12 +581,12 @@ static bool GetRGBFromName(const char *inname, bool *isNone, bool found; if ( strcmp(name, "none") == 0 ) { - *isNone = TRUE; - found = TRUE; + *isNone = true; + found = true; } else // not "None" { - found = FALSE; + found = false; // binary search: left = 0; @@ -601,8 +601,8 @@ static bool GetRGBFromName(const char *inname, bool *isNone, *r = (unsigned char)((rgbVal >> 16) & 0xFF); *g = (unsigned char)((rgbVal >> 8) & 0xFF); *b = (unsigned char)((rgbVal) & 0xFF); - *isNone = FALSE; - found = TRUE; + *isNone = false; + found = true; break; } else if ( cmp < 0 ) @@ -657,7 +657,7 @@ struct wxXPMColourMapData { unsigned char R,G,B; }; -WX_DECLARE_STRING_HASH_MAP(wxXPMColourMapData, wxXPMColourMap) +WX_DECLARE_STRING_HASH_MAP(wxXPMColourMapData, wxXPMColourMap); wxImage wxXPMDecoder::ReadData(const char **xpm_data) { @@ -668,13 +668,14 @@ wxImage wxXPMDecoder::ReadData(const char **xpm_data) wxChar key[64]; const char *clr_def; bool hasMask; - wxXPMColourMapData clr_data; wxXPMColourMap clr_tbl; + wxXPMColourMap::iterator it; + wxString maskKey; /* * Read hints and initialize structures: */ - + count = sscanf(xpm_data[0], "%u %u %u %u", &width, &height, &colors_cnt, &chars_per_pixel); if ( count != 4 || width * height * colors_cnt == 0 ) @@ -691,53 +692,67 @@ wxImage wxXPMDecoder::ReadData(const char **xpm_data) img.Create(width, height); if ( !img.Ok() ) return img; - img.SetMask(FALSE); + img.SetMask(false); key[chars_per_pixel] = wxT('\0'); - hasMask = FALSE; + hasMask = false; /* * Create colour map: */ for (i = 0; i < colors_cnt; i++) { + wxXPMColourMapData clr_data = {255,0,255}; + 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] + 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; + wxLogError(_("XPM: malformed colour definition '%s'!"), + xpm_data[1+i]); } else { - bool isNone; + bool isNone = false; if ( !GetRGBFromName(clr_def, &isNone, &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; + wxLogError(_("XPM: malformed colour definition '%s'!"), + xpm_data[1+i]); } else { if ( isNone ) { - img.SetMask(TRUE); + img.SetMask(true); img.SetMaskColour(255, 0, 255); - hasMask = TRUE; - 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; + hasMask = true; + maskKey = key; } } } clr_tbl[key] = clr_data; } + /* + * Modify colour entries with RGB = (255,0,255) to (255,0,254) if + * mask colour is present (so that existing pixels with (255,0,255) + * magenta colour are not incorrectly made transparent): + */ + if (hasMask) + { + for (it = clr_tbl.begin(); it != clr_tbl.end(); ++it) + { + if (it->second.R == 255 && it->second.G == 0 && + it->second.B == 255 && + it->first != maskKey) + { + it->second.B = 254; + } + } + } + /* * Parse image data: */ @@ -745,7 +760,7 @@ 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) @@ -757,6 +772,12 @@ wxImage wxXPMDecoder::ReadData(const char **xpm_data) 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 {