<commit_before>package main

import (
	"bytes"
	"github.com/nfnt/resize"
	"github.com/oliamb/cutter"
	"image"
	"image/gif"
	"image/jpeg"
	"image/png"
	"io"
	"log"
)

func min(x, y int) int {
	if x <= y {
		return x
	}
	return y
}

func max(x, y int) int {
	if x >= y {
		return x
	}
	return y
}

type Avatar struct {
	size int
	data []byte
	// below are used in header fields
	cacheControl string
	lastModified string
}

func avatar2Image(avatar *Avatar) (img image.Image, format string, err error) {
	return image.Decode(bytes.NewBuffer(avatar.data))
}

// alters the avatar instance!
func image2Avatar(avatar *Avatar, img image.Image, format string) {
	b := new(bytes.Buffer)
	switch format {
	case "jpeg":
		jpeg.Encode(b, img, nil)
	case "gif":
		gif.Encode(b, img, nil)
	case "png":
		png.Encode(b, img)
	}
	avatar.data = b.Bytes()
}

// scales the avatar (altering it!)
func scale(avatar *Avatar, size int) error {
	img, format, err := avatar2Image(avatar)
	if err != nil {
		return err
	}
	actualSize := img.Bounds().Dx() // assume square
	if size == actualSize {
		return nil
	}
	log.Printf("Resizing img from %vx%v to %vx%v", actualSize, actualSize, size, size)
	resized := resize.Resize(uint(size), uint(size), img, resize.Bicubic)
	image2Avatar(avatar, resized, format)
	return nil
}

func cropAndScale(avatar *Avatar) error {
	img, format, err := avatar2Image(avatar)
	if err != nil {
		return err
	}
	x := img.Bounds().Dx()
	y := img.Bounds().Dy()
	size := min(x, y)
	if x != y {
		log.Printf("Cropping img from %vx%v to %vx%v", x, y, size, size)<commit_msg>Always rewrite (scale) images when downloaded, even if the size is already correct. This fixes #1. Most of the time the requested size is anyway different so this shouldn't generally have much impact. In combination with the planned caching the effect will be even smaller.<commit_after>package main

import (
	"bytes"
	"github.com/nfnt/resize"
	"github.com/oliamb/cutter"
	"image"
	"image/gif"
	"image/jpeg"
	"image/png"
	"io"
	"log"
)

func min(x, y int) int {
	if x <= y {
		return x
	}
	return y
}

func max(x, y int) int {
	if x >= y {
		return x
	}
	return y
}

type Avatar struct {
	size int
	data []byte
	// below are used in header fields
	cacheControl string
	lastModified string
}

func avatar2Image(avatar *Avatar) (img image.Image, format string, err error) {
	return image.Decode(bytes.NewBuffer(avatar.data))
}

// alters the avatar instance!
func image2Avatar(avatar *Avatar, img image.Image, format string) {
	b := new(bytes.Buffer)
	switch format {
	case "jpeg":
		jpeg.Encode(b, img, nil)
	case "gif":
		gif.Encode(b, img, nil)
	case "png":
		png.Encode(b, img)
	}
	avatar.data = b.Bytes()
}

// scales the avatar (altering it!)
func scale(avatar *Avatar, size int) error {
	img, format, err := avatar2Image(avatar)
	if err != nil {
		return err
	}
	actualSize := img.Bounds().Dx() // assume square
	log.Printf("Resizing img from %vx%v to %vx%v", actualSize, actualSize, size, size)
	resized := resize.Resize(uint(size), uint(size), img, resize.Bicubic)
	image2Avatar(avatar, resized, format)
	return nil
}

func cropAndScale(avatar *Avatar) error {
	img, format, err := avatar2Image(avatar)
	if err != nil {
		return err
	}
	x := img.Bounds().Dx()
	y := img.Bounds().Dy()
	size := min(x, y)
	if x != y {
		log.Printf("Cropping img from %vx%v to %vx%v", x, y, size, size)
{'fraction_non_alphanumeric': 0.14132698601606664, 'fraction_numerical': 0.0032728354656352274, 'mean_word_length': 3.796005706134094, 'pattern_counts': {'":': 6, '<': 5, '<?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': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1390174', 'n_tokens_mistral': 1321, 'n_tokens_neox': 1270, 'n_words': 392}