Author: post
Date: 2009-12-29 18:09:17 +0100 (Tue, 29 Dec 2009)
New Revision: 2879

Modified:
   branches/rawstudio-ng-color/plugins/lensfun/lensfun.c
   branches/rawstudio-ng-color/plugins/lensfun/rs-lensfun-select.c
Log:
Lensfun: Added SSE2 optimized distortion modifier. Fixed lens update and 
allocation.

Modified: branches/rawstudio-ng-color/plugins/lensfun/lensfun.c
===================================================================
--- branches/rawstudio-ng-color/plugins/lensfun/lensfun.c       2009-12-29 
16:37:45 UTC (rev 2878)
+++ branches/rawstudio-ng-color/plugins/lensfun/lensfun.c       2009-12-29 
17:09:17 UTC (rev 2879)
@@ -21,6 +21,9 @@
 
 #include <rawstudio.h>
 #include <lensfun.h>
+#if defined (__SSE2__)
+#include <emmintrin.h>
+#endif /* __SSE2__ */
 #include <rs-lens.h>
 #include "rs-lensfun-select.h"
 
@@ -50,7 +53,7 @@
        gfloat vignetting_k2;
        gfloat vignetting_k3;
 
-       const lfLens *selected_lens;
+       lfLens *selected_lens;
        const lfCamera *selected_camera;
 
        gboolean DIRTY;
@@ -84,7 +87,9 @@
 static RSFilterResponse *get_image(RSFilter *filter, const RSFilterRequest 
*request);
 static void inline rs_image16_nearest_full(RS_IMAGE16 *in, gushort *out, 
gfloat *pos);
 static void inline rs_image16_bilinear_full(RS_IMAGE16 *in, gushort *out, 
gfloat *pos);
-
+#if defined (__SSE2__)
+static void inline rs_image16_bilinear_full_sse2(RS_IMAGE16 *in, gushort *out, 
gfloat *pos);
+#endif
 static RSFilterClass *rs_lensfun_parent_class = NULL;
 
 G_MODULE_EXPORT void
@@ -280,6 +285,7 @@
                        rs_filter_changed(RS_FILTER(lensfun), 
RS_FILTER_CHANGED_PIXELDATA);
                        break;
                case PROP_VIGNETTING_K2:
+                       /* FIXME: only have one vignetting input */
                        lensfun->vignetting_k1 = g_value_get_float(value);
                        lensfun->vignetting_k2 = g_value_get_float(value);
                        rs_filter_changed(RS_FILTER(lensfun), 
RS_FILTER_CHANGED_PIXELDATA);
@@ -338,7 +344,11 @@
 
                        for(x = 0; x < t->roi->width ; x++)
                        {
+#if defined (__SSE2__)
+                               rs_image16_bilinear_full_sse2(t->input, target, 
l_pos);
+#else
                                rs_image16_bilinear_full(t->input, target, 
l_pos);
+#endif
                                target += pixelsize;
                                l_pos += 6;
                        }
@@ -392,6 +402,8 @@
 
        if(lensfun->DIRTY)
        {
+               if (lensfun->selected_lens)
+                       lf_free(lensfun->selected_lens);
 
                const lfCamera **cameras = NULL;
                const lfLens **lenses = NULL;
@@ -428,8 +440,9 @@
                                lenses = lf_db_find_lenses_hd(lensfun->ldb, 
lensfun->selected_camera, make, model, 0);
                                if (lenses)
                                {
-                                       /* FIXME: selecting first lens */
-                                       lensfun->selected_lens = lenses [0];
+                                       lensfun->selected_lens = lf_lens_new();
+                                       /* FIXME: selecting first lens */       
                                
+                                       lf_lens_copy(lensfun->selected_lens, 
lenses [0]);
                                        lf_free (lenses);
                                }
                        }
@@ -458,7 +471,6 @@
                                g_object_unref(input);
                                return response;
                        }
-                       /* FIXME: It can be safely assumed that we leak this */
                        lfLens* lens = lf_lens_new ();
                        lens->Model = lensfun->model;
                        lens->MinFocal = 10.0;
