示例#1
0
 //----------------------------------------------------------------
 public void LocalScale(out int x, out int y)
 {
     m_interpolator.LocalScale(out x, out y);
 }
        //--------------------------------------------------------------------
        public unsafe override void Generate(RGBA_Bytes *span, int x, int y, uint len)
        {
            ISpanInterpolator spanInterpolator = base.interpolator();

            spanInterpolator.Begin(x + base.filter_dx_dbl(), y + base.filter_dy_dbl(), len);

            int *fg = stackalloc int[4];

            byte *fg_ptr;

            fixed(short *pWeightArray = filter().weight_array())
            {
                int diameter     = (int)base.filter().diameter();
                int filter_scale = diameter << (int)image_subpixel_scale_e.Shift;

                short *weight_array = pWeightArray;

                do
                {
                    int rx;
                    int ry;
                    int rx_inv = (int)image_subpixel_scale_e.Scale;
                    int ry_inv = (int)image_subpixel_scale_e.Scale;
                    spanInterpolator.Coordinates(out x, out y);
                    spanInterpolator.LocalScale(out rx, out ry);
                    base.AdjustScale(ref rx, ref ry);

                    rx_inv = (int)image_subpixel_scale_e.Scale * (int)image_subpixel_scale_e.Scale / rx;
                    ry_inv = (int)image_subpixel_scale_e.Scale * (int)image_subpixel_scale_e.Scale / ry;

                    int radius_x = (diameter * rx) >> 1;
                    int radius_y = (diameter * ry) >> 1;
                    int len_x_lr =
                        (diameter * rx + (int)image_subpixel_scale_e.Mask) >>
                        (int)(int)image_subpixel_scale_e.Shift;

                    x += base.filter_dx_int() - radius_x;
                    y += base.filter_dy_int() - radius_y;

                    fg[0] = fg[1] = fg[2] = fg[3] = (int)image_filter_scale_e.Scale / 2;

                    int y_lr = y >> (int)(int)image_subpixel_scale_e.Shift;
                    int y_hr = (((int)image_subpixel_scale_e.Mask - (y & (int)image_subpixel_scale_e.Mask)) *
                                ry_inv) >>
                               (int)(int)image_subpixel_scale_e.Shift;
                    int total_weight = 0;
                    int x_lr         = x >> (int)(int)image_subpixel_scale_e.Shift;
                    int x_hr         = (((int)image_subpixel_scale_e.Mask - (x & (int)image_subpixel_scale_e.Mask)) *
                                        rx_inv) >>
                                       (int)(int)image_subpixel_scale_e.Shift;
                    int x_hr2 = x_hr;
                    fg_ptr = base.source().Span(x_lr, y_lr, (uint)len_x_lr);

                    for (; ;)
                    {
                        int weight_y = weight_array[y_hr];
                        x_hr = x_hr2;
                        for (; ;)
                        {
                            int weight = (weight_y * weight_array[x_hr] +
                                          (int)image_filter_scale_e.Scale / 2) >>
                                         downscale_shift;
                            fg[0]        += *fg_ptr++ *weight;
                            fg[1]        += *fg_ptr++ *weight;
                            fg[2]        += *fg_ptr++ *weight;
                            fg[3]        += *fg_ptr++ *weight;
                            total_weight += weight;
                            x_hr         += rx_inv;
                            if (x_hr >= filter_scale)
                            {
                                break;
                            }
                            fg_ptr = base.source().NextX();
                        }
                        y_hr += ry_inv;
                        if (y_hr >= filter_scale)
                        {
                            break;
                        }

                        fg_ptr = base.source().NextY();
                    }

                    fg[0] /= total_weight;
                    fg[1] /= total_weight;
                    fg[2] /= total_weight;
                    fg[3] /= total_weight;

                    if (fg[0] < 0)
                    {
                        fg[0] = 0;
                    }
                    if (fg[1] < 0)
                    {
                        fg[1] = 0;
                    }
                    if (fg[2] < 0)
                    {
                        fg[2] = 0;
                    }
                    if (fg[3] < 0)
                    {
                        fg[3] = 0;
                    }

                    if (fg[0] > fg[0])
                    {
                        fg[0] = fg[0];
                    }
                    if (fg[1] > fg[1])
                    {
                        fg[1] = fg[1];
                    }
                    if (fg[2] > fg[2])
                    {
                        fg[2] = fg[2];
                    }
                    if (fg[3] > base_mask)
                    {
                        fg[3] = base_mask;
                    }

                    span->R_Byte = (byte)fg[OrderR];
                    span->G_Byte = (byte)fg[OrderG];
                    span->B_Byte = (byte)fg[OrderB];
                    span->A_Byte = (byte)fg[OrderA];

                    ++span;
                    interpolator().Next();
                } while (--len != 0);
            }
        }
        //--------------------------------------------------------------------
        public unsafe override void Generate(RGBA_Bytes *span, int x, int y, uint len)
        {
            ISpanInterpolator <T> spanInterpolator = base.Interpolator;

            spanInterpolator.Begin(M.New <T>(x).Add(base.FilterDxDbl()), M.New <T>(y).Add(base.FilterDyDbl()), len);

            int *fg = stackalloc int[3];

            byte *fg_ptr;

            fixed(short *pWeightArray = Filter.WeightArray())
            {
                int diameter     = (int)base.Filter.Diameter();
                int filter_scale = diameter << (int)image_subpixel_scale_e.Shift;

                short *weight_array = pWeightArray;

                do
                {
                    int rx;
                    int ry;
                    int rx_inv = (int)image_subpixel_scale_e.Scale;
                    int ry_inv = (int)image_subpixel_scale_e.Scale;
                    spanInterpolator.Coordinates(out x, out y);
                    spanInterpolator.LocalScale(out rx, out ry);
                    base.AdjustScale(ref rx, ref ry);

                    rx_inv = (int)image_subpixel_scale_e.Scale * (int)image_subpixel_scale_e.Scale / rx;
                    ry_inv = (int)image_subpixel_scale_e.Scale * (int)image_subpixel_scale_e.Scale / ry;

                    int radius_x = (diameter * rx) >> 1;
                    int radius_y = (diameter * ry) >> 1;
                    int len_x_lr =
                        (diameter * rx + (int)image_subpixel_scale_e.Mask) >>
                        (int)(int)image_subpixel_scale_e.Shift;

                    x += base.FilterDxInt() - radius_x;
                    y += base.FilterDyInt() - radius_y;

                    fg[0] = fg[1] = fg[2] = (int)image_filter_scale_e.Scale / 2;

                    int y_lr = y >> (int)(int)image_subpixel_scale_e.Shift;
                    int y_hr = (((int)image_subpixel_scale_e.Mask - (y & (int)image_subpixel_scale_e.Mask)) *
                                ry_inv) >>
                               (int)(int)image_subpixel_scale_e.Shift;
                    int total_weight = 0;
                    int x_lr         = x >> (int)(int)image_subpixel_scale_e.Shift;
                    int x_hr         = (((int)image_subpixel_scale_e.Mask - (x & (int)image_subpixel_scale_e.Mask)) *
                                        rx_inv) >>
                                       (int)(int)image_subpixel_scale_e.Shift;
                    int x_hr2 = x_hr;
                    fg_ptr = base.Source().span(x_lr, y_lr, (uint)len_x_lr);

                    for (; ;)
                    {
                        int weight_y = weight_array[y_hr];
                        x_hr = x_hr2;
                        for (; ;)
                        {
                            int weight = (weight_y * weight_array[x_hr] +
                                          (int)image_filter_scale_e.Scale / 2) >>
                                         DownscaleShift;
                            fg[0]        += *fg_ptr++ *weight;
                            fg[1]        += *fg_ptr++ *weight;
                            fg[2]        += *fg_ptr++ *weight;
                            total_weight += weight;
                            x_hr         += rx_inv;
                            if (x_hr >= filter_scale)
                            {
                                break;
                            }
                            fg_ptr = base.Source().next_x();
                        }
                        y_hr += ry_inv;
                        if (y_hr >= filter_scale)
                        {
                            break;
                        }

                        fg_ptr = base.Source().next_y();
                    }

                    fg[0] /= total_weight;
                    fg[1] /= total_weight;
                    fg[2] /= total_weight;

                    if (fg[0] < 0)
                    {
                        fg[0] = 0;
                    }
                    if (fg[1] < 0)
                    {
                        fg[1] = 0;
                    }
                    if (fg[2] < 0)
                    {
                        fg[2] = 0;
                    }

                    if (fg[0] > fg[0])
                    {
                        fg[0] = fg[0];
                    }
                    if (fg[1] > fg[1])
                    {
                        fg[1] = fg[1];
                    }
                    if (fg[2] > fg[2])
                    {
                        fg[2] = fg[2];
                    }

                    //span->R_Byte = (byte)fg[OrderR];
                    //span->G_Byte = (byte)fg[OrderG];
                    //span->B_Byte = (byte)fg[OrderB];
                    //span->A_Byte = (byte)BaseMask;

                    (*span) = new RGBA_Bytes((byte)fg[OrderR], (byte)fg[OrderG], (byte)fg[OrderB], (byte)BaseMask);

                    ++span;
                    Interpolator.Next();
                } while (--len != 0);
            }
        }