Update of /cvsroot/ufraw/ufraw
In directory sfp-cvsdas-2.v30.ch3.sourceforge.com:/tmp/cvs-serv14620

Modified Files:
        ufraw.h ufraw_preview.c ufraw_ufraw.c 
Log Message:
Reorginize and simplify the API, making ufraw_convert_prepare_buffers()
an internal function. This also fixes some segfaults.


Index: ufraw.h
===================================================================
RCS file: /cvsroot/ufraw/ufraw/ufraw.h,v
retrieving revision 1.139
retrieving revision 1.140
diff -u -d -r1.139 -r1.140
--- ufraw.h     27 Nov 2009 07:18:23 -0000      1.139
+++ ufraw.h     1 Dec 2009 03:30:57 -0000       1.140
@@ -315,17 +315,12 @@
 int ufraw_load_raw(ufraw_data *uf);
 int ufraw_load_darkframe(ufraw_data *uf);
 void ufraw_developer_prepare(ufraw_data *uf, DeveloperMode mode);
-void ufraw_convert_prepare_buffers(ufraw_data *uf);
 int ufraw_convert_image(ufraw_data *uf);
 #ifdef HAVE_LENSFUN
 void ufraw_lensfun_init(ufraw_data *uf);
 #endif
-void ufraw_image_format(int *colors, int *bytes, ufraw_image_data *img,
-       const char *formats, const char *caller);
-ufraw_image_data *ufraw_rgb_image(ufraw_data *uf, gboolean bufferok,
-       const char *dbg);
-ufraw_image_data *ufraw_final_image(ufraw_data *uf, gboolean bufferok);
-ufraw_image_data *ufraw_display_image(ufraw_data *uf, gboolean bufferok);
+ufraw_image_data *ufraw_get_image(ufraw_data *uf, UFRawPhase phase,
+       gboolean bufferok);
 ufraw_image_data *ufraw_convert_image_area(ufraw_data *uf, unsigned saidx,
        UFRawPhase phase);
 void ufraw_close(ufraw_data *uf);
@@ -338,7 +333,6 @@
 void ufraw_invalidate_despeckle_layer(ufraw_data *uf);
 void ufraw_invalidate_whitebalance_layer(ufraw_data *uf);
 void ufraw_invalidate_smoothing_layer(ufraw_data *uf);
-gboolean ufraw_invalidate_layer_event(ufraw_data *uf, UFRawPhase phase);
 int ufraw_set_wb(ufraw_data *uf);
 void ufraw_auto_expose(ufraw_data *uf);
 void ufraw_auto_black(ufraw_data *uf);

Index: ufraw_ufraw.c
===================================================================
RCS file: /cvsroot/ufraw/ufraw/ufraw_ufraw.c,v
retrieving revision 1.222
retrieving revision 1.223
diff -u -d -r1.222 -r1.223
--- ufraw_ufraw.c       28 Nov 2009 05:56:51 -0000      1.222
+++ ufraw_ufraw.c       1 Dec 2009 03:30:57 -0000       1.223
@@ -43,6 +43,8 @@
 static void ufraw_convert_image_vignetting(ufraw_data *uf,
        ufraw_image_data *img, UFRectangle *area);
 #endif
