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]); } }
/* 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); } }
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); } }