X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/655719367ac5e131d9642e5783f3ecf64d1a3385..e0876d7381ada8459e18fc81a9e47c025778b8ec:/src/common/xpmdecod.cpp diff --git a/src/common/xpmdecod.cpp b/src/common/xpmdecod.cpp index f8524971a0..fa9bcb9fc7 100644 --- a/src/common/xpmdecod.cpp +++ b/src/common/xpmdecod.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: xpmdecod.cpp +// Name: src/common/xpmdecod.cpp // Purpose: wxXPMDecoder // Author: John Cristy, Vaclav Slavik // RCS-ID: $Id$ @@ -90,29 +90,26 @@ license is as follows: * in this Software without prior written authorization from GROUPE BULL. */ -#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) -#pragma implementation "xpmdecod.h" -#endif - // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" #ifdef __BORLANDC__ -# pragma hdrstop + #pragma hdrstop #endif +#if wxUSE_IMAGE && wxUSE_XPM + #ifndef WX_PRECOMP -# include "wx/defs.h" + #include "wx/intl.h" + #include "wx/log.h" + #include "wx/utils.h" + #include "wx/hashmap.h" + #if wxUSE_STREAMS + #include "wx/stream.h" + #endif + #include "wx/image.h" #endif -#if wxUSE_IMAGE && wxUSE_XPM - -#include "wx/stream.h" -#include "wx/image.h" -#include "wx/utils.h" -#include "wx/log.h" -#include "wx/hashmap.h" -#include "wx/intl.h" #include #include @@ -127,7 +124,7 @@ bool wxXPMDecoder::CanRead(wxInputStream& stream) if ( !stream.Read(buf, WXSIZEOF(buf)) ) return false; - stream.SeekI(-(off_t)WXSIZEOF(buf), wxFromCurrent); + stream.SeekI(-(wxFileOffset)WXSIZEOF(buf), wxFromCurrent); return memcmp(buf, "/* XPM */", WXSIZEOF(buf)) == 0; } @@ -178,10 +175,10 @@ wxImage wxXPMDecoder::ReadFile(wxInputStream& stream) if ( (*q == '*') && (*(q + 1) == '/') ) break; } - + // memmove allows overlaps (unlike strcpy): size_t cpylen = strlen(q + 2) + 1; - memmove(p, q + 2, cpylen); + memmove(p, q + 2, cpylen); } /* @@ -221,7 +218,7 @@ wxImage wxXPMDecoder::ReadFile(wxInputStream& stream) return wxNullImage; } - xpm_lines = new const char*[lines_cnt]; + xpm_lines = new const char*[lines_cnt + 1]; xpm_lines[0] = xpm_buffer; line = 1; for (p = xpm_buffer; (*p != '\0') && (line < lines_cnt); p++) @@ -234,6 +231,8 @@ wxImage wxXPMDecoder::ReadFile(wxInputStream& stream) } } + xpm_lines[lines_cnt] = NULL; + /* * Read the image: */ @@ -515,18 +514,18 @@ 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, @@ -550,7 +549,7 @@ static bool GetRGBFromName(const char *inname, bool *isNone, return true; } - name = strdup(inname); + name = wxStrdupA(inname); // theRGBRecords[] has no names with spaces, and no grey, but a // lot of gray... @@ -568,7 +567,7 @@ static bool GetRGBFromName(const char *inname, bool *isNone, p = name; while (*p) { - *p = tolower(*p); + *p = (char)tolower(*p); p++; } @@ -655,12 +654,15 @@ static const char *ParseColor(const char *data) struct wxXPMColourMapData { + wxXPMColourMapData() { R = G = B = 0; } unsigned char R,G,B; }; WX_DECLARE_STRING_HASH_MAP(wxXPMColourMapData, wxXPMColourMap); wxImage wxXPMDecoder::ReadData(const char **xpm_data) { + wxCHECK_MSG(xpm_data, wxNullImage, wxT("NULL XPM data") ); + wxImage img; int count; unsigned width, height, colors_cnt, chars_per_pixel; @@ -668,7 +670,6 @@ 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; @@ -676,12 +677,12 @@ wxImage wxXPMDecoder::ReadData(const char **xpm_data) /* * 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 ) { - wxLogError(_T("XPM: Not XPM data!")); + wxLogError(_("XPM: incorrect header format!")); return wxNullImage; } @@ -690,8 +691,8 @@ wxImage wxXPMDecoder::ReadData(const char **xpm_data) // 8bit RGB... wxCHECK_MSG(chars_per_pixel < 64, wxNullImage, wxT("XPM colormaps this large not supported.")); - img.Create(width, height); - if ( !img.Ok() ) return img; + if ( !img.Create(width, height) ) + return wxNullImage; img.SetMask(false); key[chars_per_pixel] = wxT('\0'); @@ -700,40 +701,50 @@ wxImage wxXPMDecoder::ReadData(const char **xpm_data) /* * Create colour map: */ + wxXPMColourMapData clr_data; for (i = 0; i < colors_cnt; i++) { + const char *xmpColLine = xpm_data[1 + i]; + + // we must have at least " x y" after the colour index, hence +5 + if ( !xmpColLine || strlen(xmpColLine) < chars_per_pixel + 5 ) + { + wxLogError(_("XPM: incorrect colour description in line %d"), + (int)(1 + i)); + return wxNullImage; + } + 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); + key[i_key] = (wxChar)xmpColLine[i_key]; + clr_def = ParseColor(xmpColLine + 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' at line %d!"), + xmpColLine, (int)(1 + i)); + return wxNullImage; } - else + + bool isNone = false; + if ( !GetRGBFromName(clr_def, &isNone, + &clr_data.R, &clr_data.G, &clr_data.B) ) { - bool isNone; - 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; - } - else - { - if ( isNone ) - { - img.SetMask(true); - img.SetMaskColour(255, 0, 255); - hasMask = true; - clr_data.R = 255, clr_data.G = 0, clr_data.B = 255; - maskKey = key; - } - } + wxLogError(_("XPM: malformed colour definition '%s' at line %d!"), + xmpColLine, (int)(1 + i)); + return wxNullImage; } + + if ( isNone ) + { + img.SetMask(true); + img.SetMaskColour(255, 0, 255); + clr_data.R = + clr_data.B = 255; + clr_data.G = 0; + hasMask = true; + maskKey = key; + } + clr_tbl[key] = clr_data; } @@ -744,7 +755,7 @@ wxImage wxXPMDecoder::ReadData(const char **xpm_data) */ if (hasMask) { - for (it = clr_tbl.begin(); it != clr_tbl.end(); it++) + for (it = clr_tbl.begin(); it != clr_tbl.end(); ++it) { if (it->second.R == 255 && it->second.G == 0 && it->second.B == 255 && @@ -762,14 +773,24 @@ 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) { + const char *xpmImgLine = xpm_data[1 + colors_cnt + j]; + if ( !xpmImgLine || strlen(xpmImgLine) < width*chars_per_pixel ) + { + wxLogError(_("XPM: truncated image data at line %d!"), + (int)(1 + colors_cnt + j)); + return wxNullImage; + } + 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]; + { + key[i_key] = (wxChar)xpmImgLine[chars_per_pixel * i + i_key]; + } + entry = clr_tbl.find(key); if ( entry == end ) {