<commit_before>/* This file is part of magic-sdk, an sdk for the open source programming language magic.
 *
 * Copyright (C) 2016 magic-lang
 *
 * This software may be modified and distributed under the terms
 * of the MIT license.  See the LICENSE file for details.
 */

use base
use geometry

ColorMonochrome: cover {
	y: Byte
	normalized ::= this y as Float / 255
	black ::= static This new(0)
	white ::= static This new(255)

	init: func@ (=y)
	init: func@ ~default { this init(0) }
	toUv: func -> ColorUv { ColorUv new(128, 128) }
	toYuv: func -> ColorYuv { ColorYuv new(this y, 128, 128) }
	toYuva: func -> ColorYuva { ColorYuva new(this y, 128, 128, 255) }
	toRgb: func -> ColorRgb { this toYuv() toRgb() }
	toRgba: func -> ColorRgba { this toYuv() toRgba() }
	equals: func (other: This) -> Bool { this y == other y }
	mix: static func (a, b: This, ratio: Float) -> This { This new(Float mix(a y, b y, ratio) as Byte) }
	mix: static func ~bilinear (ratio: FloatPoint2D, topLeft, topRight, bottomLeft, bottomRight: This) -> This {
		This new((Float mix(Float mix(topLeft y as Float, topRight y as Float, ratio x), Float mix(bottomLeft y as Float, bottomRight y as Float, ratio x), ratio y) + 0.5f) clamp(0.0f, 255.0f) as Byte)
	}
	distance: func (other: This) -> Float { (this y - other y) as Float abs() }
	operator == (other: This) -> Bool { this equals(other) }
	operator != (other: This) -> Bool { !this equals(other) }
}

ColorUv: cover {
	u, v: Byte
	normalized ::= FloatTuple2 new(this u as Float / 255, this v as Float / 255)
	black ::= static This new(128, 128)
	white ::= static This new(128, 128)
	red ::= static This new(84, 255)
	green ::= static This new(43, 21)
	blue ::= static This new(255, 107)

	init: func@ (=u, =v)
	init: func@ ~default { this init(127, 127) }
	toMonochrome: func -> ColorMonochrome { ColorMonochrome new() }
	toYuv: func -> ColorYuv { ColorYuv new(128, this u, this v) }
	toYuva: func -> ColorYuva { ColorYuva new(128, this u, this v, 255) }
	toRgb: func -> ColorRgb { ColorConvert yuvToRgb(this toYuv()) }
	toRgba: func -> ColorRgba { this toYuv() toRgb() toRgba() }
	equals: func (other: This) -> Bool { this u == other u && this v == other v }
	mix: static func (a, b: This, ratio: Float) -> This { This new(Float mix(a u, b u, ratio) as Byte, Float mix(a v, b v, ratio) as Byte) }
	mix: static func ~bilinear (ratio: FloatPoint2D, topLeft, topRight, bottomLeft, bottomRight: This) -> This {
		result: This
		result u = (Float mix(Float mix(topLeft u as Float, topRight u as Float, ratio x), Float mix(bottomLeft u as Float, bottomRight u as Float, ratio x), ratio y) + 0.5f) clamp(0.0f, 255.0f) as Byte
		result v = (Float mix(Float mix(topLeft v as Float, topRight v as Float, ratio x), Float mix(bottomLeft v as Float, bottomRight v as Float, ratio x), ratio y) + 0.5f) clamp(0.0f, 255.0f) as Byte
		result
	}
	distance: func (other: This) -> Float { ((this u - other u) as Float pow(2) + (this v - other v) as Float pow(2)) / 2.0f sqrt() }
	operator == (other: This) -> Bool { this equals(other) }
	operator != (other: This) -> Bool { !this equals(other) }
}

ColorYuv: cover {
	y, u, v: Byte
	normalized ::= FloatTuple3 new(this y as Float / 255, this u as Float / 255, this v as Float / 255)
	black ::= static This new(0, 128, 128)
	white ::= static This new(255, 128, 128)
	red ::= static This new(76, 84, 255)
	green ::= static This new(149, 43, 21)
	blue ::= static This new(29, 255, 107)

	init: func@ (=y, =u, =v)
	init: func@ ~default { this init(0, 127, 127) }
	toMonochrome: func -> ColorMonochrome { ColorMonochrome new(this y) }
	toUv: func -> ColorUv { ColorUv new(this u, this v) }
	toYuva: func -> ColorYuva { ColorYuva new(this, 255) }
	toRgb: func -> ColorRgb { ColorConvert yuvToRgb(this) }
	toRgba: func -> ColorRgba { this toRgb() toRgba() }
	equals: func (other: This) -> Bool { this y == other y && this u == other u && this v == other v }
	mix: static func (a, b: This, ratio: Float) -> This {
		This new(Float mix(a y, b y, ratio) as Byte, Float mix(a u, b u, ratio), Float mix(a v, b v, ratio) as Byte)
	}
	distance: func (other: This) -> Float {
		((this y - other y) as Float pow(2) + (this u - other u) as Float pow(2) + (this v - other v) as Float pow(2)) / 3.0f sqrt()
	}
	operator == (other: This) -> Bool { this equals(other) }
	operator != (other: This) -> Bool { !this equals(other) }
}

