<commit_before>package hageldave.imagingkit.filter;

import static hageldave.imagingkit.core.Pixel.*;

import hageldave.imagingkit.core.Img;

public class Blend {
	
	public static interface BlendFunction {
		public int blend(int bottom, int top);
	}
	
	public static enum BlendMode {
		NORMAL(		(a,b) -> b ),
		AVERAGE( 	(a,b) -> ((a+b)>>1) ),
		MULTIPLY( 	(a,b) -> ((a*b)>>8) ),
		SCREEN( 	(a,b) -> (0xff - ((0xff-a) * (0xff-b)>>8)) ),
		DARKEN( 	(a,b) -> Math.min(a, b) ),
		BRIGHTEN(	(a,b) -> Math.max(a, b) ),
		DIFFERENCE( (a,b) -> Math.abs(a-b) ),
		ADDITION(	(a,b) -> Math.min(a+b, 0xff) ),
		SUBTRACTION((a,b) -> Math.max(a+b-0xff, 0) ),
		REFLECT(	(a,b) -> Math.min(a*a / Math.max(0xff-b, 1), 0xff) ),
		OVERLAY(	(a,b) -> a < 128 ? (a*b)>>7 : 0xff-(((0xff-a)*(0xff-b))>>7) ),
		HARDLIGHT(	(a,b) -> b < 128 ? (a*b)>>7 : 0xff-(((0xff-a)*(0xff-b))>>7) ),
		SOFTLIGHT(	(a,b) -> {int c=(a*b)>>8; return c + (a*(0xff-(((0xff-a)*(0xff-b)) >> 8)-c) >> 8);} ),
		DODGE(		(a,b) -> Math.min((a<<8)/Math.max(0xff-b, 1),0xff) );
		
		public final BlendFunction blendFunction;
		
		private BlendMode(BlendFunction func) {
			this.blendFunction = func;
		}
	}

	public static int blend(int bottomRGBA, int topRGBA, float visibility, BlendFunction func){
		int temp = 0;
		float a = visibility*func.blend(temp=a(bottomRGBA), a(topRGBA)) + temp*(1-visibility);
		visibility = Math.max(visibility-(1-(a(topRGBA)/255.0f)), 0);
		float oneMinusVis = 1-visibility;
		float r = visibility*func.blend(temp=r(bottomRGBA), r(topRGBA)) + temp*oneMinusVis;
		float g = visibility*func.blend(temp=g(bottomRGBA), g(topRGBA)) + temp*oneMinusVis;
		float b = visibility*func.blend(temp=b(bottomRGBA), b(topRGBA)) + temp*oneMinusVis;
		return argb_fast((int)a, (int)r, (int)g, (int)b);
	}
	
	public static int blend(int bottomRGBA, int topRGBA, float visibility, BlendMode mode){
		return blend(bottomRGBA, topRGBA, visibility, mode.blendFunction);<commit_msg>fixes bad blending with alpha channels (e.g. DIFFERENCE would lead to 0 alpha)<commit_after>package hageldave.imagingkit.filter;

import static hageldave.imagingkit.core.Pixel.*;

import hageldave.imagingkit.core.Img;

public class Blend {
	
	public static interface BlendFunction {
		public int blend(int bottom, int top);
	}
	
	public static enum BlendMode {
		NORMAL(		(a,b) -> b ),
		AVERAGE( 	(a,b) -> ((a+b)>>1) ),
		MULTIPLY( 	(a,b) -> ((a*b)>>8) ),
		SCREEN( 	(a,b) -> (0xff - ((0xff-a) * (0xff-b)>>8)) ),
		DARKEN( 	(a,b) -> Math.min(a, b) ),
		BRIGHTEN(	(a,b) -> Math.max(a, b) ),
		DIFFERENCE( (a,b) -> Math.abs(a-b) ),
		ADDITION(	(a,b) -> Math.min(a+b, 0xff) ),
		SUBTRACTION((a,b) -> Math.max(a+b-0xff, 0) ),
		REFLECT(	(a,b) -> Math.min(a*a / Math.max(0xff-b, 1), 0xff) ),
		OVERLAY(	(a,b) -> a < 128 ? (a*b)>>7 : 0xff-(((0xff-a)*(0xff-b))>>7) ),
		HARDLIGHT(	(a,b) -> b < 128 ? (a*b)>>7 : 0xff-(((0xff-a)*(0xff-b))>>7) ),
		SOFTLIGHT(	(a,b) -> {int c=(a*b)>>8; return c + (a*(0xff-(((0xff-a)*(0xff-b)) >> 8)-c) >> 8);} ),
		DODGE(		(a,b) -> Math.min((a<<8)/Math.max(0xff-b, 1),0xff) );
		
		public final BlendFunction blendFunction;
		
		private BlendMode(BlendFunction func) {
			this.blendFunction = func;
		}
	}

	public static int blend(int bottomRGBA, int topRGBA, float visibility, BlendFunction func){
		int temp = 0;
		float a = Math.min(visibility*(temp=a(topRGBA)) + a(bottomRGBA),0xff);
		visibility = Math.max(visibility-(1-(temp/255.0f)), 0);
		float oneMinusVis = 1-visibility;
		float r = visibility*func.blend(temp=r(bottomRGBA), r(topRGBA)) + temp*oneMinusVis;
		float g = visibility*func.blend(temp=g(bottomRGBA), g(topRGBA)) + temp*oneMinusVis;
		float b = visibility*func.blend(temp=b(bottomRGBA), b(topRGBA)) + temp*oneMinusVis;
		return argb_fast((int)a, (int)r, (int)g, (int)b);
	}
	
	public static int blend(int bottomRGBA, int topRGBA, float visibility, BlendMode mode){
		return blend(bottomRGBA, topRGBA, visibility, mode.blendFunction);
{'fraction_non_alphanumeric': 0.21036507531273935, 'fraction_numerical': 0.024253255042124073, 'mean_word_length': 4.259060402684564, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 71, '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': '1116999', 'n_tokens_mistral': 1825, 'n_tokens_neox': 1677, 'n_words': 324}