<commit_before>package gift

import (
	"image"
	"image/draw"
	"math"
)

// Resampling is an interpolation algorithm used for image resizing.
type Resampling interface {
	Support() float32
	Kernel(float32) float32
}

func bcspline(x, b, c float32) float32 {
	if x < 0 {
		x = -x
	}
	if x < 1 {
		return ((12-9*b-6*c)*x*x*x + (-18+12*b+6*c)*x*x + (6 - 2*b)) / 6
	}
	if x < 2 {
		return ((-b-6*c)*x*x*x + (6*b+30*c)*x*x + (-12*b-48*c)*x + (8*b + 24*c)) / 6
	}
	return 0
}

func sinc(x float32) float32 {
	if x == 0 {
		return 1
	}
	return float32(math.Sin(math.Pi*float64(x)) / (math.Pi * float64(x)))
}

type resamp struct {
	name    string
	support float32
	kernel  func(float32) float32
}

func (r resamp) String() string {
	return r.name
}

func (r resamp) Support() float32 {
	return r.support
}

func (r resamp) Kernel(x float32) float32 {
	return r.kernel(x)
}

// NearestNeighborResampling is a nearest neighbor resampling filter.
var NearestNeighborResampling Resampling

// BoxResampling is a box resampling filter (average of surrounding pixels).
var BoxResampling Resampling

// LinearResampling is a bilinear resampling filter.
var LinearResampling Resampling

// CubicResampling is a bicubic resampling filter (Catmull-Rom).
var CubicResampling Resampling

// LanczosResampling is a Lanczos resampling filter (3 lobes).
var LanczosResampling Resampling

type resampWeight struct {
	index  int
	weight float32
}

func prepareResampWeights(dstSize, srcSize int, resampling Resampling) [][]resampWeight {
	delta := float32(srcSize) / float32(dstSize)
	scale := delta
	if scale < 1 {
		scale = 1
	}
	radius := float32(math.Ceil(float64(scale * resampling.Support())))

	result := make([][]resampWeight, dstSize)

	for i := 0; i < dstSize; i++ {
		center := (float32(i)+0.5)*delta - 0.5

		left := int(math.Ceil(float64(center - radius)))
		if left < 0 {
			left = 0
		}
		right := int(math.Floor(float64(center + radius)))
		if right > srcSize-1 {
			right = srcSize - 1
		}

		result[i] = make([]resampWeight, 0, right-left+1)

		var sum float32
		for j := left; j <= right; j++ {
			weight := resampling.Kernel((float32(j) - center) / scale)
			if weight == 0 {
				continue
			}
			result[i] = append(result[i], resampWeight{
				index:  j,
				weight: weight,
			})
			sum += weight
		}

		for j := range result[i] {
			result[i][j].weight /= sum
		}
	}

	return result
}

func resizeLine(dst []pixel, src []pixel, weights [][]resampWeight) {
	for i := 0; i < len(dst); i++ {
		var r, g, b, a float32
		for _, w := range weights[i] {
			c := src[w.index]
			wa := c.a * w.weight
			r += c.r * wa
			g += c.g * wa
			b += c.b * wa
			a += wa
		}
		if a != 0 {
			r /= a
			g /= a
			b /= a
		}
		dst[i] = pixel{r, g, b, a}
	}
}<commit_msg>resize: further reduce the number allocations<commit_after>package gift

import (
	"image"
	"image/draw"
	"math"
)

// Resampling is an interpolation algorithm used for image resizing.
type Resampling interface {
	Support() float32
	Kernel(float32) float32
}

func bcspline(x, b, c float32) float32 {
	if x < 0 {
		x = -x
	}
	if x < 1 {
		return ((12-9*b-6*c)*x*x*x + (-18+12*b+6*c)*x*x + (6 - 2*b)) / 6
	}
	if x < 2 {
		return ((-b-6*c)*x*x*x + (6*b+30*c)*x*x + (-12*b-48*c)*x + (8*b + 24*c)) / 6
	}
	return 0
}

func sinc(x float32) float32 {
	if x == 0 {
		return 1
	}
	return float32(math.Sin(math.Pi*float64(x)) / (math.Pi * float64(x)))
}

type resamp struct {
	name    string
	support float32
	kernel  func(float32) float32
}

func (r resamp) String() string {
	return r.name
}

func (r resamp) Support() float32 {
	return r.support
}

func (r resamp) Kernel(x float32) float32 {
	return r.kernel(x)
}

// NearestNeighborResampling is a nearest neighbor resampling filter.
var NearestNeighborResampling Resampling

// BoxResampling is a box resampling filter (average of surrounding pixels).
var BoxResampling Resampling

// LinearResampling is a bilinear resampling filter.
var LinearResampling Resampling

// CubicResampling is a bicubic resampling filter (Catmull-Rom).
var CubicResampling Resampling

// LanczosResampling is a Lanczos resampling filter (3 lobes).
var LanczosResampling Resampling

type resampWeight struct {
	index  int
	weight float32
}

func prepareResampWeights(dstSize, srcSize int, resampling Resampling) [][]resampWeight {
	delta := float32(srcSize) / float32(dstSize)
	scale := delta
	if scale < 1 {
		scale = 1
	}
	radius := float32(math.Ceil(float64(scale * resampling.Support())))

	result := make([][]resampWeight, dstSize)
	tmp := make([]resampWeight, 0, dstSize*int(radius+2)*2)

	for i := 0; i < dstSize; i++ {
		center := (float32(i)+0.5)*delta - 0.5

		left := int(math.Ceil(float64(center - radius)))
		if left < 0 {
			left = 0
		}
		right := int(math.Floor(float64(center + radius)))
		if right > srcSize-1 {
			right = srcSize - 1
		}

		var sum float32
		for j := left; j <= right; j++ {
			weight := resampling.Kernel((float32(j) - center) / scale)
			if weight == 0 {
				continue
			}
			tmp = append(tmp, resampWeight{
				index:  j,
				weight: weight,
			})
			sum += weight
		}

		for j := range tmp {
			tmp[j].weight /= sum
		}

		result[i] = tmp
		tmp = tmp[len(tmp):]
	}

	return result
}

func resizeLine(dst []pixel, src []pixel, weights [][]resampWeight) {
	for i := 0; i < len(dst); i++ {
		var r, g, b, a float32
		for _, w := range weights[i] {
			c := src[w.index]
			wa := c.a * w.weight
			r += c.r * wa
			g += c.g * wa
			b += c.b * wa
			a += wa
		}
		if a != 0 {
			r /= a
			g /= a
			b /= a
		}
		dst[i] = pixel{r, g, b, a}
	}
}
{'fraction_non_alphanumeric': 0.1484149855907781, 'fraction_numerical': 0.03656340057636888, 'mean_word_length': 3.1440298507462687, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '587595', 'n_tokens_mistral': 2482, 'n_tokens_neox': 2189, 'n_words': 607}