<commit_before>// Copyright 2013 <NAME>.
// Licensed under MIT license.  See "license" file in this source tree.

// Median implements basic median cut color quantization.
package median

import (
	"container/heap"
	"image"
	"image/color"
	"math"
	"sort"
)

type Quantizer struct {}

// Quantize implements median cut color quantization.
//
// Argument n is the desired number of colors.  Returned is a paletted
// image with no more than n colors.
func (Quantizer) Quantize(img image.Image, n int) *image.Paletted {
	if n > 256 {
		n = 256
	}
	qz := newQuantizer(img, n)
	qz.cluster()         // cluster pixels by color
	return qz.paletted() // generate paletted image from clusters
}

type quantizer struct {
	img image.Image // original image
	cs  []cluster   // len(cs) is the desired number of colors
	ch  chValues    // buffer for computing median
}

type point struct{ x, y int32 }
type chValues []uint16
type queue []*cluster

type cluster struct {
	px       []point // list of points in the cluster
	widestCh int     // w const identifying channel with widest value range
}

const ( // w const
	wr = iota
	wg
	wb
)

func newQuantizer(img image.Image, nq int) *quantizer {
	b := img.Bounds()
	npx := (b.Max.X - b.Min.X) * (b.Max.Y - b.Min.Y)
	qz := &quantizer{
		img: img,
		ch:  make(chValues, npx),
		cs:  make([]cluster, nq),
	}
	// Populate initial cluster with all pixels from image.
	c := &qz.cs[0]
	px := make([]point, npx)
	c.px = px
	i := 0
	for y := b.Min.Y; y < b.Max.Y; y++ {
		for x := b.Min.X; x < b.Max.X; x++ {
			px[i].x = int32(x)
			px[i].y = int32(y)
			i++
		}
	}<commit_msg>avoid crash for n < 1<commit_after>// Copyright 2013 <NAME>.
// Licensed under MIT license.  See "license" file in this source tree.

// Median implements basic median cut color quantization.
package median

import (
	"container/heap"
	"image"
	"image/color"
	"math"
	"sort"
)

type Quantizer struct{}

// Quantize implements median cut color quantization.
//
// Argument n is the desired number of colors.  Returned is a paletted
// image with no more than n colors.
func (Quantizer) Quantize(img image.Image, n int) *image.Paletted {
	if n > 256 {
		n = 256
	}
	qz := newQuantizer(img, n)
	if n > 1 {
		qz.cluster() // cluster pixels by color
	}
	return qz.paletted() // generate paletted image from clusters
}

type quantizer struct {
	img image.Image // original image
	cs  []cluster   // len(cs) is the desired number of colors
	ch  chValues    // buffer for computing median
}

type point struct{ x, y int32 }
type chValues []uint16
type queue []*cluster

type cluster struct {
	px       []point // list of points in the cluster
	widestCh int     // w const identifying channel with widest value range
}

const ( // w const
	wr = iota
	wg
	wb
)

func newQuantizer(img image.Image, nq int) *quantizer {
	if nq < 1 {
		return &quantizer{img: img}
	}
	b := img.Bounds()
	npx := (b.Max.X - b.Min.X) * (b.Max.Y - b.Min.Y)
	qz := &quantizer{
		img: img,
		ch:  make(chValues, npx),
		cs:  make([]cluster, nq),
	}
	// Populate initial cluster with all pixels from image.
	c := &qz.cs[0]
	px := make([]point, npx)
	c.px = px
	i := 0
	for y := b.Min.Y; y < b.Max.Y; y++ {
		for x := b.Min.X; x < b.Max.X; x++ {
			px[i].x = int32(x)
			px[i].y = int32(y)
			i++
		}
	}
{'fraction_non_alphanumeric': 0.13429183236463751, 'fraction_numerical': 0.013153869684918936, 'mean_word_length': 2.8335287221570926, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 8, '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': '1825594', 'n_tokens_mistral': 1261, 'n_tokens_neox': 1185, 'n_words': 421}