@@ -490,30 +502,43 @@
        {
                gint effective_flags;
 
-               /*FIXME: TCA and Vignetting should default to the values in 
lensfun db */
+               printf("CA(R): %f, CA(B):%f, VIGN(K1): %f\n", lensfun->tca_kr, 
lensfun->tca_kb, lensfun->vignetting_k1);
+
                /* 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, &params);
-               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 (ABS(lensfun->tca_kr) > 0.01f || ABS(lensfun->tca_kb) > 
0.01f) 
+               {
+                       lfLensCalibTCA tca;
+                       tca.Model = LF_TCA_MODEL_LINEAR;
+                       const char *details = NULL;
+                       const lfParameter **params = NULL;
+                       lf_get_tca_model_desc (tca.Model, &details, &params);
+                       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);
+               } else
+               {
+                       lf_lens_remove_calib_tca(lensfun->selected_lens, 0);
+                       lf_lens_remove_calib_tca(lensfun->selected_lens, 1);
+               }
 
                /* Set vignetting */
-               lfLensCalibVignetting vignetting;
-               vignetting.Model = LF_VIGNETTING_MODEL_PA;
-//                     const char *details;
-//                     const lfParameter **params;
-//                     lf_get_vignetting_model_desc(vignetting.Model, 
&details, &params);
-               vignetting.Distance = 1.0;
-               vignetting.Focal = lensfun->focal;
-               vignetting.Aperture = lensfun->aperture;
-               vignetting.Terms[0] = -lensfun->vignetting_k1 * 0.5;
-               vignetting.Terms[1] = -lensfun->vignetting_k2 * -0.125;
-               vignetting.Terms[2] = lensfun->vignetting_k3;
-               lf_lens_add_calib_vignetting((lfLens *) lensfun->selected_lens, 
&vignetting);
+               if (ABS(lensfun->vignetting_k1) > 0.01f || 
ABS(lensfun->vignetting_k2) > 0.01f)
+               {
+                       lfLensCalibVignetting vignetting;
+                       vignetting.Model = LF_VIGNETTING_MODEL_PA;
+                       vignetting.Distance = 1.0;
+                       vignetting.Focal = lensfun->focal;
+                       vignetting.Aperture = lensfun->aperture;
+                       vignetting.Terms[0] = -lensfun->vignetting_k1 * 0.5;
+                       vignetting.Terms[1] = -lensfun->vignetting_k2 * -0.125;
+                       vignetting.Terms[2] = lensfun->vignetting_k3;
+                       lf_lens_add_calib_vignetting((lfLens *) 
lensfun->selected_lens, &vignetting);
+               } else
+               {
+                       lf_lens_remove_calib_vignetting(lensfun->selected_lens, 
0);
+                       lf_lens_remove_calib_vignetting(lensfun->selected_lens, 
1);
+                       lf_lens_remove_calib_vignetting(lensfun->selected_lens, 
2);
+               }
 
                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,
@@ -678,3 +703,121 @@
                out[i]  = (gushort) ((a[i]*aw  + b[i]*bw  + c[i]*cw  + d[i]*dw 
+ 16384) >> 15 );
        }
 }
