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