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