예제 #1
0
void intr_packet_box(const ray_packet* packet,
                     const float* box_min,
                     const float* box_max,
                     const float* prev_tmin,
                     int* hit)
{
    for (int i = 0; i < 4; i++) {
        const float* org = packet->org + i * 4;
        const float* inv = packet->inv_dir + i * 4;
        float tmin[4], tmax[4];

        vector3_subtract(box_max, org, tmax);
        vector3_subtract(box_min, org, tmin);
        vector3_scale3(tmax, inv, tmax);
        vector3_scale3(tmin, inv, tmin);

        float vmin[4], vmax[4];
        vector3_max(tmax, tmin, vmax);
        vector3_min(tmax, tmin, vmin);

        vmax[0] = (vmax[0] < vmax[1]) ? vmax[0] : vmax[1];
        vmax[0] = (vmax[0] < vmax[2]) ? vmax[0] : vmax[2];

        vmin[0] = (vmin[0] > vmin[1]) ? vmin[0] : vmin[1];
        vmin[0] = (vmin[0] > vmin[2]) ? vmin[0] : vmin[2];

        hit[i] = (vmin[0] <= vmax[0]) && (vmax[0] >= 0) && (vmin[0] <= prev_tmin[i]);
    }
}
예제 #2
0
파일: dcp.c 프로젝트: bgromov/rawstudio
/* dng_color_spec::SetWhiteXY */
static void
set_white_xy(RSDcp *dcp, const RS_xy_COORD *xy)
{
	RS_MATRIX3 color_matrix;
	RS_MATRIX3 forward_matrix;

	dcp->white_xy = *xy;

	color_matrix = find_xyz_to_camera(dcp, xy, &forward_matrix);

	RS_XYZ_VECTOR white = xy_to_XYZ(xy);

	dcp->camera_white = vector3_multiply_matrix(&white, &color_matrix);

	gfloat white_scale = 1.0 / vector3_max(&dcp->camera_white);

	dcp->camera_white.x = CLAMP(0.001, white_scale * dcp->camera_white.x, 1.0);
	dcp->camera_white.y = CLAMP(0.001, white_scale * dcp->camera_white.y, 1.0);
	dcp->camera_white.z = CLAMP(0.001, white_scale * dcp->camera_white.z, 1.0);

	if (dcp->has_forward_matrix1 || dcp->has_forward_matrix2)
	{
		/* verified by DNG SDK */
		RS_MATRIX3 refCameraWhite_diagonal = vector3_as_diagonal(&dcp->camera_white);

		RS_MATRIX3 refCameraWhite_diagonal_inv = matrix3_invert(&refCameraWhite_diagonal); /* D */
		matrix3_multiply(&forward_matrix, &refCameraWhite_diagonal_inv, &dcp->camera_to_pcs);
	}
	else
	{
		/* FIXME: test this */
		RS_xy_COORD PCStoXY = {0.3457, 0.3585};
		RS_MATRIX3 map = rs_calculate_map_white_matrix(&PCStoXY, xy); /* or &white?! */
		RS_MATRIX3 pcs_to_camera;
		matrix3_multiply(&color_matrix, &map, &pcs_to_camera);
		RS_VECTOR3 tmp = vector3_multiply_matrix(&XYZ_WP_D50, &pcs_to_camera);
		gfloat scale = vector3_max(&tmp);
		matrix3_scale(&pcs_to_camera, 1.0 / scale, &pcs_to_camera);
		dcp->camera_to_pcs = matrix3_invert(&pcs_to_camera);
	}
}
예제 #3
0
파일: dcp.c 프로젝트: bgromov/rawstudio
static void
settings_changed(RSSettings *settings, RSSettingsMask mask, RSDcp *dcp)
{
	gboolean changed = FALSE;

	if (mask & MASK_EXPOSURE)
	{
		g_object_get(settings, "exposure", &dcp->exposure, NULL);
		changed = TRUE;
	}

	if (mask & MASK_SATURATION)
	{
		g_object_get(settings, "saturation", &dcp->saturation, NULL);
		changed = TRUE;
	}
	
	if (mask & MASK_CONTRAST)
	{
		g_object_get(settings, "contrast", &dcp->contrast, NULL);
		changed = TRUE;
	}

	if (mask & MASK_HUE)
	{
		g_object_get(settings, "hue", &dcp->hue, NULL);
		dcp->hue /= 60.0;
		changed = TRUE;
	}

	if (mask & MASK_CHANNELMIXER)
	{
		const gfloat channelmixer_red;
		const gfloat channelmixer_green;
		const gfloat channelmixer_blue;
		g_object_get(settings,
			"channelmixer_red", &channelmixer_red,
			"channelmixer_green", &channelmixer_green,
			"channelmixer_blue", &channelmixer_blue,
			NULL);
		dcp->channelmixer_red = channelmixer_red / 100.0f;
		dcp->channelmixer_green = channelmixer_green / 100.0f;
		dcp->channelmixer_blue = channelmixer_blue / 100.0f;
		changed = TRUE;
	}

	if (mask & MASK_WB)
	{
		dcp->warmth = -1.0;
		dcp->tint = -1.0;
		gfloat premul_warmth = -1.0;
		gfloat pre_mul_tint = -1.0;
		gboolean recalc = FALSE;

		g_object_get(settings,
			"dcp-temp", &dcp->warmth,
			"dcp-tint", &dcp->tint,
			"warmth", &premul_warmth,
			"tint", &pre_mul_tint,
			"recalc-temp", &recalc,
			NULL);

		RS_xy_COORD whitepoint;
		RS_VECTOR3 neutral;
		/* This is messy, but we're essentially converting from warmth/tint to cameraneutral */
		dcp->pre_mul.x = (1.0+premul_warmth)*(2.0-pre_mul_tint);
		dcp->pre_mul.y = 1.0;
		dcp->pre_mul.z = (1.0-premul_warmth)*(2.0-pre_mul_tint);

		if (recalc)
		{
			neutral.x = 1.0 / CLAMP(dcp->pre_mul.x, 0.001, 100.00);
			neutral.y = 1.0 / CLAMP(dcp->pre_mul.y, 0.001, 100.00);
			neutral.z = 1.0 / CLAMP(dcp->pre_mul.z, 0.001, 100.00);
			gfloat max = vector3_max(&neutral);
			neutral.x = neutral.x / max;
			neutral.y = neutral.y / max;
			neutral.z = neutral.z / max;
			whitepoint = neutral_to_xy(dcp, &neutral);

			if (dcp->use_profile)
			{
				rs_color_whitepoint_to_temp(&whitepoint, &dcp->warmth, &dcp->tint);
			} else {
				dcp->warmth = 5000;
				dcp->tint = 0;
			}
			dcp->warmth = CLAMP(dcp->warmth, 2000, 12000);
			dcp->tint = CLAMP(dcp->tint, -150, 150);
			g_object_set(settings,
				"dcp-temp", dcp->warmth,
				"dcp-tint", dcp->tint,
				"recalc-temp", FALSE,
				NULL);
			g_signal_emit_by_name(settings, "wb-recalculated");
		}
		if (dcp->use_profile)
		{
			whitepoint = rs_color_temp_to_whitepoint(dcp->warmth, dcp->tint);
			set_white_xy(dcp, &whitepoint);
			precalc(dcp);
		}
		else
		{
			set_prophoto_wb(dcp, dcp->warmth, dcp->tint);
		}
		changed = TRUE;
	}

	if (mask & MASK_CURVE)
	{
		const gint nknots = rs_settings_get_curve_nknots(settings);
		gint i;

		if (nknots > 1)
		{
			gfloat *knots = rs_settings_get_curve_knots(settings);
			if (knots)
			{
				dcp->nknots = nknots;
				dcp->curve_is_flat = FALSE;
				if (nknots == 2)
					if (ABS(knots[0]) < 0.0001 && ABS(knots[1]) < 0.0001)
						if (ABS(1.0 - knots[2]) < 0.0001 && ABS(1.0 - knots[3]) < 0.0001)
							dcp->curve_is_flat = TRUE;

				if (!dcp->curve_is_flat)
				{
					gfloat sampled[65537];
					RSSpline *spline = rs_spline_new(knots, dcp->nknots, NATURAL);
					rs_spline_sample(spline, sampled, sizeof(sampled) / sizeof(gfloat));
					g_object_unref(spline);
					/* Create extra entry */
					sampled[65536] = sampled[65535];
					for (i = 0; i < 256; i++)
					{
						gfloat value = (gfloat)i * (1.0 / 255.0f);
						/* Gamma correct value */
						value = powf(value, 1.0f / 2.0f);
						
						/* Lookup curve corrected value */
						gfloat lookup = (int)(value * 65535.0f);
						gfloat v0 = sampled[(int)lookup];
						gfloat v1 = sampled[(int)lookup+1];
						lookup -= (gfloat)(gint)lookup;
						value = v0 * (1.0f-lookup) + v1 * lookup;

						/* Convert from gamma 2.0 back to linear */
						value = powf(value, 2.0f);

						/* Store in table */
						if (i>0)
							dcp->curve_samples[i*2-1] = value;
						dcp->curve_samples[i*2] = value;
					}
					dcp->curve_samples[256*2-1] = dcp->curve_samples[256*2] = dcp->curve_samples[256*2+1] = dcp->curve_samples[255*2];
				}
			}
			if (knots)
				g_free(knots);
		}
		else
			dcp->curve_is_flat = TRUE;

		for(i=0;i<257*2;i++)
			dcp->curve_samples[i] = MIN(1.0f, MAX(0.0f, dcp->curve_samples[i]));

		changed = TRUE;
	}

	if (changed)
	{
		rs_filter_changed(RS_FILTER(dcp), RS_FILTER_CHANGED_PIXELDATA);
	}
}