ColorYuva: cover {
	y, u, v, a: Byte
	normalized ::= FloatTuple4 new(this y as Float / 255, this u as Float / 255, this v as Float / 255, this a as Float / 255)
	black ::= static This new(0, 128, 128, 255)
	transparent ::= static This new(0, 128, 128, 0)
	white ::= static This new(255, 128, 128, 255)
	red ::= static This new(76, 84, 255, 255)
	green ::= static This new(149, 43, 21, 255)
	blue ::= static This new(29, 255, 107, 255)

	init: func@ (=y, =u, =v, =a)
	init: func@ ~default { this init(0, 0, 0, 255) }
	init: func@ ~yuv (yuv: ColorYuv, a: Byte) { this init(yuv y, yuv u, yuv v, a) }
	toMonochrome: func -> ColorMonochrome { ColorMonochrome new(this y) }
	toUv: func -> ColorUv { this toYuv() toUv() }
	toYuv: func -> ColorYuv { ColorYuv new(this y, this u, this v) }
	toRgb: func -> ColorRgb { this toYuv() toRgb() }
	toRgba: func -> ColorRgba { ColorRgba new(this toRgb(), this a) }
	equals: func (other: This) -> Bool { this y == other y && this u == other u && this v == other v && this a == other a }
	mix: static func (a, b: This, ratio: Float) -> This {
		This new(Float mix(a y, b y, ratio) as Byte, Float mix(a u, b u, ratio) as Byte, Float mix(a v, b v, ratio) as Byte, Float mix(a a, b a, ratio) as Byte)
	}
	operator == (other: This) -> Bool { this equals(other) }
	operator != (other: This) -> Bool { !this equals(other) }
}

ColorRgb: cover {
	r, g, b: Byte
	normalized ::= FloatTuple3 new(this r as Float / 255, this g as Float / 255, this b as Float / 255)
	black ::= static This new(0, 0, 0)
	white ::= static This new(255, 255, 255)
	red ::= static This new(255, 0, 0)
	green ::= static This new(0, 255, 0)
	blue ::= static This new(0, 0, 255)

	init: func@ (=r, =g, =b)
	init: func@ ~default { this init(0, 0, 0) }
	toMonochrome: func -> ColorMonochrome { ColorMonochrome new(this toYuv() y) }
	toUv: func -> ColorUv { this toYuv() toUv() }
	toYuv: func -> ColorYuv { ColorConvert rgbToYuv(this) }
	toYuva: func -> ColorYuva { ColorYuva new(this toYuv(), 255) }
	toRgba: func -> ColorRgba { ColorRgba new(this, 255) }
	equals: func (other: This) -> Bool { this r == other r && this g == other g && this b == other b }
	mix: static func (a, b: This, ratio: Float) -> This {
		This new(Float mix(a r, b r, ratio) as Byte, Float mix(a g, b g, ratio) as Byte, Float mix(a b, b b, ratio) as Byte)
	}
	distance: func (other: This) -> Float {
		((this r - other r) as Float pow(2) + (this g - other g) as Float pow(2) + (this b - other b) as Float pow(2)) / 3.0f sqrt()
	}
	operator == (other: This) -> Bool { this equals(other) }
	operator != (other: This) -> Bool { !this equals(other) }
}