+static void ufraw_image_format(int *colors, int *bytes, ufraw_image_data *img,
+       const char *formats, const char *caller);
 static void ufraw_convert_image_raw(ufraw_data *uf, UFRawPhase phase);
 static void ufraw_convert_image_first(ufraw_data *uf, UFRawPhase phase);
 static void ufraw_convert_image_transform(ufraw_data *uf, ufraw_image_data 
*img,
@@ -1392,6 +1394,8 @@
     {
        g_free(img->buffer);
        img->buffer = NULL;
+       img->width = width;
+       img->height = height;
     } else {
        double sine = sin(uf->conf->rotationAngle * 2 * M_PI / 360);
        double cosine = cos(uf->conf->rotationAngle * 2 * M_PI / 360);
@@ -1408,35 +1412,42 @@
  * invalidation here is a secondary effect of the need to resize
  * buffers. The invalidate events should all have been set already.
  */
-void ufraw_convert_prepare_buffers(ufraw_data *uf)
+static void ufraw_convert_prepare_buffers(ufraw_data *uf, UFRawPhase phase)
 {
-    ufraw_image_data *img = &uf->Images[ufraw_first_phase];
-    if (img->valid == 0) {
-       ufraw_convert_prepare_first_buffer(uf, img);
+    ufraw_image_data *img = &uf->Images[phase];
+    if (!img->invalidate_event)
+       return;
+    img->invalidate_event = FALSE;
+    int width = 0, height = 0;
+    if (phase > ufraw_first_phase) {
+       ufraw_convert_prepare_buffers(uf, phase-1);
+       width = uf->Images[phase-1].width;
+       height = uf->Images[phase-1].height;
     }
-    int width = img->width;
-    int height = img->height;
-
-    img = &uf->Images[ufraw_transform_phase];
-    if (img->valid == 0) {
+    switch (phase) {
+    case ufraw_raw_phase:
+       return;
+    case ufraw_first_phase:
+       ufraw_convert_prepare_first_buffer(uf, img);
+       return;
+    case ufraw_transform_phase:
        ufraw_convert_prepare_transform_buffer(uf, img, width, height);
-    }
-    if (img->buffer != NULL) {
-       width = img->width;
-       height = img->height;
-    }
-    img = &uf->Images[ufraw_develop_phase];
-    if (img->valid == 0) {
+       return;
+    case ufraw_develop_phase:
        ufraw_image_init(img, width, height, 3);
-    }
-    img = &uf->Images[ufraw_display_phase];
-    if (img->valid == 0) {
+       return;
+    case ufraw_display_phase:
        if (uf->developer->working2displayTransform == NULL) {
            g_free(img->buffer);
            img->buffer = NULL;
+           img->width = width;
+           img->height = height;
        } else {
            ufraw_image_init(img, width, height, 3);
        }
+       return;
+    default:
+       g_warning("ufraw_convert_prepare_buffers: unsupported phase %d", phase);
     }
 }
 
@@ -1495,7 +1506,7 @@
  * algorithms all over the place to accept more image formats: replacing
  * constants by variables may turn off some compiler optimizations.
  */
-void ufraw_image_format(int *colors, int *bytes, ufraw_image_data *img,
+static void ufraw_image_format(int *colors, int *bytes, ufraw_image_data *img,
        const char *formats, const char *caller)
 {
     int b, c;
@@ -1528,88 +1539,32 @@
        *bytes = b;
 }
 
-/*
- * Some algorithms need access to the RGB data before color adjustments
- * such as white-balance, hue, saturation have been applied.
- */
-ufraw_image_data *ufraw_rgb_image(ufraw_data *uf, gboolean bufferok,
-       const char *dbg)
-{
-    UFRawPhase phase = ufraw_first_phase;
-#ifdef HAVE_LENSFUN
-    if (uf->modifier &&
-       (uf->modFlags & (UF_LF_ALL & ~LF_MODIFY_VIGNETTING)))
-       phase = ufraw_transform_phase;
-#endif /* HAVE_LENSFUN */
-    int i;
-
-    if (bufferok) {
-       if (dbg && uf->Images[phase].valid != 0xffffffff) {
-           g_warning("%s->%s: conversion necessary (suboptimal).\n", dbg,
-               G_STRFUNC);
-           for (i = 0; i < 32; ++i) {
-               ufraw_convert_image_area(uf, i, phase);
-           }
-       }
-    } else {
-       if (uf->Images[phase].valid == 0)
-           ufraw_convert_prepare_buffers(uf);
-    }
-    return &uf->Images[phase];
-}
-
-ufraw_image_data *ufraw_final_image(ufraw_data *uf, gboolean bufferok)
+ufraw_image_data *ufraw_get_image(ufraw_data *uf, UFRawPhase phase,
+       gboolean bufferok)
 {
-    UFRawPhase phase;
-    int i;
-
-    phase = ufraw_develop_phase;
-    if (bufferok) {
-           /* It should never be necessary to actually finish the conversion
-            * because it can break render_preview_image() which uses the
-            * final image "valid" mask for deciding what to update in the
-            * pixbuf. That can be fixed but is suboptimal anyway. The best
-            * we can do is print a warning in case we need to finish the
-            * conversion and finish it here. */
-       if (uf->Images[phase].valid != 0xffffffff) {
-           g_warning("%s: fixing unfinished conversion.\n", G_STRFUNC);
-           for (i = 0; i < 32; ++i)
-               ufraw_convert_image_area(uf, i, phase);
-       }
-    } else {
-       if (uf->Images[phase].valid == 0)
-           ufraw_convert_prepare_buffers(uf);
-    }
-    return &uf->Images[phase];
-}
+    ufraw_convert_prepare_buffers(uf, phase);
+    // Find the closest phase that is actually rendered:
+    while (phase > ufraw_raw_phase && uf->Images[phase].buffer == NULL)
+       phase--;
 
-ufraw_image_data *ufraw_display_image(ufraw_data *uf, gboolean bufferok)
-{
-    UFRawPhase phase = ufraw_display_phase;
-    if (uf->developer->working2displayTransform == NULL)
-       phase = ufraw_develop_phase;
- 
     if (bufferok) {
-           /* It should never be necessary to actually finish the conversion
-            * because it can break render_preview_image() which uses the
-            * final image "valid" mask for deciding what to update in the
-            * pixbuf. That can be fixed but is suboptimal anyway. The best
-            * we can do is print a warning in case we need to finish the
-            * conversion and finish it here. */
+       /* It should never be necessary to actually finish the conversion
+        * because it can break render_preview_image() which uses the
+        * final image "valid" mask for deciding what to update in the
+        * pixbuf. That can be fixed but is suboptimal anyway. The best
+        * we can do is print a warning in case we need to finish the
+        * conversion and finish it here. */
        if (uf->Images[phase].valid != 0xffffffff) {
-           g_warning("%s: fixing unfinished conversion.\n", G_STRFUNC);
+           g_warning("%s: fixing unfinished conversion for phase %d.\n",
+                   G_STRFUNC, phase);
            int i;
            for (i = 0; i < 32; ++i)
                ufraw_convert_image_area(uf, i, phase);
        }
-    } else {
-       if (uf->Images[phase].valid == 0)
-           ufraw_convert_prepare_buffers(uf);
     }
     return &uf->Images[phase];
 }
 
-
 ufraw_image_data *ufraw_convert_image_area(ufraw_data *uf, unsigned saidx,
        UFRawPhase phase)
 {
@@ -1624,7 +1579,8 @@
     if (phase > ufraw_raw_phase) {
        in = ufraw_convert_image_area(uf, saidx, phase - 1);
     }
-
+    // ufraw_convert_prepare_buffers() may set out->buffer to NULL.
+    ufraw_convert_prepare_buffers(uf, phase);
     if (phase>ufraw_first_phase && out->buffer == NULL)
        return in; // skip phase
 
@@ -1638,21 +1594,17 @@
     switch (phase)
     {
         case ufraw_raw_phase:
-           if (out->valid != 0xffffffff) {
-               ufraw_convert_image_raw(uf, phase);
-               out->valid = 0xffffffff;
-           }
+           ufraw_convert_image_raw(uf, phase);
+           out->valid = 0xffffffff;
            return out;
 
         case ufraw_first_phase:
-           if (out->valid != 0xffffffff) {
-               ufraw_convert_image_first(uf, phase);
-               out->valid = 0xffffffff;
+           ufraw_convert_image_first(uf, phase);
+           out->valid = 0xffffffff;
 #ifdef HAVE_LENSFUN
-               UFRectangle area = { 0, 0, out->width, out->height };
-               ufraw_convert_image_vignetting(uf, out, &area);
+           UFRectangle allArea = { 0, 0, out->width, out->height };
+           ufraw_convert_image_vignetting(uf, out, &allArea);
 #endif /* HAVE_LENSFUN */
-           }
            return out;
 
         case ufraw_transform_phase:
@@ -1893,10 +1845,9 @@
 void ufraw_invalidate_whitebalance_layer(ufraw_data *uf)
 {
     ufraw_invalidate_layer(uf, ufraw_develop_phase);
-//    if (uf->Images[ufraw_raw_phase].valid) {
-       uf->Images[ufraw_raw_phase].valid = 0;
-       uf->Images[ufraw_raw_phase].invalidate_event = TRUE;
-//    }
+    uf->Images[ufraw_raw_phase].valid = 0;
+    uf->Images[ufraw_raw_phase].invalidate_event = TRUE;
+
     /* Despeckling is sensitive for WB changes because it is nonlinear. */
     if (ufraw_despeckle_active(uf))
        ufraw_invalidate_despeckle_layer(uf);
@@ -1912,15 +1863,6 @@
     ufraw_invalidate_layer(uf, ufraw_first_phase);
 }
 
-gboolean ufraw_invalidate_layer_event(ufraw_data *uf, UFRawPhase phase)
-{
-    gboolean ret;
-
-    ret = uf->Images[phase].invalidate_event;
-    uf->Images[phase].invalidate_event = FALSE;
-    return ret;
-}
-
 int ufraw_set_wb(ufraw_data *uf)
 {
     dcraw_data *raw = uf->raw;

Index: ufraw_preview.c
===================================================================
RCS file: /cvsroot/ufraw/ufraw/ufraw_preview.c,v
retrieving revision 1.318
retrieving revision 1.319
diff -u -d -r1.318 -r1.319
--- ufraw_preview.c     29 Nov 2009 13:40:11 -0000      1.318
+++ ufraw_preview.c     1 Dec 2009 03:30:57 -0000       1.319
@@ -516,7 +516,7 @@
 void scale_crop_to_final_image(ufraw_data *uf,
     int *x1, int *x2, int *y1, int *y2)
 {
-    ufraw_image_data *img = ufraw_final_image(uf, FALSE);
+    ufraw_image_data *img = ufraw_get_image(uf, ufraw_develop_phase, FALSE);
 
     float scale_x = ((float)img->width) / uf->rotatedWidth;
     float scale_y = ((float)img->height) / uf->rotatedHeight;
@@ -577,9 +577,10 @@
     /* This is bad. `img' should have been a parameter because we
      * cannot request an up to date buffer but it must be up to
      * date to some extend. In theory we could get the wrong buffer */
-    ufraw_image_data *displayImage = ufraw_display_image(data->UF, FALSE);
+    ufraw_image_data *displayImage = ufraw_get_image(data->UF, 
ufraw_display_phase, FALSE);
     guint8 *displayPixies = displayImage->buffer + x*displayImage->depth;
-    ufraw_image_data *workingImage = ufraw_final_image(data->UF, FALSE);
+    ufraw_image_data *workingImage = ufraw_get_image(data->UF,
+           ufraw_develop_phase, FALSE);
     guint8 *workingPixies = workingImage->buffer + x*workingImage->depth;
 
     int xx, yy, c;
@@ -789,7 +790,8 @@
     /* Check if we need a new pixbuf */
     int width = gdk_pixbuf_get_width(data->PreviewPixbuf);
     int height = gdk_pixbuf_get_height(data->PreviewPixbuf);
-    ufraw_image_data *image = ufraw_final_image(data->UF, FALSE);
+    ufraw_image_data *image = ufraw_get_image(data->UF,
+           ufraw_display_phase, FALSE);
     if (width!=image->width || height!=image->height) {
     
        /* Calculate current viewport center */
@@ -935,10 +937,8 @@
                &data->UF->displayProfileSize);
     }
     ufraw_developer_prepare(data->UF, display_developer);
-    ufraw_convert_prepare_buffers(data->UF);
-    if (ufraw_invalidate_layer_event(data->UF, ufraw_transform_phase)) {
-       render_init(data);
-    }
+    render_init(data);
+
     /* This will trigger the untiled phases if necessary. The progress bar
      * updates require gtk_main_iteration() calls which can only be
      * done when there are no pending idle tasks which could recurse
@@ -1064,18 +1064,18 @@
 {
     int subarea = -1;
     int max_area = -1;
-    int i;
-    ufraw_image_data *img;
-    GdkRectangle viewport;
 
     /* First of all, find the maximally visible yet unrendered subarea.
      * Refreshing visible subareas in the first place improves visual
      * feedback and overall user experience.
      */
-    img = ufraw_final_image(data->UF, FALSE);
+    ufraw_image_data *img = ufraw_get_image(data->UF,
+           ufraw_display_phase, FALSE);
+    GdkRectangle viewport;
     gtk_image_view_get_viewport(
         GTK_IMAGE_VIEW(data->PreviewWidget), &viewport);
 
+    int i;
     for (i = 0; i < 32; i++) {
         /* Skip valid subareas */
         if (img->valid & (1 << i))
@@ -1177,7 +1177,8 @@
     if (data->FreezeDialog) return FALSE;
 
     int x, y, c, min, max;
-    ufraw_image_data *img = ufraw_final_image(data->UF, TRUE);
+    ufraw_image_data *img = ufraw_get_image(data->UF,
+           ufraw_develop_phase, TRUE);
 
     int CropX1, CropX2, CropY1, CropY2;
     scale_crop_to_final_image(data->UF, &CropX1, &CropX2, &CropY1, &CropY2);
@@ -1323,28 +1324,26 @@
 
 static gboolean render_spot(preview_data *data)
 {
-    ufraw_image_data *img;
-    int rawDepth, outDepth, width, height;
-    void *rawBuffer, *outBuffer;
-    struct spot spot;
-
     if (data->FreezeDialog) return FALSE;
 
     if (data->SpotX1<0) return FALSE;
     if ( data->SpotX1>=data->UF->rotatedWidth ||
         data->SpotY1>=data->UF->rotatedHeight ) return FALSE;
-    img = ufraw_final_image(data->UF, TRUE);
-    width = img->width;
-    height = img->height;
-    outDepth = img->depth;
-    outBuffer = img->buffer;
-    img = ufraw_rgb_image(data->UF, TRUE, G_STRFUNC);
-    rawDepth = img->depth;
-    rawBuffer = img->buffer;
+    ufraw_image_data *img = ufraw_get_image(data->UF,
+           ufraw_develop_phase, TRUE);
+    int width = img->width;
+    int height = img->height;
+    int outDepth = img->depth;
+    void *outBuffer = img->buffer;
+    img = ufraw_get_image(data->UF, ufraw_transform_phase, TRUE);
+    int rawDepth = img->depth;
+    void *rawBuffer = img->buffer;
 
-    /* We assume that first_phase and final_phase buffer sizes are the same. */
+    /* We assume that transform_phase and develop_phase buffer sizes are the
+     * same. */
     /* Scale image coordinates to Images[ufraw_develop_phase] coordinates */
     /* TODO: explain and cleanup if necessary */
+    struct spot spot;
     calculate_spot(data, &spot, width, height);
 
     guint64 rawSum[4], outSum[3];
@@ -1615,7 +1614,8 @@
     height = gdk_pixbuf_get_height(data->PreviewPixbuf);
     /* Scale image coordinates to pixbuf coordinates */
     calculate_spot(data, &spot, width, height);
-    ufraw_image_data *image = ufraw_rgb_image(data->UF, TRUE, G_STRFUNC);
+    ufraw_image_data *image = ufraw_get_image(data->UF,
+           ufraw_transform_phase, TRUE);
 
     for (c=0; c<4; c++) rgb[c] = 0;
     for (y=spot.StartY; y<spot.EndY; y++)
@@ -1660,20 +1660,14 @@
 
 static void calculate_hue(preview_data *data, int i)
 {
-    ufraw_image_data *img;
-    int rawDepth;
-    void *rawBuffer;
-    float lch[3];
-    int width, height;
-    struct spot spot;
-
-    img = ufraw_final_image(data->UF, FALSE);
-    width = img->width;
-    height = img->height;
-    img = ufraw_rgb_image(data->UF, TRUE, G_STRFUNC);
-    rawDepth = img->depth;
-    rawBuffer = img->buffer;
+    ufraw_image_data *img = ufraw_get_image(data->UF,
+           ufraw_transform_phase, FALSE);
+    int width = img->width;
+    int height = img->height;
+    int rawDepth = img->depth;
+    void *rawBuffer = img->buffer;
 
+    struct spot spot;
     /* TODO: explain and cleanup if necessary */
     calculate_spot(data, &spot, width, height);
 
@@ -1691,6 +1685,7 @@
     for (c=0; c<data->UF->colors; c++)
        rawChannels[c] = rawSum[c] / spot.Size;
 
+    float lch[3];
     uf_raw_to_cielch(Developer, rawChannels, lch);
     CFG->lightnessAdjustment[i].hue = lch[2];
 
@@ -3159,7 +3154,6 @@
     }
     ufraw_invalidate_layer(data->UF, ufraw_transform_phase);
 
-    render_init(data);
     if (CFG->CropX2 > data->UF->rotatedWidth)
        fix_crop_aspect(data, top_right_cursor, FALSE);
     else if (CFG->CropY2 > data->UF->rotatedHeight)
@@ -5853,10 +5847,11 @@
     /* This will start the conversion and enqueue rendering functions */
     update_scales(data);
     render_preview_now(data);
-    update_crop_ranges(data, FALSE);   // calls ufraw_final_image(uf, FALSE)
+    update_crop_ranges(data, FALSE);
 
     /* Collect raw histogram data */
-    ufraw_image_data *image = ufraw_rgb_image(data->UF, TRUE, G_STRFUNC);
+    ufraw_image_data *image = ufraw_get_image(data->UF,
+           ufraw_first_phase, TRUE);
     for (i=0; i<image->height*image->width; i++) {
            guint16 *buf = (guint16*)(image->buffer+i*image->depth);
            for (c=0; c<data->UF->colors; c++)


------------------------------------------------------------------------------
Join us December 9, 2009 for the Red Hat Virtual Experience,
a free event focused on virtualization and cloud computing. 
Attend in-depth sessions from your desk. Your couch. Anywhere.
http://p.sf.net/sfu/redhat-sfdev2dev
_______________________________________________
ufraw-cvs mailing list
ufraw-cvs@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ufraw-cvs

Reply via email to