+
+
+#if defined (__SSE2__)
+static gfloat twofiftytwo_ps[4] __attribute__ ((aligned (16))) = {256.0f, 
256.0f, 256.0f, 0.0f};
+               
+static void inline
+rs_image16_bilinear_full_sse2(RS_IMAGE16 *in, gushort *out, gfloat *pos)
+{
+       const gint m_w = (in->w-1);
+       const gint m_h = (in->h-1);
+
+       __m128 p0, p1;
+       if ((uintptr_t)pos & 15)
+       {
+               p0 = _mm_loadu_ps(pos);         // y1x1 y0x0
+               p1 = _mm_loadu_ps(pos+4);       // ---- y2x2
+       } else 
+       {
+               p0 = _mm_load_ps(pos);          // y1x1 y0x0
+               p1 = _mm_load_ps(pos+4);        // ---- y2x2
+       }
+               
+       __m128 xf = _mm_shuffle_ps(p1, p0, _MM_SHUFFLE(0,2,2,0));
+       __m128 yf = _mm_shuffle_ps(p1, p0, _MM_SHUFFLE(1,3,1,1));
+                       
+       __m128 fl256 = _mm_load_ps(twofiftytwo_ps);
+       xf = _mm_mul_ps(xf, fl256);
+       yf = _mm_mul_ps(yf, fl256);
+       __m128i x = _mm_cvttps_epi32(xf);
+       __m128i y = _mm_cvttps_epi32(yf);
+
+       __m128i _m_w = _mm_slli_epi32(_mm_set1_epi32(m_w), 8);
+       __m128i _m_h = _mm_slli_epi32(_mm_set1_epi32(m_h), 8);
+       
+       __m128i x_gt, y_gt;
+       
+       /* If positions from lensfun is properly clamped this should not be 
needed */
+       /* Enable, if crashes begin occuring here here */
+#if 0
+       x_gt = _mm_cmpgt_epi32(x, _m_w);
+       y_gt = _mm_cmpgt_epi32(y, _m_h);
+       
+       x = _mm_or_si128(_mm_andnot_si128(x_gt, x), _mm_and_si128(_m_w, x_gt));
+       y = _mm_or_si128(_mm_andnot_si128(y_gt, y), _mm_and_si128(_m_h, y_gt));
+
+       __m128i zero = _mm_setzero_si128();
+       __m128i x_lt = _mm_cmplt_epi32(x, zero);
+       __m128i y_lt = _mm_cmplt_epi32(y, zero);
+       x = _mm_andnot_si128(x_lt, x);
+       y = _mm_andnot_si128(y_lt, y);
+#endif
+       __m128i one = _mm_set1_epi32(1);
+       __m128i nx = _mm_add_epi32(one, _mm_srai_epi32(x, 8));
+       __m128i ny = _mm_add_epi32(one, _mm_srai_epi32(y, 8));
+
+       _m_w = _mm_srai_epi32(_m_w, 8);
+       _m_h = _mm_srai_epi32(_m_h, 8);
+
+       x_gt = _mm_cmpgt_epi32(nx, _m_w);
+       y_gt = _mm_cmpgt_epi32(ny, _m_h);
+       
+       nx = _mm_or_si128(_mm_andnot_si128(x_gt, nx), _mm_and_si128(_m_w, 
x_gt));
+       ny = _mm_or_si128(_mm_andnot_si128(y_gt, ny), _mm_and_si128(_m_h, 
y_gt));
+
+       int xfer[16] __attribute__ ((aligned (16)));
+
+       _mm_store_si128((__m128i*)xfer, _mm_srai_epi32(x, 8));
+       _mm_store_si128((__m128i*)&xfer[4], _mm_srai_epi32(y, 8));
+       _mm_store_si128((__m128i*)&xfer[8], nx);
+       _mm_store_si128((__m128i*)&xfer[12], ny);
+       
+       gushort* pixels[12];
+       
+       /* Loop unrolled, allows agressive instruction reordering */
+       /* Red, then G & B */
+       pixels[0] = GET_PIXEL(in, xfer[0], xfer[4]);    // a
+       pixels[1] = GET_PIXEL(in, xfer[8], xfer[4]);    // b
+       pixels[2] = GET_PIXEL(in, xfer[0], xfer[12]);   // c
+       pixels[3] = GET_PIXEL(in, xfer[8], xfer[12]);   // d
+               
+       pixels[4] = GET_PIXEL(in, xfer[1], xfer[1+4]) + 1;              // a
+       pixels[4+1] = GET_PIXEL(in, xfer[1+8], xfer[1+4]) + 1;  // b
+       pixels[4+2] = GET_PIXEL(in, xfer[1], xfer[1+12]) + 1;   // c
+       pixels[4+3] = GET_PIXEL(in, xfer[1+8], xfer[1+12]) + 1; // d
+
+       pixels[2*4] = GET_PIXEL(in, xfer[2], xfer[2+4]) + 2;            // a
+       pixels[2*4+1] = GET_PIXEL(in, xfer[2+8], xfer[2+4]) + 2;        // b
+       pixels[2*4+2] = GET_PIXEL(in, xfer[2], xfer[2+12]) + 2;         // c
+       pixels[2*4+3] = GET_PIXEL(in, xfer[2+8], xfer[2+12]) + 2;       // d
+
+       /* Calculate distances */
+       __m128i twofiftyfive = _mm_set1_epi32(255);
+       __m128i diffx = _mm_and_si128(x, twofiftyfive); 
+       __m128i diffy = _mm_and_si128(y, twofiftyfive); 
+       __m128i inv_diffx = _mm_andnot_si128(diffx, twofiftyfive);
+       __m128i inv_diffy = _mm_andnot_si128(diffy, twofiftyfive);
+
+       /* Calculate weights */
+       __m128i aw = _mm_srai_epi32(_mm_mullo_epi16(inv_diffx, inv_diffy),1);
+       __m128i bw = _mm_srai_epi32(_mm_mullo_epi16(diffx, inv_diffy),1);
+       __m128i cw = _mm_srai_epi32(_mm_mullo_epi16(inv_diffx, diffy),1);
+       __m128i dw = _mm_srai_epi32(_mm_mullo_epi16(diffx, diffy),1);
+
+       _mm_store_si128((__m128i*)xfer, aw);
+       _mm_store_si128((__m128i*)&xfer[4], bw);
+       _mm_store_si128((__m128i*)&xfer[8], cw);
+       _mm_store_si128((__m128i*)&xfer[12], dw);
+       
+       gushort** p = pixels;
+       /* Loop unrolled */
+       out[0]  = (gushort) ((xfer[0] * *p[0] + xfer[4] * *p[1] + xfer[8] * 
*p[2] + xfer[12] * *p[3]  + 16384) >> 15 );
+       p+=4;
+       out[1]  = (gushort) ((xfer[1] * *p[0] + xfer[1+4] * *p[1] + xfer[1+8] * 
*p[2] + xfer[1+12] * *p[3]  + 16384) >> 15 );
+       p+=4;
+       out[2]  = (gushort) ((xfer[2] * *p[0] + xfer[2+4] * *p[1] + xfer[2+8] * 
*p[2] + xfer[2+12] * *p[3]  + 16384) >> 15 );
+}
+
+#endif // defined (__SSE2__)

