changed wxImage::ComputeHistogram to use wxHashMap

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@14056 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Václav Slavík
2002-02-07 18:11:39 +00:00
parent d353bd452e
commit 952ae1e88b
6 changed files with 100 additions and 120 deletions

View File

@@ -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)
{

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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