Пример #1
0
/**
 * Set the RSFilter a RSLoupe will get its image data from
 * @param loupe A RSLoupe
 * @param filter A RSFilter
 */
void
rs_loupe_set_filter(RSLoupe *loupe, RSFilter *filter)
{
	g_assert(RS_IS_LOUPE(loupe));
	g_assert(RS_IS_FILTER(filter));

	if (loupe->filter == filter)
		return;

	if (loupe->filter)
		g_object_unref(loupe->filter);

	loupe->filter = g_object_ref(filter);
}
Пример #2
0
static RSFilterResponse *
get_image(RSFilter *filter, const RSFilterRequest *request)
{
	RSDcp *dcp = RS_DCP(filter);
	RSDcpClass *klass = RS_DCP_GET_CLASS(dcp);
	GdkRectangle *roi;
	RSFilterResponse *previous_response;
	RSFilterResponse *response;
	RS_IMAGE16 *input;
	RS_IMAGE16 *output;
	RS_IMAGE16 *tmp;

	gint j;

	RSFilterRequest *request_clone = rs_filter_request_clone(request);

	if (!dcp->use_profile)
	{
		gfloat premul[4] = {dcp->pre_mul.x, dcp->pre_mul.y, dcp->pre_mul.z, 1.0};
		rs_filter_param_set_float4(RS_FILTER_PARAM(request_clone), "premul", premul);
	}

	rs_filter_param_set_object(RS_FILTER_PARAM(request_clone), "colorspace", klass->prophoto);
	previous_response = rs_filter_get_image(filter->previous, request_clone);
	g_object_unref(request_clone);

	if (!RS_IS_FILTER(filter->previous))
		return previous_response;

	input = rs_filter_response_get_image(previous_response);
	if (!input) return previous_response;
	response = rs_filter_response_clone(previous_response);

	/* We always deliver in ProPhoto */
	rs_filter_param_set_object(RS_FILTER_PARAM(response), "colorspace", klass->prophoto);
	g_object_unref(previous_response);

	if ((roi = rs_filter_request_get_roi(request)))
	{
		/* Align so we start at even pixel counts */
		roi->width += (roi->x&1);
		roi->x -= (roi->x&1);
		roi->width = MIN(input->w - roi->x, roi->width);
		output = rs_image16_copy(input, FALSE);
		tmp = rs_image16_new_subframe(output, roi);
		bit_blt((char*)GET_PIXEL(tmp,0,0), tmp->rowstride * 2, 
			(const char*)GET_PIXEL(input,roi->x,roi->y), input->rowstride * 2, tmp->w * tmp->pixelsize * 2, tmp->h);
	}
	else
	{
		output = rs_image16_copy(input, TRUE);
		tmp = g_object_ref(output);
	}
	g_object_unref(input);
	rs_filter_response_set_image(response, output);
	g_object_unref(output);

	g_static_rec_mutex_lock(&dcp_mutex);
	init_exposure(dcp);

	guint i, y_offset, y_per_thread, threaded_h;
	guint threads = rs_get_number_of_processor_cores();
	if (tmp->h * tmp->w < 200*200)
		threads = 1;

	ThreadInfo *t = g_new(ThreadInfo, threads);

	threaded_h = tmp->h;
	y_per_thread = (threaded_h + threads-1)/threads;
	y_offset = 0;

	for (i = 0; i < threads; i++)
	{
		t[i].tmp = tmp;
		t[i].start_y = y_offset;
		t[i].start_x = 0;
		t[i].dcp = dcp;
		y_offset += y_per_thread;
		y_offset = MIN(tmp->h, y_offset);
		t[i].end_y = y_offset;
		for(j = 0; j < 256; j++)
			t[i].curve_input_values[j] = 0;
		t[i].single_thread = (threads == 1);
		if (threads == 1)
			start_single_dcp_thread(&t[0]);
		else	
			t[i].threadid = g_thread_create(start_single_dcp_thread, &t[i], TRUE, NULL);
	}

	/* Wait for threads to finish */
	for(i = 0; threads > 1 && i < threads; i++)
		g_thread_join(t[i].threadid);

	/* Settings can change now */
	g_static_rec_mutex_unlock(&dcp_mutex);

	/* If we must deliver histogram data, do it now */
	if (dcp->read_out_curve)
	{
		gint *values = g_malloc0(256*sizeof(gint));
		for(i = 0; i < threads; i++)
			for(j = 0; j < 256; j++)
				values[j] += t[i].curve_input_values[j];
		rs_curve_set_histogram_data(RS_CURVE_WIDGET(dcp->read_out_curve), values);
		g_free(values);
	}
	g_free(t);
	g_object_unref(tmp);

	return response;
}