Author: post
Date: 2009-11-22 16:17:27 +0100 (Sun, 22 Nov 2009)
New Revision: 2751
Modified:
trunk/plugins/lensfun/lensfun.c
Log:
Lensfun: Added multithreaded vignetting correction. Vignetting no longer
overwrites input. Added (future) ROI-support for lensfun. Also set Vignetting
and TCA if they are zero to allow resetting it.
Modified: trunk/plugins/lensfun/lensfun.c
===================================================================
--- trunk/plugins/lensfun/lensfun.c 2009-11-16 23:01:04 UTC (rev 2750)
+++ trunk/plugins/lensfun/lensfun.c 2009-11-22 15:17:27 UTC (rev 2751)
@@ -296,33 +296,51 @@
RS_IMAGE16 *input;
RS_IMAGE16 *output;
GThread *threadid;
+ gint effective_flags;
+ GdkRectangle *roi;
+ gint stage;
} ThreadInfo;
static gpointer
thread_func(gpointer _thread_info)
{
- gint row, col;
+ gint x, y;
ThreadInfo* t = _thread_info;
- gfloat *pos = g_new0(gfloat, t->input->w*6);
- const gint pixelsize = t->output->pixelsize;
- for(row=t->start_y;row<t->end_y;row++)
+ if (t->stage == 2)
{
- gushort *target;
- lf_modifier_apply_subpixel_geometry_distortion(t->mod, 0.0,
(gfloat) row, t->input->w, 1, pos);
- target = GET_PIXEL(t->output, 0, row);
- gfloat* l_pos = pos;
-
- for(col=0;col<t->input->w;col++)
+ /* Do lensfun vignetting */
+ if (t->effective_flags & LF_MODIFY_VIGNETTING)
{
- rs_image16_bilinear_full(t->input, target, l_pos);
- target += pixelsize;
- l_pos += 6;
+ lf_modifier_apply_color_modification (t->mod,
GET_PIXEL(t->input, t->roi->x, t->start_y),
+ t->roi->x, t->start_y, t->roi->width, t->end_y
- t->start_y,
+ LF_CR_4 (RED, GREEN, BLUE, UNKNOWN),
+ t->input->rowstride*2);
}
}
- g_free(pos);
+ if (t->stage == 3)
+ {
+ /* Do TCA and distortion */
+ gfloat *pos = g_new0(gfloat, t->input->w*6);
+ const gint pixelsize = t->output->pixelsize;
+
+ for(y = t->start_y; y < t->end_y; y++)
+ {
+ gushort *target;
+ lf_modifier_apply_subpixel_geometry_distortion(t->mod,
t->roi->x, (gfloat) y, t->roi->width, 1, pos);
+ target = GET_PIXEL(t->output, t->roi->x, y);
+ gfloat* l_pos = pos;
+ for(x = 0; x < t->roi->width ; x++)
+ {
+ rs_image16_bilinear_full(t->input, target,
l_pos);
+ target += pixelsize;
+ l_pos += 6;
+ }
+ }
+ g_free(pos);
+ }
return NULL;
}
@@ -337,6 +355,7 @@
RS_IMAGE16 *output = NULL;
const gchar *make = NULL;
const gchar *model = NULL;
+ GdkRectangle *roi;
previous_response = rs_filter_get_image(filter->previous, request);
input = rs_filter_response_get_image(previous_response);
@@ -357,7 +376,7 @@
if (!RS_IS_IMAGE16(input))
return response;
- gint i, j;
+ gint i;
if (!lensfun->ldb)
{
@@ -392,7 +411,6 @@
{
model = rs_lens_get_lensfun_model(lensfun->lens);
make = rs_lens_get_lensfun_make(lensfun->lens);
-
lenses = lf_db_find_lenses_hd(lensfun->ldb,
lensfun->selected_camera, make, model, 0);
}
@@ -410,41 +428,49 @@
lensfun->DIRTY = FALSE;
}
-
+
+ roi = rs_filter_request_get_roi(request);
+ gboolean destroy_roi = FALSE;
+ printf("ROI: ");
+ if (!roi)
+ {
+ roi = g_new(GdkRectangle, 1);
+ roi->x = 0;
+ roi->y = 0;
+ roi->width = input->w;
+ roi->height = input->h;
+ destroy_roi = TRUE;
+ printf("(new) ");
+ }
+ printf("x:%d, y:%d; w:%d, h:%d\n",roi->x,roi->y,roi->width,
roi->height);
/* Procedd if we got everything */
if (lf_lens_check((lfLens *) lensfun->selected_lens))
{
gint effective_flags;
- if (lensfun->tca_kr != 0.0 || lensfun->tca_kb != 0.0)
- {
- /* Set TCA */
- lfLensCalibTCA tca;
- tca.Model = LF_TCA_MODEL_LINEAR;
- const char *details = NULL;
- const lfParameter **params = NULL;
- lf_get_tca_model_desc (tca.Model, &details, ¶ms);
- tca.Terms[0] = (lensfun->tca_kr/100)+1;
- tca.Terms[1] = (lensfun->tca_kb/100)+1;
- lf_lens_add_calib_tca((lfLens *)
lensfun->selected_lens, (lfLensCalibTCA *) &tca);
- }
+ /* Set TCA */
+ lfLensCalibTCA tca;
+ tca.Model = LF_TCA_MODEL_LINEAR;
+ const char *details = NULL;
+ const lfParameter **params = NULL;
+ lf_get_tca_model_desc (tca.Model, &details, ¶ms);
+ tca.Terms[0] = (lensfun->tca_kr/100)+1;
+ tca.Terms[1] = (lensfun->tca_kb/100)+1;
+ lf_lens_add_calib_tca((lfLens *) lensfun->selected_lens,
(lfLensCalibTCA *) &tca);
- if (lensfun->vignetting_k2 != 0.0 )
- {
- /* Set vignetting */
- lfLensCalibVignetting vignetting;
- vignetting.Model = LF_VIGNETTING_MODEL_PA;
+ /* Set vignetting */
+ lfLensCalibVignetting vignetting;
+ vignetting.Model = LF_VIGNETTING_MODEL_PA;
// const char *details;
// const lfParameter **params;
// lf_get_vignetting_model_desc(vignetting.Model,
&details, ¶ms);
- vignetting.Distance = 1.0;
- vignetting.Focal = lensfun->focal;
- vignetting.Aperture = lensfun->aperture;
- vignetting.Terms[0] = lensfun->vignetting_k1;
- vignetting.Terms[1] = lensfun->vignetting_k2;
- vignetting.Terms[2] = lensfun->vignetting_k3;
- lf_lens_add_calib_vignetting((lfLens *)
lensfun->selected_lens, &vignetting);
- }
+ vignetting.Distance = 1.0;
+ vignetting.Focal = lensfun->focal;
+ vignetting.Aperture = lensfun->aperture;
+ vignetting.Terms[0] = lensfun->vignetting_k1;
+ vignetting.Terms[1] = lensfun->vignetting_k2;
+ vignetting.Terms[2] = lensfun->vignetting_k3;
+ lf_lens_add_calib_vignetting((lfLens *) lensfun->selected_lens,
&vignetting);
lfModifier *mod = lf_modifier_new (lensfun->selected_lens,
lensfun->selected_camera->CropFactor, input->w, input->h);
effective_flags = lf_modifier_initialize (mod,
lensfun->selected_lens,
@@ -474,44 +500,68 @@
g_debug("Effective flags:%s", flags->str);
g_string_free(flags, TRUE);
- /* Do lensfun vignetting */
- if (effective_flags & LF_MODIFY_VIGNETTING)
- {
- lf_modifier_apply_color_modification (
- mod, input->pixels, 0.0, 0.0, input->w,
input->h,
- LF_CR_4 (RED, GREEN, BLUE, UNKNOWN),
- input->rowstride*2);
- }
if (effective_flags > 0)
{
guint y_offset, y_per_thread, threaded_h;
const guint threads =
rs_get_number_of_processor_cores();
- output = rs_image16_copy(input, FALSE);
ThreadInfo *t = g_new(ThreadInfo, threads);
- threaded_h = input->h;
+ threaded_h = roi->height;
y_per_thread = (threaded_h + threads-1)/threads;
- y_offset = 0;
+ y_offset = roi->y;
/* Set up job description for individual threads */
for (i = 0; i < threads; i++)
{
- t[i].input = input;
- t[i].output = output;
t[i].mod = mod;
t[i].start_y = y_offset;
y_offset += y_per_thread;
- /* FIXME: Why the -1 */
- y_offset = MIN(input->h-1, y_offset);
+ y_offset = MIN(roi->height, y_offset);
t[i].end_y = y_offset;
-
- t[i].threadid = g_thread_create(thread_func,
&t[i], TRUE, NULL);
+ t[i].effective_flags = effective_flags;
+ t[i].roi = roi;
}
- /* Wait for threads to finish */
- for(i = 0; i < threads; i++)
- g_thread_join(t[i].threadid);
+ /* Start threads to apply phase 2, Vignetting and CA
Correction */
+ if (effective_flags & (LF_MODIFY_VIGNETTING |
LF_MODIFY_CCI))
+ {
+ /* Phase 2 is corrected inplace, so copy input
first */
+ output = rs_image16_copy(input, TRUE);
+ g_object_unref(input);
+ for (i = 0; i < threads; i++)
+ {
+ t[i].input = t[i].output = output;
+ t[i].stage = 2;
+ t[i].threadid =
g_thread_create(thread_func, &t[i], TRUE, NULL);
+ }
+
+ /* Wait for threads to finish */
+ for(i = 0; i < threads; i++)
+ g_thread_join(t[i].threadid);
+ input = output;
+ }
+
+ /* Start threads to apply phase 1+3, Chromatic
abberation and distortion Correction */
+ if (effective_flags & (LF_MODIFY_TCA |
LF_MODIFY_DISTORTION | LF_MODIFY_GEOMETRY))
+ {
+ output = rs_image16_copy(input, FALSE);
+ for (i = 0; i < threads; i++)
+ {
+ t[i].input = input;
+ t[i].output = output;
+ t[i].stage = 3;
+ t[i].threadid =
g_thread_create(thread_func, &t[i], TRUE, NULL);
+ }
+
+ /* Wait for threads to finish */
+ for(i = 0; i < threads; i++)
+ g_thread_join(t[i].threadid);
+ }
+ else
+ {
+ output = rs_image16_copy(input, TRUE);
+ }
g_free(t);
rs_filter_response_set_image(response, output);
g_object_unref(output);
@@ -524,6 +574,8 @@
else
g_debug("lf_lens_check() failed");
// lfModifier *mod = lfModifier::Create (lens, opts.Crop, img->width,
img->height);
+ if (destroy_roi)
+ g_free(roi);
g_object_unref(input);
return response;
_______________________________________________
Rawstudio-commit mailing list
[email protected]
http://rawstudio.org/cgi-bin/mailman/listinfo/rawstudio-commit