//---------------------------------------------------------------- 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); } }