<commit_before>/*
  PUBLIC DOMAIN STATEMENT
  To the extent possible under law, <NAME> has waived all copyright
  and related or neighboring rights to this Source Code file.
  This work is published from the United Kingdom.
*/

// Crops an image to its most interesting area
package salience

import (
	"fmt"
	"image"
	"image/color"
	"math"
)

type Section struct {
	x, y int
	e    float64
}

// Crops an image to its most interesting area with the specified extents
func Crop(img image.Image, cropWidth, cropHeight int) image.Image {
	r := img.Bounds()
	imageWidth := r.Max.X - r.Min.X
	imageHeight := r.Max.Y - r.Min.Y

	x, y := 0, 0
	sliceStep := imageWidth / 8
	if imageHeight/8 < sliceStep {
		sliceStep = imageHeight / 8
	}
	bestSection := Section{0, 0, 0.0}

	for x = 0; x < imageWidth-cropWidth; x += sliceStep {
		for y = 0; y < imageHeight-cropHeight; y += sliceStep {
			e := entropy(img, image.Rect(x, y, x+cropWidth, y+cropHeight))

			if e > bestSection.e {
				bestSection.e = e
				bestSection.x = x
				bestSection.y = y
			}
		}
	}

	return crop(img, image.Rect(bestSection.x, bestSection.y, bestSection.x+cropWidth, bestSection.y+cropHeight))
}

func crop(img image.Image, r image.Rectangle) image.Image {
	cropped := image.NewRGBA(r)
	for x := r.Min.X; x < r.Max.X; x++ {
		for y := r.Min.Y; y < r.Max.Y; y++ {
			cropped.Set(x, y, img.At(x, y))
		}
	}
	return cropped
}

// Calculate the entropy of a portion of an image
// From http://www.astro.cornell.edu/research/projects/compression/entropy.html
func entropy(img image.Image, r image.Rectangle) float64 {
	arraySize := 256*2 - 1
	freq := make([]float64, arraySize)

	for x := r.Min.X; x < r.Max.X-1; x++ {
		for y := r.Min.Y; y < r.Max.Y; y++ {
			diff := greyvalue(img.At(x, y)) - greyvalue(img.At(x+1, y))
			if -(arraySize+1)/2 < diff && diff < (arraySize+1)/2 {
				freq[diff+(arraySize-1)/2] += 1
			}
		}
	}

	n := 0.0
	for _, v := range freq {
		n += v
	}

	e := 0.0
	for i := 0; i < len(freq); i++ {
		freq[i] = freq[i] / n
		if freq[i] != 0.0 {
			e -= freq[i] * math.Log2(freq[i])
		}
	}

	fmt.Printf("Entropy of (%d, %d) (%d, %d) is %0.2f\n", r.Min.X, r.Min.Y, r.Max.X, r.Max.Y, e)

	return e

}

func greyvalue(c color.Color) int {
	r, g, b, _ := c.RGBA()
	return int((r*299 + g*587 + b*114) / 1000)
}<commit_msg>Removed debugging messages, D'oh\!<commit_after>/*
  PUBLIC DOMAIN STATEMENT
  To the extent possible under law, <NAME> has waived all copyright
  and related or neighboring rights to this Source Code file.
  This work is published from the United Kingdom.
*/

// Crops an image to its most interesting area
package salience

import (
	"image"
	"image/color"
	"math"
)

type Section struct {
	x, y int
	e    float64
}

// Crops an image to its most interesting area with the specified extents
func Crop(img image.Image, cropWidth, cropHeight int) image.Image {
	r := img.Bounds()
	imageWidth := r.Max.X - r.Min.X
	imageHeight := r.Max.Y - r.Min.Y

	x, y := 0, 0
	sliceStep := imageWidth / 8
	if imageHeight/8 < sliceStep {
		sliceStep = imageHeight / 8
	}
	bestSection := Section{0, 0, 0.0}

	for x = 0; x < imageWidth-cropWidth; x += sliceStep {
		for y = 0; y < imageHeight-cropHeight; y += sliceStep {
			e := entropy(img, image.Rect(x, y, x+cropWidth, y+cropHeight))

			if e > bestSection.e {
				bestSection.e = e
				bestSection.x = x
				bestSection.y = y
			}
		}
	}

	return crop(img, image.Rect(bestSection.x, bestSection.y, bestSection.x+cropWidth, bestSection.y+cropHeight))
}

func crop(img image.Image, r image.Rectangle) image.Image {
	cropped := image.NewRGBA(r)
	for x := r.Min.X; x < r.Max.X; x++ {
		for y := r.Min.Y; y < r.Max.Y; y++ {
			cropped.Set(x, y, img.At(x, y))
		}
	}
	return cropped
}

// Calculate the entropy of a portion of an image
// From http://www.astro.cornell.edu/research/projects/compression/entropy.html
func entropy(img image.Image, r image.Rectangle) float64 {
	arraySize := 256*2 - 1
	freq := make([]float64, arraySize)

	for x := r.Min.X; x < r.Max.X-1; x++ {
		for y := r.Min.Y; y < r.Max.Y; y++ {
			diff := greyvalue(img.At(x, y)) - greyvalue(img.At(x+1, y))
			if -(arraySize+1)/2 < diff && diff < (arraySize+1)/2 {
				freq[diff+(arraySize-1)/2] += 1
			}
		}
	}

	n := 0.0
	for _, v := range freq {
		n += v
	}

	e := 0.0
	for i := 0; i < len(freq); i++ {
		freq[i] = freq[i] / n
		if freq[i] != 0.0 {
			e -= freq[i] * math.Log2(freq[i])
		}
	}

	return e

}

func greyvalue(c color.Color) int {
	r, g, b, _ := c.RGBA()
	return int((r*299 + g*587 + b*114) / 1000)
}
{'fraction_non_alphanumeric': 0.16257465162574652, 'fraction_numerical': 0.023446140234461402, 'mean_word_length': 2.9083837510803803, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '4684770', 'n_tokens_mistral': 1984, 'n_tokens_neox': 1811, 'n_words': 511}