ColorRgba: cover {
	r, g, b, a: Byte
	normalized ::= FloatTuple4 new(this r as Float / 255, this g as Float / 255, this b as Float / 255, this a as Float / 255)
	black ::= static This new(0, 0, 0, 255)
	transparent ::= static This new(0, 0, 0, 0)
	white ::= static This new(255, 255, 255, 255)
	red ::= static This new(255, 0, 0, 255)
	green ::= static This new(0, 255, 0, 255)
	blue ::= static This new(0, 0, 255, 255)

	init: func@ (=r, =g, =b, =a)
	init: func@ ~default { this init(0, 0, 0, 255) }
	init: func@ ~rgb (rgb: ColorRgb, a: Byte) { this init(rgb r, rgb g, rgb b, a) }
	toMonochrome: func -> ColorMonochrome { this toRgb() toMonochrome() }
	toUv: func -> ColorUv { this toYuv() toUv() }
	toYuv: func -> ColorYuv { this toRgb() toYuv() }
	toYuva: func -> ColorYuva { ColorYuva new(this toRgb() toYuv(), this a) }
	toRgb: func -> ColorRgb { ColorRgb new(this r, this g, this b) }
	equals: func (other: This) -> Bool { this r == other r && this g == other g && this b == other b && this a == other a }
	mix: static func (a, b: This, ratio: Float) -> This {
		This new(Float mix(a r, b r, ratio) as Byte, Float mix(a g, b g, ratio) as Byte, Float mix(a b, b b, ratio) as Byte, Float mix(a a, b a, ratio) as Byte)
	}
	distance: func (other: This) -> Float { (this toRgb() distance(other toRgb()) * 3.0f + (this a - other a) as Float pow(2)) / 4.0f sqrt() }
	operator == (other: This) -> Bool { this equals(other) }
	operator != (other: This) -> Bool { !this equals(other) }

	fromString: static func (string: String) -> This {
		channels := string split(',')
		result: This
		match (channels count) {
			case 1 => // Y
				luma := channels[0] toInt()
				result = This new(ColorConvert monochromeToRgb(ColorMonochrome new(luma)), 255)
			case 2 => // YA
				luma := channels[0] toInt()
				alpha := channels[1] toInt()
				result = This new(ColorConvert monochromeToRgb(ColorMonochrome new(luma)), alpha)
			case 3 => // RGB
				red := channels[0] toInt()
				green := channels[1] toInt()
				blue := channels[2] toInt()
				result = This new(red, green, blue, 255)
			case 4 => // RGBA
				red := channels[0] toInt()
				green := channels[1] toInt()
				blue := channels[2] toInt()
				alpha := channels[3] toInt()
				result = This new(red, green, blue, alpha)
		}<commit_msg>Color distances are now Euclidean<commit_after>/* This file is part of magic-sdk, an sdk for the open source programming language magic.
 *
 * Copyright (C) 2016 magic-lang
 *
 * This software may be modified and distributed under the terms
 * of the MIT license.  See the LICENSE file for details.
 */

use base
use geometry

ColorMonochrome: cover {
	y: Byte
	normalized ::= this y as Float / 255
	black ::= static This new(0)
	white ::= static This new(255)

	init: func@ (=y)
	init: func@ ~default { this init(0) }
	toUv: func -> ColorUv { ColorUv new(128, 128) }
	toYuv: func -> ColorYuv { ColorYuv new(this y, 128, 128) }
	toYuva: func -> ColorYuva { ColorYuva new(this y, 128, 128, 255) }
	toRgb: func -> ColorRgb { this toYuv() toRgb() }
	toRgba: func -> ColorRgba { this toYuv() toRgba() }
	equals: func (other: This) -> Bool { this y == other y }
	mix: static func (a, b: This, ratio: Float) -> This { This new(Float mix(a y, b y, ratio) as Byte) }
	mix: static func ~bilinear (ratio: FloatPoint2D, topLeft, topRight, bottomLeft, bottomRight: This) -> This {
		This new((Float mix(Float mix(topLeft y as Float, topRight y as Float, ratio x), Float mix(bottomLeft y as Float, bottomRight y as Float, ratio x), ratio y) + 0.5f) clamp(0.0f, 255.0f) as Byte)
	}
	distance: func (other: This) -> Float { (this y - other y) as Float abs() }
	operator == (other: This) -> Bool { this equals(other) }
	operator != (other: This) -> Bool { !this equals(other) }
}

ColorUv: cover {
	u, v: Byte
	normalized ::= FloatTuple2 new(this u as Float / 255, this v as Float / 255)
	black ::= static This new(128, 128)
	white ::= static This new(128, 128)
	red ::= static This new(84, 255)
	green ::= static This new(43, 21)
	blue ::= static This new(255, 107)

	init: func@ (=u, =v)
	init: func@ ~default { this init(127, 127) }
	toMonochrome: func -> ColorMonochrome { ColorMonochrome new() }
	toYuv: func -> ColorYuv { ColorYuv new(128, this u, this v) }
	toYuva: func -> ColorYuva { ColorYuva new(128, this u, this v, 255) }
	toRgb: func -> ColorRgb { ColorConvert yuvToRgb(this toYuv()) }
	toRgba: func -> ColorRgba { this toYuv() toRgb() toRgba() }
	equals: func (other: This) -> Bool { this u == other u && this v == other v }
	mix: static func (a, b: This, ratio: Float) -> This { This new(Float mix(a u, b u, ratio) as Byte, Float mix(a v, b v, ratio) as Byte) }
	mix: static func ~bilinear (ratio: FloatPoint2D, topLeft, topRight, bottomLeft, bottomRight: This) -> This {
		result: This
		result u = (Float mix(Float mix(topLeft u as Float, topRight u as Float, ratio x), Float mix(bottomLeft u as Float, bottomRight u as Float, ratio x), ratio y) + 0.5f) clamp(0.0f, 255.0f) as Byte
		result v = (Float mix(Float mix(topLeft v as Float, topRight v as Float, ratio x), Float mix(bottomLeft v as Float, bottomRight v as Float, ratio x), ratio y) + 0.5f) clamp(0.0f, 255.0f) as Byte
		result
	}
	distance: func (other: This) -> Float { ((this u - other u) as Float pow(2) + (this v - other v) as Float pow(2)) sqrt() }
	operator == (other: This) -> Bool { this equals(other) }
	operator != (other: This) -> Bool { !this equals(other) }
}

ColorYuv: cover {
	y, u, v: Byte
	normalized ::= FloatTuple3 new(this y as Float / 255, this u as Float / 255, this v as Float / 255)
	black ::= static This new(0, 128, 128)
	white ::= static This new(255, 128, 128)
	red ::= static This new(76, 84, 255)
	green ::= static This new(149, 43, 21)
	blue ::= static This new(29, 255, 107)

	init: func@ (=y, =u, =v)
	init: func@ ~default { this init(0, 127, 127) }
	toMonochrome: func -> ColorMonochrome { ColorMonochrome new(this y) }
	toUv: func -> ColorUv { ColorUv new(this u, this v) }
	toYuva: func -> ColorYuva { ColorYuva new(this, 255) }
	toRgb: func -> ColorRgb { ColorConvert yuvToRgb(this) }
	toRgba: func -> ColorRgba { this toRgb() toRgba() }
	equals: func (other: This) -> Bool { this y == other y && this u == other u && this v == other v }
	mix: static func (a, b: This, ratio: Float) -> This {
		This new(Float mix(a y, b y, ratio) as Byte, Float mix(a u, b u, ratio), Float mix(a v, b v, ratio) as Byte)
	}
	distance: func (other: This) -> Float {
		((this y - other y) as Float pow(2) + (this u - other u) as Float pow(2) + (this v - other v) as Float pow(2)) sqrt()
	}
	operator == (other: This) -> Bool { this equals(other) }
	operator != (other: This) -> Bool { !this equals(other) }
}

ColorYuva: cover {
	y, u, v, a: Byte
	normalized ::= FloatTuple4 new(this y as Float / 255, this u as Float / 255, this v as Float / 255, this a as Float / 255)
	black ::= static This new(0, 128, 128, 255)
	transparent ::= static This new(0, 128, 128, 0)
	white ::= static This new(255, 128, 128, 255)
	red ::= static This new(76, 84, 255, 255)
	green ::= static This new(149, 43, 21, 255)
	blue ::= static This new(29, 255, 107, 255)

	init: func@ (=y, =u, =v, =a)
	init: func@ ~default { this init(0, 0, 0, 255) }
	init: func@ ~yuv (yuv: ColorYuv, a: Byte) { this init(yuv y, yuv u, yuv v, a) }
	toMonochrome: func -> ColorMonochrome { ColorMonochrome new(this y) }
	toUv: func -> ColorUv { this toYuv() toUv() }
	toYuv: func -> ColorYuv { ColorYuv new(this y, this u, this v) }
	toRgb: func -> ColorRgb { this toYuv() toRgb() }
	toRgba: func -> ColorRgba { ColorRgba new(this toRgb(), this a) }
	equals: func (other: This) -> Bool { this y == other y && this u == other u && this v == other v && this a == other a }
	mix: static func (a, b: This, ratio: Float) -> This {
		This new(Float mix(a y, b y, ratio) as Byte, Float mix(a u, b u, ratio) as Byte, Float mix(a v, b v, ratio) as Byte, Float mix(a a, b a, ratio) as Byte)
	}
	distance: func (other: This) -> Float { ((this toYuv() distance(other toYuv()) as Float pow(2) * 3.0f + (this a - other a) as Float pow(2)) / 4.0f) sqrt() }
	operator == (other: This) -> Bool { this equals(other) }
	operator != (other: This) -> Bool { !this equals(other) }
}

ColorRgb: cover {
	r, g, b: Byte
	normalized ::= FloatTuple3 new(this r as Float / 255, this g as Float / 255, this b as Float / 255)
	black ::= static This new(0, 0, 0)
	white ::= static This new(255, 255, 255)
	red ::= static This new(255, 0, 0)
	green ::= static This new(0, 255, 0)
	blue ::= static This new(0, 0, 255)

	init: func@ (=r, =g, =b)
	init: func@ ~default { this init(0, 0, 0) }
	toMonochrome: func -> ColorMonochrome { ColorMonochrome new(this toYuv() y) }
	toUv: func -> ColorUv { this toYuv() toUv() }
	toYuv: func -> ColorYuv { ColorConvert rgbToYuv(this) }
	toYuva: func -> ColorYuva { ColorYuva new(this toYuv(), 255) }
	toRgba: func -> ColorRgba { ColorRgba new(this, 255) }
	equals: func (other: This) -> Bool { this r == other r && this g == other g && this b == other b }
	mix: static func (a, b: This, ratio: Float) -> This {
		This new(Float mix(a r, b r, ratio) as Byte, Float mix(a g, b g, ratio) as Byte, Float mix(a b, b b, ratio) as Byte)
	}
	distance: func (other: This) -> Float {
		((this r - other r) as Float pow(2) + (this g - other g) as Float pow(2) + (this b - other b) as Float pow(2)) sqrt()
	}
	operator == (other: This) -> Bool { this equals(other) }
	operator != (other: This) -> Bool { !this equals(other) }
}

ColorRgba: cover {
	r, g, b, a: Byte
	normalized ::= FloatTuple4 new(this r as Float / 255, this g as Float / 255, this b as Float / 255, this a as Float / 255)
	black ::= static This new(0, 0, 0, 255)
	transparent ::= static This new(0, 0, 0, 0)
	white ::= static This new(255, 255, 255, 255)
	red ::= static This new(255, 0, 0, 255)
	green ::= static This new(0, 255, 0, 255)
	blue ::= static This new(0, 0, 255, 255)

	init: func@ (=r, =g, =b, =a)
	init: func@ ~default { this init(0, 0, 0, 255) }
	init: func@ ~rgb (rgb: ColorRgb, a: Byte) { this init(rgb r, rgb g, rgb b, a) }
	toMonochrome: func -> ColorMonochrome { this toRgb() toMonochrome() }
	toUv: func -> ColorUv { this toYuv() toUv() }
	toYuv: func -> ColorYuv { this toRgb() toYuv() }
	toYuva: func -> ColorYuva { ColorYuva new(this toRgb() toYuv(), this a) }
	toRgb: func -> ColorRgb { ColorRgb new(this r, this g, this b) }
	equals: func (other: This) -> Bool { this r == other r && this g == other g && this b == other b && this a == other a }
	mix: static func (a, b: This, ratio: Float) -> This {
		This new(Float mix(a r, b r, ratio) as Byte, Float mix(a g, b g, ratio) as Byte, Float mix(a b, b b, ratio) as Byte, Float mix(a a, b a, ratio) as Byte)
	}
	distance: func (other: This) -> Float { ((this toRgb() distance(other toRgb()) as Float pow(2) * 3.0f + (this a - other a) as Float pow(2)) / 4.0f) sqrt() }
	operator == (other: This) -> Bool { this equals(other) }
	operator != (other: This) -> Bool { !this equals(other) }

	fromString: static func (string: String) -> This {
		channels := string split(',')
		result: This
		match (channels count) {
			case 1 => // Y
				luma := channels[0] toInt()
				result = This new(ColorConvert monochromeToRgb(ColorMonochrome new(luma)), 255)
			case 2 => // YA
				luma := channels[0] toInt()
				alpha := channels[1] toInt()
				result = This new(ColorConvert monochromeToRgb(ColorMonochrome new(luma)), alpha)
			case 3 => // RGB
				red := channels[0] toInt()
				green := channels[1] toInt()
				blue := channels[2] toInt()
				result = This new(red, green, blue, 255)
			case 4 => // RGBA
				red := channels[0] toInt()
				green := channels[1] toInt()
				blue := channels[2] toInt()
				alpha := channels[3] toInt()
				result = This new(red, green, blue, alpha)
		}
{'fraction_non_alphanumeric': 0.15770647589557418, 'fraction_numerical': 0.04233623405050451, 'mean_word_length': 3.514822848879248, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 136, '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': '5404278', 'n_tokens_mistral': 7812, 'n_tokens_neox': 6925, 'n_words': 2692}