Modified: branches/rawstudio-ng-color/plugins/lensfun/rs-lensfun-select.c
===================================================================
--- branches/rawstudio-ng-color/plugins/lensfun/rs-lensfun-select.c     
2009-12-29 16:37:45 UTC (rev 2878)
+++ branches/rawstudio-ng-color/plugins/lensfun/rs-lensfun-select.c     
2009-12-29 17:09:17 UTC (rev 2879)
@@ -31,8 +31,8 @@
 #include "rs-lensfun-select.h"
 
 void lensfun_editor_load_database(GtkTreeModel *list);
-GtkWidget *gui_dialog_make_from_widget(const gchar *stock_id, gchar 
*primary_text, GtkWidget *widget); /* FIXME */
 
+
 /* BEGIN BLOCK - mostly grabbed from UFRaw */
 typedef struct {
        /* The GtkEntry with camera maker/model name */
@@ -47,6 +47,61 @@
        RSLens *lens;
 } lens_data;
 
+
+GtkWidget *
+gui_dialog_make_from_widget(const gchar *stock_id, gchar *primary_text, 
GtkWidget *widget)
+{
+       GtkWidget *dialog, *image, *hhbox, *vvbox;
+       GtkWidget *primary_label;
+       gchar *str;
+
+       image = gtk_image_new_from_stock(stock_id, GTK_ICON_SIZE_DIALOG);
+       gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0.0);
+       dialog = gtk_dialog_new();
+       gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
+       gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 14);
+       gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
+       gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
+       gtk_window_set_title (GTK_WINDOW (dialog), "");
+       gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
+       gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE);
+
+       primary_label = gtk_label_new (NULL);
+       gtk_label_set_line_wrap (GTK_LABEL (primary_label), TRUE);
+       gtk_label_set_use_markup (GTK_LABEL (primary_label), TRUE);
+       gtk_misc_set_alignment (GTK_MISC (primary_label), 0.0, 0.5);
+       gtk_label_set_selectable (GTK_LABEL (primary_label), TRUE);
+       str = g_strconcat("<span weight=\"bold\" size=\"larger\">", 
primary_text, "</span>", NULL);
+       gtk_label_set_markup (GTK_LABEL (primary_label), str);
+       g_free(str);
+
+       hhbox = gtk_hbox_new (FALSE, 12);
+       gtk_container_set_border_width (GTK_CONTAINER (hhbox), 5);
+       gtk_box_pack_start (GTK_BOX (hhbox), image, FALSE, FALSE, 0);
+       vvbox = gtk_vbox_new (FALSE, 12);
+       gtk_box_pack_start (GTK_BOX (hhbox), vvbox, FALSE, FALSE, 0);
+       gtk_box_pack_start (GTK_BOX (vvbox), primary_label, FALSE, FALSE, 0);
+       gtk_box_pack_start (GTK_BOX (vvbox), widget, FALSE, FALSE, 0);
+       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), hhbox, FALSE, 
FALSE, 0);
+
+       return(dialog);
+}
+
+GtkWidget *
+gui_dialog_make_from_text(const gchar *stock_id, gchar *primary_text, gchar 
*secondary_text)
+{
+       GtkWidget *secondary_label;
+
+       secondary_label = gtk_label_new (NULL);
+       gtk_label_set_line_wrap (GTK_LABEL (secondary_label), TRUE);
+       gtk_label_set_use_markup (GTK_LABEL (secondary_label), TRUE);
+       gtk_misc_set_alignment (GTK_MISC (secondary_label), 0.0, 0.5);
+       gtk_label_set_selectable (GTK_LABEL (secondary_label), TRUE);
+       gtk_label_set_markup (GTK_LABEL (secondary_label), secondary_text);
+       
+       return(gui_dialog_make_from_widget(stock_id, primary_text, 
secondary_label));
+}
+
 static void lens_set (lens_data *data, const lfLens *lens)
 {
        g_print ("Lens: %s / %s\n",


_______________________________________________
Rawstudio-commit mailing list
[email protected]
http://rawstudio.org/cgi-bin/mailman/listinfo/rawstudio-commit

Reply via email to