public override void generate(RGBA_Bytes[] span, int spanIndex, int x, int y, int len) { ISpanInterpolator spanInterpolator = base.interpolator(); spanInterpolator.begin(x + base.filter_dx_dbl(), y + base.filter_dy_dbl(), len); int[] fg = new int[3]; byte[] fg_ptr; int[] weightArray = filter().weight_array(); int diameter = (int)base.filter().diameter(); int filter_scale = diameter << (int)image_subpixel_scale_e.image_subpixel_shift; int[] weight_array = weightArray; do { int rx; int ry; int rx_inv = (int)image_subpixel_scale_e.image_subpixel_scale; int ry_inv = (int)image_subpixel_scale_e.image_subpixel_scale; spanInterpolator.coordinates(out x, out y); spanInterpolator.local_scale(out rx, out ry); base.adjust_scale(ref rx, ref ry); rx_inv = (int)image_subpixel_scale_e.image_subpixel_scale * (int)image_subpixel_scale_e.image_subpixel_scale / rx; ry_inv = (int)image_subpixel_scale_e.image_subpixel_scale * (int)image_subpixel_scale_e.image_subpixel_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.image_subpixel_mask) >> (int)(int)image_subpixel_scale_e.image_subpixel_shift; x += base.filter_dx_int() - radius_x; y += base.filter_dy_int() - radius_y; fg[0] = fg[1] = fg[2] = (int)image_filter_scale_e.image_filter_scale / 2; int y_lr = y >> (int)(int)image_subpixel_scale_e.image_subpixel_shift; int y_hr = (((int)image_subpixel_scale_e.image_subpixel_mask - (y & (int)image_subpixel_scale_e.image_subpixel_mask)) * ry_inv) >> (int)(int)image_subpixel_scale_e.image_subpixel_shift; int total_weight = 0; int x_lr = x >> (int)(int)image_subpixel_scale_e.image_subpixel_shift; int x_hr = (((int)image_subpixel_scale_e.image_subpixel_mask - (x & (int)image_subpixel_scale_e.image_subpixel_mask)) * rx_inv) >> (int)(int)image_subpixel_scale_e.image_subpixel_shift; int x_hr2 = x_hr; int sourceIndex; fg_ptr = base.GetImageBufferAccessor().span(x_lr, y_lr, len_x_lr, out sourceIndex); 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.image_filter_scale / 2) >> downscale_shift; fg[0] += fg_ptr[sourceIndex + ImageBuffer.OrderR] * weight; fg[1] += fg_ptr[sourceIndex + ImageBuffer.OrderG] * weight; fg[2] += fg_ptr[sourceIndex + ImageBuffer.OrderB] * weight; total_weight += weight; x_hr += rx_inv; if (x_hr >= filter_scale) { break; } fg_ptr = base.GetImageBufferAccessor().next_x(out sourceIndex); } y_hr += ry_inv; if (y_hr >= filter_scale) { break; } fg_ptr = base.GetImageBufferAccessor().next_y(out sourceIndex); } 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] > base_mask) { fg[0] = base_mask; } if (fg[1] > base_mask) { fg[1] = base_mask; } if (fg[2] > base_mask) { fg[2] = base_mask; } span[spanIndex].alpha = base_mask; span[spanIndex].red = (byte)fg[0]; span[spanIndex].green = (byte)fg[1]; span[spanIndex].blue = (byte)fg[2]; spanIndex++; interpolator().Next(); } while (--len != 0); }
//---------------------------------------------------------------- public void local_scale(out int x, out int y) { m_interpolator.local_scale(out x, out y); }