#include "wx/string.h"
#include "wx/gdicmn.h"
#include "wx/bitmap.h"
+#include "wx/hashmap.h"
#if wxUSE_STREAMS
# include "wx/stream.h"
};
//-----------------------------------------------------------------------------
-// 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:
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)
{
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;
key = (r2 << 16) | (g2 << 8) | b2;
- while ( (wxHNode *) hTable.Get(key) )
+ while ( histogram.find(key) != histogram.end() )
{
// color already used
r2++;
}
-// 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();
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;
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;
if (image->CountColours(256) <= 256)
{
- image->ComputeHistogram(h);
+ image->ComputeHistogram(histogram);
format = wxPCX_8BIT;
nplanes = 1;
}
case wxPCX_8BIT:
{
unsigned char r, g, b;
- wxHNode *hnode;
for (i = 0; i < width; i++)
{
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;
}
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);
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];
}
sym[j] = '\0';
- long key = node->GetKeyInteger();
+ unsigned long key = entry->first;
if (key == 0)
tmp.Printf(wxT("\"%s c Black\",\n"), sym);
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() )
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;
}
//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) ) ;
(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 );
gdk_bitmap_unref( mask );
delete [] bits ;
delete [] maskBits;
-
}
#endif
//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) ) ;
(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 );
gdk_bitmap_unref( mask );
delete [] bits ;
delete [] maskBits;
-
}
#endif