Based on the ideas presented in this thread, I wrote a replacement for agg::gradient_linear_color that uses a lookup table for the most expensive operation (operator[]). Its a pair of classes. One is the replacement, the other is the cache.
You will have to change the code that uses Util:Pool (my custom memory allocator):
template<class ColorT>
struct gradient_linear_cache
{
gradient_linear_cache( Util::Pool &pool );
~gradient_linear_cache();
struct Item
{
ColorT c1;
ColorT c2;
unsigned size;
ColorT * table;
Item * next;
};
ColorT *GetTable( const ColorT &c0, const ColorT &c1, unsigned size );
Util::Pool &m_pool;
Item *m_list;
int m_count;
};
template<class ColorT>
gradient_linear_cache<ColorT>::gradient_linear_cache( Util::Pool &pool )
:m_pool( pool )
{
m_list=0;
m_count=0;
}
template<class ColorT>
gradient_linear_cache<ColorT>::~gradient_linear_cache()
{
Item *item=m_list;
while( item!=0 )
{
Item *next=item->next;
m_pool.Free( item->table );
m_pool.Free( item );
item=next;
}
}
template<class ColorT>
ColorT *gradient_linear_cache<ColorT>::GetTable( const ColorT &c1, const ColorT &c2, unsigned size )
{
ColorT *table=0;
Item *item=m_list;
while( item!=0 )
{
if( ::memcmp( &item->c1, &c1, sizeof(c1) )==0 &&
::memcmp( &item->c2, &c2, sizeof(c2) )==0 &&
item->size==size )
{
table=item->table;
break;
}
item=item->next;
}
if( !table )
{
Item *item=(Item *)m_pool.Alloc(sizeof(*item));
item->table=(ColorT *)m_pool.Alloc(size*sizeof(ColorT));
item->next=m_list;
item->c1=c1;
item->c2=c2;
item->size=size;
m_list=item;
table=item->table;
double m=1/double(size-1);
for( int i=0;i<size;i++ )
table[i]=c1.gradient( c2, double(i) * m );
m_count++;
}
return table;
}
//------------------------------------------------------------------------
template<class ColorT>
struct gradient_linear_color_fast
{
typedef ColorT color_type;
gradient_linear_color_fast( gradient_linear_cache<ColorT> &cache ):m_cache(cache) {}
gradient_linear_color_fast( gradient_linear_cache<ColorT> &cache, const color_type& c1, const color_type& c2,
unsigned size = 256) :
m_cache(cache), m_size(size)
{
m_table=m_cache.GetTable( c1, c2, size );
}
unsigned size() const { return m_size; }
color_type operator [] (unsigned v) const
{
return m_table[v];
}
void colors(const color_type& c1, const color_type& c2, unsigned size = 256)
{
m_table=m_cache.GetTable( c1, c2, size );
m_size = size;
}
gradient_linear_cache<ColorT> &m_cache;
ColorT *m_table;
unsigned m_size;
};
------------------------------------------------------------------------------
The NEW KODAK i700 Series Scanners deliver under ANY circumstances! Your
production scanning environment may not be a perfect world - but thanks to
Kodak, there's a perfect scanner to get the job done! With the NEW KODAK i700
Series Scanner you'll get full speed at 300 dpi even with all image
processing features enabled.
http://p.sf.net/sfu/kodak-com_______________________________________________
Vector-agg-general mailing list
Vector-agg-general@...
https://lists.sourceforge.net/lists/listinfo/vector-agg-general