//--------------------------------------------------------------------
        public void generate(color_type *span, int x, int y, unsigned len)
        {
            base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
                                            y + base_type::filter_dy_dbl(), len);

            int         fg;
            value_type *fg_ptr;

            unsigned diameter     = base_type::filter().diameter();
            int      start        = base_type::filter().start();
            int16 *  weight_array = base_type::filter().weight_array();

            int x_count;
            int weight_y;

            do
            {
                base_type::interpolator().coordinates(&x, &y);

                x -= base_type::filter_dx_int();
                y -= base_type::filter_dy_int();

                int x_hr = x;
                int y_hr = y;

                int x_lr = x_hr >> image_subpixel_shift;
                int y_lr = y_hr >> image_subpixel_shift;

                fg = image_filter_scale / 2;

                int      x_fract = x_hr & image_subpixel_mask;
                unsigned y_count = diameter;

                y_hr   = image_subpixel_mask - (y_hr & image_subpixel_mask);
                fg_ptr = (value_type *)base_type::source().span(x_lr + start,
                                                                y_lr + start,
                                                                diameter);
                for (;;)
                {
                    x_count  = diameter;
                    weight_y = weight_array[y_hr];
                    x_hr     = image_subpixel_mask - x_fract;
                    for (;;)
                    {
                        fg += *fg_ptr *
                              ((weight_y * weight_array[x_hr] +
                                image_filter_scale / 2) >>
                               image_filter_shift);
                        if (--x_count == 0)
                        {
                            break;
                        }
                        x_hr  += image_subpixel_scale;
                        fg_ptr = (value_type *)base_type::source().next_x();
                    }

                    if (--y_count == 0)
                    {
                        break;
                    }
                    y_hr  += image_subpixel_scale;
                    fg_ptr = (value_type *)base_type::source().next_y();
                }

                fg >>= image_filter_shift;
                if (fg < 0)
                {
                    fg = 0;
                }
                if (fg > base_mask)
                {
                    fg = base_mask;
                }
                span->v = (value_type)fg;
                span->a = base_mask;

                ++span;
                ++base_type::interpolator();
            } while(--len);
        }
        //--------------------------------------------------------------------
        public void generate(color_type *span, int x, int y, unsigned len)
        {
            base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
                                            y + base_type::filter_dy_dbl(), len);
            long_type fg;

            int diameter     = base_type::filter().diameter();
            int filter_scale = diameter << image_subpixel_shift;

            int16 *weight_array = base_type::filter().weight_array();

            do
            {
                int rx;
                int ry;
                int rx_inv = image_subpixel_scale;
                int ry_inv = image_subpixel_scale;
                base_type::interpolator().coordinates(&x, &y);
                base_type::interpolator().local_scale(&rx, &ry);
                base_type::adjust_scale(&rx, &ry);

                rx_inv = image_subpixel_scale * image_subpixel_scale / rx;
                ry_inv = image_subpixel_scale * image_subpixel_scale / ry;

                int radius_x = (diameter * rx) >> 1;
                int radius_y = (diameter * ry) >> 1;
                int len_x_lr =
                    (diameter * rx + image_subpixel_mask) >>
                    image_subpixel_shift;

                x += base_type::filter_dx_int() - radius_x;
                y += base_type::filter_dy_int() - radius_y;

                fg = image_filter_scale / 2;

                int y_lr = y >> image_subpixel_shift;
                int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) *
                            ry_inv) >>
                           image_subpixel_shift;
                int total_weight = 0;
                int x_lr         = x >> image_subpixel_shift;
                int x_hr         = ((image_subpixel_mask - (x & image_subpixel_mask)) *
                                    rx_inv) >>
                                   image_subpixel_shift;
                int         x_hr2  = x_hr;
                value_type *fg_ptr =
                    (value_type *)base_type::source().span(x_lr, y_lr, len_x_lr);

                for (;;)
                {
                    int weight_y = weight_array[y_hr];
                    x_hr = x_hr2;
                    for (;;)
                    {
                        int weight = (weight_y * weight_array[x_hr] +
                                      image_filter_scale / 2) >>
                                     downscale_shift;
                        fg           += *fg_ptr * weight;
                        total_weight += weight;
                        x_hr         += rx_inv;
                        if (x_hr >= filter_scale)
                        {
                            break;
                        }
                        fg_ptr = (value_type *)base_type::source().next_x();
                    }
                    y_hr += ry_inv;
                    if (y_hr >= filter_scale)
                    {
                        break;
                    }
                    fg_ptr = (value_type *)base_type::source().next_y();
                }

                fg /= total_weight;
                if (fg < 0)
                {
                    fg = 0;
                }
                if (fg > base_mask)
                {
                    fg = base_mask;
                }

                span->v = (value_type)fg;
                span->a = base_mask;

                ++span;
                ++base_type::interpolator();
            } while(--len);
        }
        //--------------------------------------------------------------------
        public void generate(color_type *span, int x, int y, unsigned len)
        {
            base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
                                            y + base_type::filter_dy_dbl(), len);

            calc_type fg;

            value_type *fg_ptr;
            int16 *     weight_array = base_type::filter().weight_array() +
                                       ((base_type::filter().diameter() / 2 - 1) <<
                                   image_subpixel_shift);

            do
            {
                int x_hr;
                int y_hr;

                base_type::interpolator().coordinates(&x_hr, &y_hr);

                x_hr -= base_type::filter_dx_int();
                y_hr -= base_type::filter_dy_int();

                int x_lr = x_hr >> image_subpixel_shift;
                int y_lr = y_hr >> image_subpixel_shift;

                unsigned weight;
                fg = image_filter_scale / 2;

                x_hr &= image_subpixel_mask;
                y_hr &= image_subpixel_mask;

                fg_ptr = (value_type *)base_type::source().span(x_lr, y_lr, 2);
                weight = (weight_array[x_hr + image_subpixel_scale] *
                          weight_array[y_hr + image_subpixel_scale] +
                          image_filter_scale / 2) >>
                         image_filter_shift;
                fg += weight * *fg_ptr;

                fg_ptr = (value_type *)base_type::source().next_x();
                weight = (weight_array[x_hr] *
                          weight_array[y_hr + image_subpixel_scale] +
                          image_filter_scale / 2) >>
                         image_filter_shift;
                fg += weight * *fg_ptr;

                fg_ptr = (value_type *)base_type::source().next_y();
                weight = (weight_array[x_hr + image_subpixel_scale] *
                          weight_array[y_hr] +
                          image_filter_scale / 2) >>
                         image_filter_shift;
                fg += weight * *fg_ptr;

                fg_ptr = (value_type *)base_type::source().next_x();
                weight = (weight_array[x_hr] *
                          weight_array[y_hr] +
                          image_filter_scale / 2) >>
                         image_filter_shift;
                fg += weight * *fg_ptr;

                fg >>= image_filter_shift;
                if (fg > base_mask)
                {
                    fg = base_mask;
                }

                span->v = (value_type)fg;
                span->a = base_mask;
                ++span;
                ++base_type::interpolator();
            } while(--len);
        }