« Return to Thread: A big optimization to gradient_linear_color

A big optimization to gradient_linear_color

by Vinnie-4 :: Rate this Message:

Reply to Author | View in Thread


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

 « Return to Thread: A big optimization to gradient_linear_color