static fz_weights *
make_weights(fz_context *ctx, int src_w, float x, float dst_w, fz_scale_filter *filter, int vertical, int dst_w_int, int patch_l, int patch_r, int n, int flip)
{
	fz_weights *weights;
	float F, G;
	float window;
	int j;

	if (dst_w < src_w)
	{
		/* Scaling down */
		F = dst_w / src_w;
		G = 1;
	}
	else
	{
		/* Scaling up */
		F = 1;
		G = src_w / dst_w;
	}
	window = filter->width / F;
	DBUG(("make_weights src_w=%d x=%g dst_w=%g patch_l=%d patch_r=%d F=%g window=%g\n", src_w, x, dst_w, patch_l, patch_r, F, window));
	weights	= new_weights(ctx, filter, src_w, dst_w, patch_r-patch_l, n, flip, patch_l);
	if (!weights)
		return NULL;
	for (j = patch_l; j < patch_r; j++)
	{
		/* find the position of the centre of dst[j] in src space */
		float centre = (j - x + 0.5f)*src_w/dst_w - 0.5f;
		int l, r;
		l = ceilf(centre - window);
		r = floorf(centre + window);
		DBUG(("%d: centre=%g l=%d r=%d\n", j, centre, l, r));
		init_weights(weights, j);
		for (; l <= r; l++)
		{
			add_weight(weights, j, l, filter, x, F, G, src_w, dst_w);
		}
		check_weights(weights, j, dst_w_int, x, dst_w);
		if (vertical)
		{
			reorder_weights(weights, j, src_w);
		}
	}
	weights->count++; /* weights->count = dst_w_int now */
	return weights;
}
static fz_weights *
make_weights(fz_context *ctx, int src_w, float x, float dst_w, fz_scale_filter *filter, int vertical, int dst_w_int, int patch_l, int patch_r, int n, int flip, fz_scale_cache *cache)
{
	fz_weights *weights;
	float F, G;
	float window;
	int j;

	if (cache)
	{
		if (cache->src_w == src_w && cache->x == x && cache->dst_w == dst_w &&
			cache->filter == filter && cache->vertical == vertical &&
			cache->dst_w_int == dst_w_int &&
			cache->patch_l == patch_l && cache->patch_r == patch_r &&
			cache->n == n && cache->flip == flip)
		{
			return cache->weights;
		}
		cache->src_w = src_w;
		cache->x = x;
		cache->dst_w = dst_w;
		cache->filter = filter;
		cache->vertical = vertical;
		cache->dst_w_int = dst_w_int;
		cache->patch_l = patch_l;
		cache->patch_r = patch_r;
		cache->n = n;
		cache->flip = flip;
		fz_free(ctx, cache->weights);
		cache->weights = NULL;
	}

	if (dst_w < src_w)
	{
		/* Scaling down */
		F = dst_w / src_w;
		G = 1;
	}
	else
	{
		/* Scaling up */
		F = 1;
		G = src_w / dst_w;
	}
	window = filter->width / F;
	weights	= new_weights(ctx, filter, src_w, dst_w, patch_r-patch_l, n, flip, patch_l);
	if (!weights)
		return NULL;
	for (j = patch_l; j < patch_r; j++)
	{
		/* find the position of the centre of dst[j] in src space */
		float centre = (j - x + 0.5f)*src_w/dst_w - 0.5f;
		int l, r;
		l = ceilf(centre - window);
		r = floorf(centre + window);
		init_weights(weights, j);
		for (; l <= r; l++)
		{
			add_weight(weights, j, l, filter, x, F, G, src_w, dst_w);
		}
		check_weights(weights, j, dst_w_int, x, dst_w);
		if (vertical)
		{
			reorder_weights(weights, j, src_w);
		}
	}
	weights->count++; /* weights->count = dst_w_int now */
	if (cache)
	{
		cache->weights = weights;
	}
	return weights;
}