Example #1
0
static void psd_hue_saturation_proc(psd_uint layer_info_data, psd_int * red, psd_int * green, psd_int * blue)
{
	psd_layer_hue_saturation * data = (psd_layer_hue_saturation *)layer_info_data;
	psd_int src_hue, src_saturation, src_lightness;
	psd_int dst_hue, dst_saturation, dst_lightness;
	psd_int i, opacity;

	psd_rgb_to_inthsb(*red, *green, *blue, &src_hue, &src_saturation, &src_lightness);
	
	dst_hue = data->master_hue;
	dst_saturation = data->master_saturation;
	dst_lightness = data->master_lightness;
	for(i = 0; i < 6; i ++)
	{
		opacity = data->lookup_table[i][src_hue];
		if(opacity > 0)
		{
			dst_hue += data->setting_values[i][0] * opacity / 255;
			dst_saturation += data->setting_values[i][1] * opacity / 255;
			dst_lightness += data->setting_values[i][2] * opacity / 255;
		}
	}

	if(dst_hue != 0 || dst_saturation != 0 || dst_lightness != 0)
	{
		dst_hue = (src_hue + dst_hue + 2160) % 360;
		dst_saturation = src_saturation + src_saturation * PSD_CONSTRAIN(dst_saturation, -100, 100) / 100;
		dst_saturation = PSD_CONSTRAIN(dst_saturation, 0, 255);
		dst_lightness = src_lightness + src_lightness * PSD_CONSTRAIN(dst_lightness, -100, 100) / 100;
		dst_lightness = PSD_CONSTRAIN(dst_lightness, 0, 255);
		
		psd_inthsb_to_rgb(dst_hue, dst_saturation, dst_lightness, red, green, blue);
	}
}
Example #2
0
static void psd_channel_mixer_proc(psd_uint layer_info_data, psd_int * red, psd_int * green, psd_int * blue)
{
	psd_layer_channel_mixer * data = (psd_layer_channel_mixer *)layer_info_data;
	psd_int dst_red, dst_green, dst_blue, src_red, src_green, src_blue, gray;
	
	src_red = *red;
	src_green = *green;
	src_blue = *blue;

	if(data->monochrome == psd_true)
	{
		gray = 0;
		gray += src_red * data->red_cyan[0] / 100;
		gray += src_green * data->green_magenta[0] / 100;
		gray += src_blue * data->blue_yellow[0] / 100;
		gray += data->constant[0] * 255 / 100;
		gray = PSD_CONSTRAIN(gray, 0, 255);
		*red = gray;
		*green = gray;
		*blue = gray;
	}
	else
	{
		if(data->red_cyan[0] != 100 || data->green_magenta[0] != 0 || 
			data->blue_yellow[0] != 0 || data->constant[0] != 0)
		{
			dst_red = 0;
			dst_red += src_red * data->red_cyan[0] / 100;
			dst_red += src_green * data->green_magenta[0] / 100;
			dst_red += src_blue * data->blue_yellow[0] / 100;
			dst_red += data->constant[0] * 255 / 100;
			*red = PSD_CONSTRAIN(dst_red, 0, 255);
		}

		if(data->green_magenta[1] != 100 || data->red_cyan[1] != 0 || 
			data->blue_yellow[1] != 0 || data->constant[1] != 0)
		{
			dst_green = 0;
			dst_green += src_green * data->green_magenta[1] / 100;
			dst_green += src_red * data->red_cyan[1] / 100;
			dst_green += src_blue * data->blue_yellow[1] / 100;
			dst_green += data->constant[1] * 255 / 100;
			*green = PSD_CONSTRAIN(dst_green, 0, 255);
		}

		if(data->blue_yellow[2] != 100 || data->red_cyan[2] != 0 || 
			data->green_magenta[2] != 0 || data->constant[2] != 0)
		{
			dst_blue = 0;
			dst_blue += src_blue * data->blue_yellow[2] / 100;
			dst_blue += src_red * data->red_cyan[2] / 100;
			dst_blue += src_green * data->green_magenta[2] / 100;
			dst_blue += data->constant[2] * 255 / 100;
			*blue = PSD_CONSTRAIN(dst_blue, 0, 255);
		}
	}
}
Example #3
0
void psd_adjustment_blend_rgb(psd_context * context, psd_layer_record * layer, psd_rect * dst_rect, 
	psd_uchar * red_lookup_table, psd_uchar * green_lookup_table, psd_uchar * blue_lookup_table,
	psd_bool preserve_luminosity)
{
	psd_int i, j, width, height;
	psd_int dst_red, dst_green, dst_blue, dst_alpha, src_red, src_green, src_blue;
	psd_argb_color *src_data, * dst_data, src_color;
	psd_int dst_luminosity, src_luminosity, value;
	
	width = psd_rect_width(dst_rect);
	height = psd_rect_height(dst_rect);
	
	for(i = 0; i < height; i ++)
	{
		src_data = context->blending_image_data + (dst_rect->top + i) * context->width + dst_rect->left;
		dst_data = layer->image_data + (dst_rect->top + i) * layer->width + dst_rect->left;
		
		for(j = 0; j < width; j ++, src_data ++, dst_data ++)
		{
			src_color = *src_data;
			dst_alpha = PSD_GET_ALPHA_COMPONENT(src_color);
			src_red = PSD_GET_RED_COMPONENT(src_color);
			src_green = PSD_GET_GREEN_COMPONENT(src_color);
			src_blue = PSD_GET_BLUE_COMPONENT(src_color);
			
			dst_red = red_lookup_table[src_red];
			dst_green = green_lookup_table[src_green];
			dst_blue = blue_lookup_table[src_blue];

			if(preserve_luminosity == psd_true)
			{
				src_luminosity = psd_rgb_get_brightness(src_red, src_green, src_blue);
				dst_luminosity = psd_rgb_get_brightness(dst_red, dst_green, dst_blue);
				value = dst_red * src_luminosity / dst_luminosity;
				src_red = PSD_CONSTRAIN(value, 0, 255);
				value = dst_green * src_luminosity / dst_luminosity;
				src_green = PSD_CONSTRAIN(value, 0, 255);
				value = dst_blue * src_luminosity / dst_luminosity;
				src_blue = PSD_CONSTRAIN(value, 0, 255);
			}
			
			*dst_data = PSD_ARGB_TO_COLOR(dst_alpha, dst_red, dst_green, dst_blue);
		}
	}
}
Example #4
0
psd_bool psd_layer_blend_levels(psd_context * context, psd_layer_record * layer, psd_rect * dst_rect)
{
	psd_int i, j, range, floor, value;
	psd_float gamma;
	psd_layer_levels * data = NULL;
	psd_uchar input_table[256], output_table[256];

	if(context->color_mode != psd_color_mode_rgb && context->color_mode != psd_color_mode_grayscale)
		return psd_false;

	for(i = 0; i < layer->layer_info_count; i ++)
	{
		if(layer->layer_info_type[i] == psd_layer_info_type_levels)
		{
			data = (psd_layer_levels *)layer->layer_info_data[i];
			break;
		}
	}
	if(data == NULL)
		return psd_false;

	if(layer->adjustment_valid == psd_true)
	{
		for(i = 0; i < 3; i ++)
		{
			for(j = 0; j < 256; j ++)
				data->lookup_table[i][j] = j;
		}
		for(i = 0; i < 4; i ++)
		{
			if(data->record[i].input_floor != 0 || data->record[i].input_ceiling != 255 ||
				data->record[i].output_floor != 0 || data->record[i].output_ceiling != 255 ||
				data->record[i].gamma != 1.0)
			{
				if(layer->adjustment_valid == psd_true)
				{
					if(data->record[i].input_floor != 0 || data->record[i].input_ceiling != 255 ||
						data->record[i].gamma != 1.0)
					{
						range = data->record[i].input_ceiling - data->record[i].input_floor;
						floor = data->record[i].input_floor;
						if(data->record[i].gamma != 1.0)
						{
							gamma = 1 / data->record[i].gamma;
							for(j = 0; j < 256; j ++)
							{
								value = (psd_int)(pow((psd_float)(j - floor) / range, gamma) * 255 + 0.5);
								input_table[j] = PSD_CONSTRAIN(value, 0, 255);
							}
						}
						else
						{
							for(j = 0; j < 256; j ++)
							{
								value = (psd_int)((j - floor) * 255.0 / range);
								input_table[j] = PSD_CONSTRAIN(value, 0, 255);
							}
						}
					}
					else
					{
						for(j = 0; j < 256; j ++)
							input_table[j] = j;
					}

					if(data->record[i].output_floor != 0 || data->record[i].output_ceiling != 255)
					{
						range = data->record[i].output_ceiling - data->record[i].output_floor;
						floor = data->record[i].output_floor;
						for(j = 0; j < 256; j ++)
						{
							output_table[j] = (j * range + 128) / 255 + floor;
						}
					}
					else
					{
						for(j = 0; j < 256; j ++)
							output_table[j] = j;
					}

					if(i == 0)
					{
						for(j = 0; j < 256; j ++)
						{
							data->lookup_table[0][j] = data->lookup_table[1][j] = 
								data->lookup_table[2][j] = output_table[input_table[j]];
						}
					}
					else
					{
						for(j = 0; j < 256; j ++)
							data->lookup_table[i - 1][j] = output_table[input_table[data->lookup_table[i - 1][j]]];
					}
				}
			}
			
			if(context->color_mode == psd_color_mode_grayscale)
				break;
		}
	}
	
	psd_adjustment_blend_rgb(context, layer, dst_rect, data->lookup_table[0],
		data->lookup_table[1], data->lookup_table[2], psd_false);

	layer->adjustment_valid = psd_false;

	return psd_true;
}