From 952ae1e88b9092f493b4ea6911a2b60b378d422d Mon Sep 17 00:00:00 2001 From: =?utf8?q?V=C3=A1clav=20Slav=C3=ADk?= Date: Thu, 7 Feb 2002 18:11:39 +0000 Subject: [PATCH] changed wxImage::ComputeHistogram to use wxHashMap git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@14056 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/image.h | 23 +++++++++++++++--- src/common/image.cpp | 33 +++++++------------------- src/common/imagpcx.cpp | 32 +++++++++++-------------- src/common/imagxpm.cpp | 26 +++++++-------------- src/gtk/cursor.cpp | 53 ++++++++++++++++++++---------------------- src/gtk1/cursor.cpp | 53 ++++++++++++++++++++---------------------- 6 files changed, 100 insertions(+), 120 deletions(-) diff --git a/include/wx/image.h b/include/wx/image.h index 05cee7069d..eaeb0f085f 100644 --- a/include/wx/image.h +++ b/include/wx/image.h @@ -19,6 +19,7 @@ #include "wx/string.h" #include "wx/gdicmn.h" #include "wx/bitmap.h" +#include "wx/hashmap.h" #if wxUSE_STREAMS # include "wx/stream.h" @@ -76,16 +77,25 @@ private: }; //----------------------------------------------------------------------------- -// wxImage +// wxImageHistogram //----------------------------------------------------------------------------- -class WXDLLEXPORT wxHNode +class WXDLLEXPORT wxImageHistogramEntry { public: + wxImageHistogramEntry() : index(0), value(0) {} unsigned long index; unsigned long value; }; +WX_DECLARE_EXPORTED_HASH_MAP(unsigned long, wxImageHistogramEntry, + wxIntegerHash, wxIntegerEqual, + wxImageHistogram); + +//----------------------------------------------------------------------------- +// wxImage +//----------------------------------------------------------------------------- + class WXDLLEXPORT wxImage: public wxObject { public: @@ -214,7 +224,14 @@ public: bool HasOption(const wxString& name) const; unsigned long CountColours( unsigned long stopafter = (unsigned long) -1 ); - unsigned long ComputeHistogram( wxHashTable &h ); + + // Computes the histogram of the image and fills a hash table, indexed + // with integer keys built as 0xRRGGBB, containing wxImageHistogramEntry + // objects. Each of them contains an 'index' (useful to build a palette + // with the image colours) and a 'value', which is the number of pixels + // in the image with that colour. + // Returned value: # of entries in the histogram + unsigned long ComputeHistogram( wxImageHistogram &h ); wxImage& operator = (const wxImage& image) { diff --git a/src/common/image.cpp b/src/common/image.cpp index d450769808..addb165539 100644 --- a/src/common/image.cpp +++ b/src/common/image.cpp @@ -725,10 +725,10 @@ bool wxImage::FindFirstUnusedColour( unsigned char *r, unsigned char *g, unsigned char *b, unsigned char startR, unsigned char startG, unsigned char startB) { - wxHashTable hTable; + wxImageHistogram histogram; unsigned long key; - ComputeHistogram( hTable ); + ComputeHistogram(histogram); unsigned char r2 = startR; unsigned char g2 = startG; @@ -736,7 +736,7 @@ bool wxImage::FindFirstUnusedColour( key = (r2 << 16) | (g2 << 8) | b2; - while ( (wxHNode *) hTable.Get(key) ) + while ( histogram.find(key) != histogram.end() ) { // color already used r2++; @@ -1352,19 +1352,13 @@ unsigned long wxImage::CountColours( unsigned long stopafter ) } -// GRG, Dic/99 -// Computes the histogram of the image and fills a hash table, indexed -// with integer keys built as 0xRRGGBB, containing wxHNode objects. Each -// wxHNode contains an 'index' (useful to build a palette with the image -// colours) and a 'value', which is the number of pixels in the image with -// that colour. -// -unsigned long wxImage::ComputeHistogram( wxHashTable &h ) +unsigned long wxImage::ComputeHistogram( wxImageHistogram &h ) { unsigned char r, g, b; unsigned char *p; unsigned long size, nentries, key; - wxHNode *hnode; + + h.clear(); p = GetData(); size = GetWidth() * GetHeight(); @@ -1377,18 +1371,9 @@ unsigned long wxImage::ComputeHistogram( wxHashTable &h ) b = *(p++); key = (r << 16) | (g << 8) | b; - hnode = (wxHNode *) h.Get(key); - - if (hnode) - hnode->value++; - else - { - hnode = new wxHNode(); - hnode->index = nentries++; - hnode->value = 1; - - h.Put(key, (wxObject *)hnode); - } + wxImageHistogramEntry& entry = h[key]; + if ( entry.value++ == 0 ) + entry.index = nentries++; } return nentries; diff --git a/src/common/imagpcx.cpp b/src/common/imagpcx.cpp index 17a9b54bd5..2e50e2c5a5 100644 --- a/src/common/imagpcx.cpp +++ b/src/common/imagpcx.cpp @@ -311,7 +311,7 @@ int SavePCX(wxImage *image, wxOutputStream& stream) unsigned int bytesperline; // bytes per line (each plane) int nplanes = 3; // number of planes int format = wxPCX_24BIT; // image format (8 bit, 24 bit) - wxHashTable h(wxKEY_INTEGER); // image histogram + wxImageHistogram histogram; // image histogram unsigned long key; // key in the hashtable unsigned int i; @@ -319,7 +319,7 @@ int SavePCX(wxImage *image, wxOutputStream& stream) if (image->CountColours(256) <= 256) { - image->ComputeHistogram(h); + image->ComputeHistogram(histogram); format = wxPCX_8BIT; nplanes = 1; } @@ -371,7 +371,6 @@ int SavePCX(wxImage *image, wxOutputStream& stream) case wxPCX_8BIT: { unsigned char r, g, b; - wxHNode *hnode; for (i = 0; i < width; i++) { @@ -380,8 +379,7 @@ int SavePCX(wxImage *image, wxOutputStream& stream) b = *(src++); key = (r << 16) | (g << 8) | b; - hnode = (wxHNode *) h.Get(key); - p[i] = (unsigned char)hnode->index; + p[i] = (unsigned char)histogram[key].index; } break; } @@ -402,26 +400,22 @@ int SavePCX(wxImage *image, wxOutputStream& stream) free(p); - // For 8 bit images, build the palette and write it to the stream - + // For 8 bit images, build the palette and write it to the stream: if (format == wxPCX_8BIT) { - wxNode *node; - wxHNode *hnode; - // zero unused colours memset(pal, 0, sizeof(pal)); - h.BeginFind(); - while ((node = h.Next()) != NULL) + unsigned long index; + + for (wxImageHistogram::iterator entry = histogram.begin(); + entry != histogram.end(); entry++ ) { - key = node->GetKeyInteger(); - hnode = (wxHNode *) node->GetData(); - - pal[3 * hnode->index] = (unsigned char)(key >> 16); - pal[3 * hnode->index + 1] = (unsigned char)(key >> 8); - pal[3 * hnode->index + 2] = (unsigned char)(key); - delete hnode; + key = entry->first; + index = entry->second.index; + pal[3 * index] = (unsigned char)(key >> 16); + pal[3 * index + 1] = (unsigned char)(key >> 8); + pal[3 * index + 2] = (unsigned char)(key); } stream.PutC(12); diff --git a/src/common/imagxpm.cpp b/src/common/imagxpm.cpp index 22584d6655..7ebe0c9edf 100644 --- a/src/common/imagxpm.cpp +++ b/src/common/imagxpm.cpp @@ -140,25 +140,23 @@ bool wxXPMHandler::SaveFile(wxImage * image, stream.Write(tmpbuf, strlen(tmpbuf)); // 3. create color symbols table: - wxHashTable table(wxKEY_INTEGER); - image->ComputeHistogram(table); + wxImageHistogram histogram; + image->ComputeHistogram(histogram); char *symbols_data = new char[cols * (chars_per_pixel+1)]; char **symbols = new char*[cols]; // 2a. find mask colour: - long mask_key = -1; + unsigned long mask_key = 0x1000000 /*invalid RGB value*/; if (image->HasMask()) mask_key = (image->GetMaskRed() << 16) | (image->GetMaskGreen() << 8) | image->GetMaskBlue(); // 2b. generate colour table: - table.BeginFind(); - wxNode *node = NULL; - while ((node = table.Next()) != NULL) + for (wxImageHistogram::iterator entry = histogram.begin(); + entry != histogram.end(); entry++ ) { - wxHNode *hnode = (wxHNode*) node->GetData(); - long index = hnode->index; + unsigned long index = entry->second.index; symbols[index] = symbols_data + index * (chars_per_pixel+1); char *sym = symbols[index]; @@ -171,7 +169,7 @@ bool wxXPMHandler::SaveFile(wxImage * image, } sym[j] = '\0'; - long key = node->GetKeyInteger(); + unsigned long key = entry->first; if (key == 0) tmp.Printf(wxT("\"%s c Black\",\n"), sym); @@ -195,8 +193,7 @@ bool wxXPMHandler::SaveFile(wxImage * image, for (i = 0; i < image->GetWidth(); i++, data += 3) { unsigned long key = (data[0] << 16) | (data[1] << 8) | (data[2]); - wxHNode *hnode = (wxHNode*) table.Get(key); - stream.Write(symbols[hnode->index], chars_per_pixel); + stream.Write(symbols[histogram[key].index], chars_per_pixel); } tmp_c = '\"'; stream.Write(&tmp_c, 1); if ( j + 1 < image->GetHeight() ) @@ -212,13 +209,6 @@ bool wxXPMHandler::SaveFile(wxImage * image, delete[] symbols; delete[] symbols_data; - // FIXME: it will be better to use macros-based wxHashTable & DeleteContents(TRUE) - table.BeginFind(); - while ((node = table.Next()) != NULL) - { - delete (wxHNode *) node->GetData(); - } - return TRUE; } diff --git a/src/gtk/cursor.cpp b/src/gtk/cursor.cpp index ab0d7294a2..adf882b133 100644 --- a/src/gtk/cursor.cpp +++ b/src/gtk/cursor.cpp @@ -205,42 +205,42 @@ wxCursor::wxCursor( const wxImage & image ) //it seems a waste of effort to copy the image //but otherwise we need to remove the const modifier ?? wxImage tmpImage = image.Copy(); - wxHashTable hTable; + wxImageHistogram histogram; //colors as rrggbb unsigned long key; + unsigned long value; unsigned long keyMaskColor = 0; - if (bHasMask) keyMaskColor = (r << 16) | (g << 8) | b; + if (bHasMask) + keyMaskColor = (r << 16) | (g << 8) | b; - tmpImage.ComputeHistogram( hTable ); + tmpImage.ComputeHistogram(histogram); - long MostFreqCol = 0 ; long nMost = 0; - long NextFreqCol = 0 ; long nNext = 0; - long value ; - hTable.BeginFind(); - wxNode *node = NULL; - while ((node = hTable.Next()) != NULL) + long MostFreqCol = 0; + unsigned long nMost = 0; + long NextFreqCol = 0; + unsigned long nNext = 0; + wxImageHistogram::iterator entry = histogram.begin(); + + while ( entry != histogram.end() ) { - wxHNode *hnode = (wxHNode*) node->GetData(); - value = hnode->value; - key = node->GetKeyInteger() ; - if (!bHasMask || (key != keyMaskColor) ) + value = entry->second.value; + key = entry->first; + if ( !bHasMask || (key != keyMaskColor) ) { - if (value > nMost) + if (value > nMost) { - nMost = value; - MostFreqCol = key; + nMost = value; + MostFreqCol = key; } - else - if (value > nNext) + else if (value > nNext) { - nNext = value ; - NextFreqCol = key; + nNext = value; + NextFreqCol = key; } } } - wxColour fg = wxColour ( (unsigned char)(MostFreqCol >> 16), (unsigned char)(MostFreqCol >> 8), (unsigned char)(MostFreqCol) ) ; @@ -249,20 +249,18 @@ wxCursor::wxCursor( const wxImage & image ) (unsigned char)(NextFreqCol >> 8), (unsigned char)(NextFreqCol) ) ; - - int hotSpotX=0; int hotSpotY=0; if (image.HasOption(wxCUR_HOTSPOT_X)) - hotSpotX = image.GetOptionInt(wxCUR_HOTSPOT_X); + hotSpotX = image.GetOptionInt(wxCUR_HOTSPOT_X); if (image.HasOption(wxCUR_HOTSPOT_Y)) - hotSpotY = image.GetOptionInt(wxCUR_HOTSPOT_Y); + hotSpotY = image.GetOptionInt(wxCUR_HOTSPOT_Y); if (hotSpotX < 0 || hotSpotX >= w) - hotSpotX = 0; + hotSpotX = 0; if (hotSpotY < 0 || hotSpotY >= h) - hotSpotY = 0; + hotSpotY = 0; GdkBitmap *data = gdk_bitmap_create_from_data( wxGetRootWindow()->window, (gchar *) bits, w, h ); @@ -278,7 +276,6 @@ wxCursor::wxCursor( const wxImage & image ) gdk_bitmap_unref( mask ); delete [] bits ; delete [] maskBits; - } #endif diff --git a/src/gtk1/cursor.cpp b/src/gtk1/cursor.cpp index ab0d7294a2..adf882b133 100644 --- a/src/gtk1/cursor.cpp +++ b/src/gtk1/cursor.cpp @@ -205,42 +205,42 @@ wxCursor::wxCursor( const wxImage & image ) //it seems a waste of effort to copy the image //but otherwise we need to remove the const modifier ?? wxImage tmpImage = image.Copy(); - wxHashTable hTable; + wxImageHistogram histogram; //colors as rrggbb unsigned long key; + unsigned long value; unsigned long keyMaskColor = 0; - if (bHasMask) keyMaskColor = (r << 16) | (g << 8) | b; + if (bHasMask) + keyMaskColor = (r << 16) | (g << 8) | b; - tmpImage.ComputeHistogram( hTable ); + tmpImage.ComputeHistogram(histogram); - long MostFreqCol = 0 ; long nMost = 0; - long NextFreqCol = 0 ; long nNext = 0; - long value ; - hTable.BeginFind(); - wxNode *node = NULL; - while ((node = hTable.Next()) != NULL) + long MostFreqCol = 0; + unsigned long nMost = 0; + long NextFreqCol = 0; + unsigned long nNext = 0; + wxImageHistogram::iterator entry = histogram.begin(); + + while ( entry != histogram.end() ) { - wxHNode *hnode = (wxHNode*) node->GetData(); - value = hnode->value; - key = node->GetKeyInteger() ; - if (!bHasMask || (key != keyMaskColor) ) + value = entry->second.value; + key = entry->first; + if ( !bHasMask || (key != keyMaskColor) ) { - if (value > nMost) + if (value > nMost) { - nMost = value; - MostFreqCol = key; + nMost = value; + MostFreqCol = key; } - else - if (value > nNext) + else if (value > nNext) { - nNext = value ; - NextFreqCol = key; + nNext = value; + NextFreqCol = key; } } } - wxColour fg = wxColour ( (unsigned char)(MostFreqCol >> 16), (unsigned char)(MostFreqCol >> 8), (unsigned char)(MostFreqCol) ) ; @@ -249,20 +249,18 @@ wxCursor::wxCursor( const wxImage & image ) (unsigned char)(NextFreqCol >> 8), (unsigned char)(NextFreqCol) ) ; - - int hotSpotX=0; int hotSpotY=0; if (image.HasOption(wxCUR_HOTSPOT_X)) - hotSpotX = image.GetOptionInt(wxCUR_HOTSPOT_X); + hotSpotX = image.GetOptionInt(wxCUR_HOTSPOT_X); if (image.HasOption(wxCUR_HOTSPOT_Y)) - hotSpotY = image.GetOptionInt(wxCUR_HOTSPOT_Y); + hotSpotY = image.GetOptionInt(wxCUR_HOTSPOT_Y); if (hotSpotX < 0 || hotSpotX >= w) - hotSpotX = 0; + hotSpotX = 0; if (hotSpotY < 0 || hotSpotY >= h) - hotSpotY = 0; + hotSpotY = 0; GdkBitmap *data = gdk_bitmap_create_from_data( wxGetRootWindow()->window, (gchar *) bits, w, h ); @@ -278,7 +276,6 @@ wxCursor::wxCursor( const wxImage & image ) gdk_bitmap_unref( mask ); delete [] bits ; delete [] maskBits; - } #endif -- 2.45.2