Update of /cvsroot/ufraw/ufraw In directory ddv4jf1.ch3.sourceforge.com:/tmp/cvs-serv1901
Modified Files: ufraw.h ufraw_lens_ui.c ufraw_preview.c ufraw_ufraw.c ufraw_writer.c Log Message: Apply rotation together with lensfun. lensfun_phase was renamed to transfrom_phase accordingly. Index: ufraw.h =================================================================== RCS file: /cvsroot/ufraw/ufraw/ufraw.h,v retrieving revision 1.136 retrieving revision 1.137 diff -u -d -r1.136 -r1.137 --- ufraw.h 11 Nov 2009 02:09:23 -0000 1.136 +++ ufraw.h 21 Nov 2009 05:51:59 -0000 1.137 @@ -68,7 +68,7 @@ DeveloperMode; typedef enum { perceptual_intent, relative_intent, saturation_intent, absolute_intent, disable_intent } Intent; -typedef enum { ufraw_raw_phase, ufraw_first_phase, ufraw_lensfun_phase, +typedef enum { ufraw_raw_phase, ufraw_first_phase, ufraw_transform_phase, ufraw_develop_phase, ufraw_display_phase, ufraw_phases_num } UFRawPhase; typedef enum { grayscale_none, grayscale_lightness, grayscale_luminance, grayscale_value, grayscale_mixer } GrayscaleMode; @@ -290,8 +290,8 @@ #ifdef HAVE_LENSFUN int modFlags; /* postprocessing operations (LF_MODIFY_XXX) */ lfModifier *modifier; - void *lanczos_func; /* the Lanczos kernel */ #endif /* HAVE_LENSFUN */ + void *lanczos_func; /* the Lanczos kernel */ int hotpixels; gboolean mark_hotpixels; unsigned raw_multiplier; @@ -313,11 +313,9 @@ 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); -void ufraw_convert_image_raw(ufraw_data *uf, UFRawPhase phase); -void ufraw_convert_image_first(ufraw_data *uf, UFRawPhase phase); #ifdef HAVE_LENSFUN -void ufraw_prepare_lensfun(ufraw_data *uf, UFRawPhase phase); void ufraw_lensfun_init(ufraw_data *uf); #endif void ufraw_image_format(int *colors, int *bytes, ufraw_image_data *img, @@ -329,7 +327,8 @@ ufraw_image_data *ufraw_convert_image_area(ufraw_data *uf, unsigned saidx, UFRawPhase phase); void ufraw_close(ufraw_data *uf); -int ufraw_flip_image(ufraw_data *uf, int flip); +void ufraw_flip_orientation(ufraw_data *uf, int flip); +void ufraw_flip_image(ufraw_data *uf, int flip); void ufraw_invalidate_layer(ufraw_data *uf, UFRawPhase phase); void ufraw_invalidate_hotpixel_layer(ufraw_data *uf); void ufraw_invalidate_denoise_layer(ufraw_data *uf); @@ -342,9 +341,6 @@ void ufraw_auto_expose(ufraw_data *uf); void ufraw_auto_black(ufraw_data *uf); void ufraw_auto_curve(ufraw_data *uf); -void ufraw_rotate_row(ufraw_image_data *image, void *pixbuf, double angle, - int bitDepth, int row, int offset, int width); -void ufraw_rotate_image_buffer(ufraw_image_data *img, double angle); void ufraw_normalize_rotation(ufraw_data *uf); void ufraw_unnormalize_rotation(ufraw_data *uf); void ufraw_get_image_dimensions(ufraw_data *uf); Index: ufraw_writer.c =================================================================== RCS file: /cvsroot/ufraw/ufraw/ufraw_writer.c,v retrieving revision 1.66 retrieving revision 1.67 diff -u -d -r1.66 -r1.67 --- ufraw_writer.c 4 Nov 2009 02:48:54 -0000 1.66 +++ ufraw_writer.c 21 Nov 2009 05:51:59 -0000 1.67 @@ -215,71 +215,25 @@ int byteDepth = (bitDepth+7)/8; guint8 pixbuf8[width * 3 * byteDepth * DEVELOP_BATCH]; - if (uf->conf->rotationAngle != 0) { - // Buffer for unrotated image. - ufraw_image_data image; - image.width = uf->Images[ufraw_first_phase].width; - image.height = uf->Images[ufraw_first_phase].height; - image.depth = 6; - image.rowstride = image.width * image.depth; - image.buffer = g_new(guint8, image.height * image.rowstride); - // Develop complete raw image into buffer. -#ifdef _OPENMP -#pragma omp parallel for schedule(static,1) default(shared) private(row0) -#endif - for (row0 = 0; row0 < image.height; row0 += DEVELOP_BATCH) { - if (uf_omp_get_thread_num() == 0) - preview_progress(uf->widget, _("Converting image"), - 0.5 * row0/image.height); - guint8 *rowbuf = &image.buffer[row0*image.rowstride]; - develop(rowbuf, rawImage[row0*rowStride], - uf->developer, 16, - MIN(image.height - row0, DEVELOP_BATCH) * image.width); - } - // Write rotated image to output. - for (row0 = 0; row0 < height; row0 += DEVELOP_BATCH) { - preview_progress(uf->widget, _("Saving image"), - 0.5 + 0.5*row0/height); -#ifdef _OPENMP -#pragma omp parallel for default(shared) private(row) -#endif - for (row = 0; row < DEVELOP_BATCH; row++) { - if (row + row0 >= height) - continue; - guint8 *rowbuf = &pixbuf8[row * width * 3 * byteDepth]; - ufraw_rotate_row(&image, rowbuf, uf->conf->rotationAngle, - bitDepth, top+row+row0, left, width); - if (grayscaleMode) - grayscale_buffer(rowbuf, width, bitDepth); - } - int batchHeight = MIN(height-row0, DEVELOP_BATCH); - if ( row_writer(uf, out, pixbuf8, row0, width, batchHeight, - grayscaleMode, bitDepth) != UFRAW_SUCCESS ) - break; - } - g_free(image.buffer); - } else { - // No rotation required. Develop straight to output. - for (row0 = 0; row0 < height; row0 += DEVELOP_BATCH) { - preview_progress(uf->widget, _("Saving image"), + for (row0 = 0; row0 < height; row0 += DEVELOP_BATCH) { + preview_progress(uf->widget, _("Saving image"), 0.5 + 0.5*row0/height); #ifdef _OPENMP #pragma omp parallel for default(shared) private(row) #endif - for (row = 0; row < DEVELOP_BATCH; row++) { - if (row + row0 >= height) - continue; - guint8 *rowbuf = &pixbuf8[row * width * 3 * byteDepth]; - develop(rowbuf, rawImage[(top+row+row0)*rowStride+left], + for (row = 0; row < DEVELOP_BATCH; row++) { + if (row + row0 >= height) + continue; + guint8 *rowbuf = &pixbuf8[row * width * 3 * byteDepth]; + develop(rowbuf, rawImage[(top+row+row0)*rowStride+left], uf->developer, bitDepth, width); - if (grayscaleMode) - grayscale_buffer(rowbuf, width, bitDepth); - } - int batchHeight = MIN(height-row0, DEVELOP_BATCH); - if ( row_writer(uf, out, pixbuf8, row0, width, batchHeight, - grayscaleMode, bitDepth) != UFRAW_SUCCESS ) - break; + if (grayscaleMode) + grayscale_buffer(rowbuf, width, bitDepth); } + int batchHeight = MIN(height-row0, DEVELOP_BATCH); + if ( row_writer(uf, out, pixbuf8, row0, width, batchHeight, + grayscaleMode, bitDepth) != UFRAW_SUCCESS ) + break; } } @@ -377,15 +331,15 @@ // TODO: error handling ufraw_convert_image(uf); ufraw_image_data *FirstImage = &uf->Images[ufraw_first_phase]; - left = uf->conf->CropX1 * FirstImage->width / uf->initialWidth; - top = uf->conf->CropY1 * FirstImage->height / uf->initialHeight; + left = uf->conf->CropX1 * FirstImage->width / uf->rotatedWidth; + top = uf->conf->CropY1 * FirstImage->height / uf->rotatedHeight; volatile int BitDepth = uf->conf->profile[out_profile] [uf->conf->profileIndex[out_profile]].BitDepth; if ( BitDepth!=16 ) BitDepth = 8; width = (uf->conf->CropX2 - uf->conf->CropX1) - * FirstImage->width / uf->initialWidth; + * FirstImage->width / uf->rotatedWidth; height = (uf->conf->CropY2 - uf->conf->CropY1) - * FirstImage->height / uf->initialHeight; + * FirstImage->height / uf->rotatedHeight; if ( uf->conf->type==ppm_type && BitDepth==8 ) { fprintf(out, "P%c\n%d %d\n%d\n", grayscaleMode ? '5' : '6', width, height, 0xFF); Index: ufraw_lens_ui.c =================================================================== RCS file: /cvsroot/ufraw/ufraw/ufraw_lens_ui.c,v retrieving revision 1.20 retrieving revision 1.21 diff -u -d -r1.20 -r1.21 --- ufraw_lens_ui.c 17 Nov 2009 05:05:06 -0000 1.20 +++ ufraw_lens_ui.c 21 Nov 2009 05:51:59 -0000 1.21 @@ -339,7 +339,7 @@ if (data->UF->modFlags & LF_MODIFY_VIGNETTING) ufraw_invalidate_layer(data->UF, ufraw_first_phase); else - ufraw_invalidate_layer(data->UF, ufraw_lensfun_phase); + ufraw_invalidate_layer(data->UF, ufraw_transform_phase); render_preview (data); } @@ -615,7 +615,7 @@ { preview_data *data = get_preview_data (adj); *valuep = gtk_adjustment_get_value (adj); - ufraw_invalidate_layer(data->UF, ufraw_lensfun_phase); + ufraw_invalidate_layer(data->UF, ufraw_transform_phase); render_preview (data); } @@ -624,7 +624,7 @@ (void)user_data; preview_data *data = get_preview_data (button); gtk_adjustment_set_value (data->LensScaleAdjustment, 0.0); - ufraw_invalidate_layer(data->UF, ufraw_lensfun_phase); + ufraw_invalidate_layer(data->UF, ufraw_transform_phase); render_preview (data); } @@ -640,7 +640,7 @@ float as = lf_modifier_get_auto_scale (data->UF->modifier, 0); gtk_adjustment_set_value (data->LensScaleAdjustment, log (cs * as) / log (2.0)); - ufraw_invalidate_layer(data->UF, ufraw_lensfun_phase); + ufraw_invalidate_layer(data->UF, ufraw_transform_phase); render_preview (data); } } @@ -670,7 +670,7 @@ remove_tca_models (data, CFG->lens_tca.Model); lf_lens_add_calib_tca (CFG->lens, &CFG->lens_tca); - ufraw_invalidate_layer(data->UF, ufraw_lensfun_phase); + ufraw_invalidate_layer(data->UF, ufraw_transform_phase); render_preview (data); } @@ -708,7 +708,7 @@ gtk_label_set_text (GTK_LABEL (data->LensTCADesc), details); gtk_widget_show_all (data->LensTCATable); - ufraw_invalidate_layer(data->UF, ufraw_lensfun_phase); + ufraw_invalidate_layer(data->UF, ufraw_transform_phase); render_preview (data); } @@ -896,7 +896,7 @@ remove_dist_models (data, CFG->lens_distortion.Model); lf_lens_add_calib_distortion (CFG->lens, &CFG->lens_distortion); - ufraw_invalidate_layer(data->UF, ufraw_lensfun_phase); + ufraw_invalidate_layer(data->UF, ufraw_transform_phase); render_preview (data); } @@ -934,7 +934,7 @@ gtk_label_set_text (GTK_LABEL (data->LensDistortionDesc), details); gtk_widget_show_all (data->LensDistortionTable); - ufraw_invalidate_layer(data->UF, ufraw_lensfun_phase); + ufraw_invalidate_layer(data->UF, ufraw_transform_phase); render_preview (data); } @@ -1006,7 +1006,7 @@ else gtk_label_set_text (GTK_LABEL (data->LensFromGeometryDesc), details); - ufraw_invalidate_layer(data->UF, ufraw_lensfun_phase); + ufraw_invalidate_layer(data->UF, ufraw_transform_phase); render_preview (data); } Index: ufraw_ufraw.c =================================================================== RCS file: /cvsroot/ufraw/ufraw/ufraw_ufraw.c,v retrieving revision 1.217 retrieving revision 1.218 diff -u -d -r1.217 -r1.218 --- ufraw_ufraw.c 19 Nov 2009 05:44:21 -0000 1.217 +++ ufraw_ufraw.c 21 Nov 2009 05:51:59 -0000 1.218 @@ -40,12 +40,16 @@ static void ufraw_convert_image_vignetting(ufraw_data *uf, ufraw_image_data *img, UFRectangle *area); -static void ufraw_convert_image_lensfun(ufraw_data *uf, ufraw_image_data *img, - ufraw_image_data *outimg, UFRectangle *area); #endif +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, + ufraw_image_data *outimg, UFRectangle *area); +static void ufraw_prepare_transform(ufraw_data *uf); +static void ufraw_convert_prepare_transform_buffer(ufraw_data *uf, + ufraw_image_data *img, int width, int height); static void ufraw_convert_reverse_wb(ufraw_data *uf, UFRawPhase phase); static void ufraw_convert_import_buffer(ufraw_data *uf, UFRawPhase phase, dcraw_image_data *dcimg); -static void ufraw_convert_prepare_buffers(ufraw_data *uf); static int make_temporary(char *basefilename, char **tmpfilename) { @@ -741,32 +745,28 @@ ufraw_developer_prepare(uf, file_developer); ufraw_convert_image_raw(uf, ufraw_raw_phase); ufraw_convert_image_first(uf, ufraw_first_phase); + ufraw_image_data *img = &uf->Images[ufraw_first_phase]; + UFRectangle area = { 0, 0, img->width, img->height }; #ifdef HAVE_LENSFUN - ufraw_prepare_lensfun(uf, ufraw_first_phase); + ufraw_prepare_transform(uf); if (uf->modifier != NULL) { - ufraw_image_data *img = &uf->Images[ufraw_first_phase]; - UFRectangle area = { 0, 0, img->width, img->height }; ufraw_convert_image_vignetting(uf, img, &area); - if ((uf->modFlags & (UF_LF_ALL & ~LF_MODIFY_VIGNETTING)) != 0) { - /* Apply distortion, TCA and geometry */ - ufraw_image_data *img2 = &uf->Images[ufraw_lensfun_phase]; - img2->height = img->height; - img2->width = img->width; - img2->depth = img->depth; - img2->rowstride = img2->width * img2->depth; - img2->buffer = g_realloc(img2->buffer, img2->height * img2->rowstride); - ufraw_convert_image_lensfun(uf, img, img2, &area); - g_free(img->buffer); - img->buffer = img2->buffer; - img2->buffer = NULL; - } } #endif + ufraw_image_data *img2 = &uf->Images[ufraw_transform_phase]; + ufraw_convert_prepare_transform_buffer(uf, img2, img->width, img->height); + if (img2->buffer != NULL) { + area.width = img2->width; + area.height = img2->height; + /* Apply distortion, TCA, geometry and rotation */ + ufraw_convert_image_transform(uf, img, img2, &area); + g_free(img->buffer); + *img = *img2; + img2->buffer = NULL; + } return UFRAW_SUCCESS; } -#ifdef HAVE_LENSFUN - /* Lanczos kernel is precomputed in a table with this resolution * The value below seems to be enough for HQ upscaling up to eight times */ @@ -789,6 +789,7 @@ #define LANCZOS_DATA_ONE 4096 #endif +#ifdef HAVE_LENSFUN static void ufraw_convert_image_vignetting(ufraw_data *uf, ufraw_image_data *img, UFRectangle *area) { @@ -799,35 +800,52 @@ area->x, area->y, area->width, area->height, LF_CR_4(RED, GREEN, BLUE, UNKNOWN), img->rowstride); } +#endif -static void ufraw_convert_image_lensfun(ufraw_data *uf, ufraw_image_data *img, +/* Apply distortion, TCA, geometry and rotation in a single pass */ +static void ufraw_convert_image_transform(ufraw_data *uf, ufraw_image_data *img, ufraw_image_data *outimg, UFRectangle *area) { - /* Now apply distortion, TCA and geometry in a single pass */ - if ((uf->modFlags & (UF_LF_ALL & ~LF_MODIFY_VIGNETTING)) == 0) - return; + double sine = sin(uf->conf->rotationAngle * 2 * M_PI / 360); + double cosine = cos(uf->conf->rotationAngle * 2 * M_PI / 360); /* Use precomputed Lanczos kernel */ LANCZOS_DATA_TYPE *lanczos_func = uf->lanczos_func; int x, y, c; - float *buff = g_alloca(area->width * 3 * 2 * sizeof(float)); - for (y = area->y; y < area->y + area->height; y++) { - if (!lf_modifier_apply_subpixel_geometry_distortion(uf->modifier, - area->x, y, area->width, 1, buff)) - g_error("ufraw_convert_image_lensfun: " - "lf_modifier_apply_subpixel_geometry_distortion() failed"); +#ifdef HAVE_LENSFUN + gboolean applyLF = uf->modifier != NULL && + (uf->modFlags & (UF_LF_ALL & ~LF_MODIFY_VIGNETTING)); +#endif - float *modcoord = buff; + for (y = area->y; y < area->y + area->height; y++) { + guint8 *cur0 = outimg->buffer + y * outimg->rowstride; + float srcX0 = y*sine - img->height*sine*cosine; + float srcY0 = y*cosine + img->height*sine*sine; for (x = area->x; x < area->x + area->width; x++) { - guint16 *cur = (guint16 *)(outimg->buffer + - y * outimg->rowstride + x * outimg->depth); + guint16 *cur = (guint16 *)(cur0 + x * outimg->depth); + float srcX = srcX0 + x*cosine; + float srcY = srcY0 - x*sine; +#ifdef HAVE_LENSFUN + float buff[3 * 2]; + float *modcoord = buff; + if (applyLF) { + lf_modifier_apply_subpixel_geometry_distortion(uf->modifier, + srcX, srcY, 1, 1, buff); + } +#endif for (c = 0; c < 3; c++, modcoord += 2) { +#ifdef HAVE_LENSFUN + if (applyLF) { + srcX = modcoord[0]; + srcY = modcoord[1]; + } +#endif #ifdef LANCZOS_DATA_FLOAT - float xs = ceilf(modcoord[0]) - LANCZOS_SUPPORT; - float xe = floorf(modcoord[0]) + LANCZOS_SUPPORT; - float ys = ceilf(modcoord[1]) - LANCZOS_SUPPORT; - float ye = floorf(modcoord[1]) + LANCZOS_SUPPORT; + float xs = ceilf(srcX) - LANCZOS_SUPPORT; + float xe = floorf(srcX) + LANCZOS_SUPPORT; + float ys = ceilf(srcY) - LANCZOS_SUPPORT; + float ye = floorf(srcY) + LANCZOS_SUPPORT; if (xs < 0 || ys < 0 || xe >= img->width || ye >= img->height) { cur[c] = 0; continue; @@ -839,8 +857,8 @@ float norm = 0.0; float sum = 0.0; - float _dx = modcoord[0] - xs; - float dy = modcoord[1] - ys; + float _dx = srcX - xs; + float dy = srcY - ys; for (; ys <= ye; ys += 1.0, dy -= 1.0) { float xc, dx = _dx; for (xc = xs; xc <= xe; xc += 1.0, dx -= 1.0, src++) { @@ -860,8 +878,8 @@ cur[c] = 0; #else /* Do it in integer arithmetic, it's faster */ - int xx = (int)modcoord[0]; - int yy = (int)modcoord[1]; + int xx = (int)srcX; + int yy = (int)srcY; int xs = xx + 1 - LANCZOS_SUPPORT; int xe = xx + LANCZOS_SUPPORT; int ys = yy + 1 - LANCZOS_SUPPORT; @@ -877,8 +895,8 @@ int norm = 0; int sum = 0; - int _dx = (int)(modcoord[0] * 4096.0) - (xs << 12); - int dy = (int)(modcoord[1] * 4096.0) - (ys << 12); + int _dx = (int)(srcX * 4096.0) - (xs << 12); + int dy = (int)(srcY * 4096.0) - (ys << 12); for (; ys <= ye; ys++, dy -= 4096) { int xc, dx = _dx; for (xc = xs; xc <= xe; xc++, src++, dx -= 4096) { @@ -902,8 +920,6 @@ } } -#endif /* HAVE_LENSFUN */ - /* * A pixel with a significantly larger value than all of its four direct * neighbours is considered "hot". It will be replaced by the maximum value @@ -1145,7 +1161,7 @@ * dcraw_wavelet_denoise() too should change to accept a phase argument and * no longer require type casts. */ -void ufraw_convert_image_raw(ufraw_data *uf, UFRawPhase phase) +static void ufraw_convert_image_raw(ufraw_data *uf, UFRawPhase phase) { ufraw_image_data *img = &uf->Images[phase]; dcraw_data *dark = uf->conf->darkframe ? uf->conf->darkframe->raw : NULL; @@ -1169,7 +1185,7 @@ * Interface of ufraw_convertshrink() and dcraw_flip_image() should change * to accept a phase argument and no longer require type casts. */ -void ufraw_convert_image_first(ufraw_data *uf, UFRawPhase phase) +static void ufraw_convert_image_first(ufraw_data *uf, UFRawPhase phase) { ufraw_image_data *in = &uf->Images[phase - 1]; ufraw_image_data *out = &uf->Images[phase]; @@ -1278,9 +1294,11 @@ static void ufraw_image_init(ufraw_image_data *img, int width, int height, int bitdepth) { - if (img->height != height || img->width != width || img->buffer == NULL) - img->valid = 0; + if (img->height == height && img->width == width && + img->depth == bitdepth && img->buffer != NULL) + return; + img->valid = 0; img->height = height; img->width = width; img->depth = bitdepth; @@ -1288,38 +1306,94 @@ img->buffer = g_realloc(img->buffer, img->height * img->rowstride); } +static void ufraw_convert_prepare_transform_buffer(ufraw_data *uf, + ufraw_image_data *img, int width, int height) +{ + ufraw_prepare_transform(uf); +#ifdef HAVE_LENSFUN + if (uf->conf->rotationAngle == 0 && + (uf->modifier == NULL || + !(uf->modFlags & (UF_LF_ALL & ~LF_MODIFY_VIGNETTING)))) +#else + if (uf->conf->rotationAngle == 0) +#endif /* HAVE_LENSFUN */ + { + g_free(img->buffer); + img->buffer = NULL; + } else { + double sine = sin(uf->conf->rotationAngle * 2 * M_PI / 360); + double cosine = cos(uf->conf->rotationAngle * 2 * M_PI / 360); + int newWidth = ceil((height * sine) + (width * cosine)); + int newHeight = ceil((width * sine) + (height * cosine)); + width = newWidth; + height = newHeight; + ufraw_image_init(img, width, height, 8); + } +} + /* * This function does not set img->invalidate_event because the * invalidation here is a secondary effect of the need to resize * buffers. The invalidate events should all have been set already. */ -static void ufraw_convert_prepare_buffers(ufraw_data *uf) +void ufraw_convert_prepare_buffers(ufraw_data *uf) { - ufraw_image_data *FirstImage = &uf->Images[ufraw_first_phase]; - -#ifdef HAVE_LENSFUN - ufraw_image_init(&uf->Images[ufraw_lensfun_phase], - FirstImage->width, FirstImage->height, 8); -#endif /* HAVE_LENSFUN */ + ufraw_image_data *img = &uf->Images[ufraw_first_phase]; + // Buffers can be prepared only after first image is generated. + // If first image is not valid we can easily skip the buffer + // preparation since it will be prepared after first image generation. + if (img->valid != 0xffffffff) + return; - ufraw_image_init(&uf->Images[ufraw_develop_phase], - FirstImage->width, FirstImage->height, 3); + int width = img->width; + int height = img->height; - ufraw_image_init(&uf->Images[ufraw_display_phase], - FirstImage->width, FirstImage->height, 3); - // TODO: We should be able to allocate a buffer only if it is needed. -// if (uf->developer->working2displayTransform == NULL) { -// g_free(img->buffer); -// img->buffer = NULL; -// } else { -// img->buffer = g_realloc(img->buffer, img->height * img->rowstride); -// } + img = &uf->Images[ufraw_transform_phase]; + if (img->valid == 0) { + 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) { + ufraw_image_init(img, width, height, 3); + } + img = &uf->Images[ufraw_display_phase]; + if (img->valid == 0) { + if (uf->developer->working2displayTransform == NULL) { + g_free(img->buffer); + img->buffer = NULL; + } else { + ufraw_image_init(img, width, height, 3); + } + } } -#ifdef HAVE_LENSFUN -void ufraw_prepare_lensfun(ufraw_data *uf, UFRawPhase phase) +static void ufraw_prepare_transform(ufraw_data *uf) { - ufraw_image_data *img = &uf->Images[phase]; + if (uf->lanczos_func == NULL) { + /* Precompute the Lanczos kernel */ + LANCZOS_DATA_TYPE *lanczos_func = g_new(LANCZOS_DATA_TYPE, + LANCZOS_SUPPORT * LANCZOS_SUPPORT * LANCZOS_TABLE_RES); + uf->lanczos_func = lanczos_func; + int i; + for (i = 0; i < LANCZOS_SUPPORT*LANCZOS_SUPPORT * LANCZOS_TABLE_RES; + i++) { + if (i == 0) { + lanczos_func[i] = LANCZOS_DATA_ONE; + } else { + float d = sqrt((float)i / LANCZOS_TABLE_RES); + lanczos_func[i] = (LANCZOS_DATA_TYPE)( + LANCZOS_DATA_ONE * LANCZOS_SUPPORT * + sin(M_PI * d) * sin(M_PI / LANCZOS_SUPPORT * d) / + (M_PI * M_PI * d * d) ); + } + } + } +#ifdef HAVE_LENSFUN + ufraw_image_data *img = &uf->Images[ufraw_first_phase]; conf_data *conf = uf->conf; if (uf->modifier != NULL) @@ -1342,27 +1416,8 @@ lf_modifier_destroy(uf->modifier); uf->modifier = NULL; } - - if (uf->lanczos_func != NULL) - return; - /* Precompute the Lanczos kernel */ - LANCZOS_DATA_TYPE *lanczos_func = g_new(LANCZOS_DATA_TYPE, - LANCZOS_SUPPORT * LANCZOS_SUPPORT * LANCZOS_TABLE_RES); - uf->lanczos_func = lanczos_func; - int i; - for (i = 0; i < LANCZOS_SUPPORT*LANCZOS_SUPPORT * LANCZOS_TABLE_RES; i++) { - if (i == 0) { - lanczos_func[i] = LANCZOS_DATA_ONE; - } else { - float d = sqrt((float)i / LANCZOS_TABLE_RES); - lanczos_func[i] = (LANCZOS_DATA_TYPE)( - LANCZOS_DATA_ONE * LANCZOS_SUPPORT * - sin(M_PI * d) * sin(M_PI / LANCZOS_SUPPORT * d) / - (M_PI * M_PI * d * d) ); - } - } -} #endif /* HAVE_LENSFUN */ +} /* * This function is very permissive in accepting NULL pointers but it does @@ -1415,7 +1470,7 @@ #ifdef HAVE_LENSFUN if (uf->modifier && (uf->modFlags & (UF_LF_ALL & ~LF_MODIFY_VIGNETTING))) - phase = ufraw_lensfun_phase; + phase = ufraw_transform_phase; #endif /* HAVE_LENSFUN */ int i; @@ -1501,18 +1556,22 @@ if (out->valid & (1 << saidx)) return out; // the subarea has been already computed - /* Get subarea coordinates */ - UFRectangle area = ufraw_image_get_subarea_rectangle(out, saidx); - guint8 *dest = out->buffer + area.y*out->rowstride + area.x*out->depth; - /* Get the subarea image for previous phase */ ufraw_image_data *in = NULL; - guint8 *src = NULL; if (phase > ufraw_raw_phase) { in = ufraw_convert_image_area(uf, saidx, phase - 1); - src = in->buffer + area.y*in->rowstride + area.x*in->depth; } + if (phase>ufraw_first_phase && out->buffer == NULL) + return in; // skip phase + + /* Get subarea coordinates */ + UFRectangle area = ufraw_image_get_subarea_rectangle(out, saidx); + guint8 *dest = out->buffer + area.y*out->rowstride + area.x*out->depth; + guint8 *src = NULL; + if (in != NULL) + src = in->buffer + area.y*in->rowstride + area.x*in->depth; + switch (phase) { case ufraw_raw_phase: @@ -1525,28 +1584,17 @@ case ufraw_first_phase: if (out->valid != 0xffffffff) { ufraw_convert_image_first(uf, phase); - ufraw_rotate_image_buffer(&uf->Images[phase], - uf->conf->rotationAngle); + out->valid = 0xffffffff; ufraw_convert_prepare_buffers(uf); #ifdef HAVE_LENSFUN - ufraw_prepare_lensfun(uf, ufraw_lensfun_phase); - ufraw_image_data *img = &uf->Images[ufraw_first_phase]; - UFRectangle area = { 0, 0, img->width, img->height }; - ufraw_convert_image_vignetting(uf, img, &area); + UFRectangle area = { 0, 0, out->width, out->height }; + ufraw_convert_image_vignetting(uf, out, &area); #endif /* HAVE_LENSFUN */ - out->valid = 0xffffffff; } return out; - case ufraw_lensfun_phase: -#ifdef HAVE_LENSFUN + case ufraw_transform_phase: { - if (uf->modifier == NULL || - !(uf->modFlags & (UF_LF_ALL & ~LF_MODIFY_VIGNETTING))) { -// out->valid = in->valid; /* for invalidate_event */ - return in; - } - /* Area calculation is not needed at the moment since * ufraw_first_phase is not tiled yet. */ /* @@ -1578,12 +1626,9 @@ ufraw_convert_image_area (uf, idx, phase - 1); } */ - ufraw_convert_image_lensfun(uf, in, out, &area); + ufraw_convert_image_transform(uf, in, out, &area); } break; -#else /* HAVE_LENSFUN */ - return in; -#endif /* HAVE_LENSFUN */ case ufraw_develop_phase: for (yy = 0; yy < area.height; yy++, dest += out->rowstride, @@ -1593,9 +1638,6 @@ break; case ufraw_display_phase: - if (uf->developer->working2displayTransform == NULL) - return in; - for (yy = 0; yy < area.height; yy++, dest += out->rowstride, src += in->rowstride) { develop_display(dest, src, uf->developer, area.width); @@ -1616,8 +1658,10 @@ return out; } -static int ufraw_flip_image_buffer(ufraw_image_data *img, int flip) +static void ufraw_flip_image_buffer(ufraw_image_data *img, int flip) { + if (img->buffer == NULL) + return; /* Following code was copied from dcraw's flip_image() * and modified to work with any pixel depth. */ int base, dest, next, row, col; @@ -1659,10 +1703,9 @@ img->width = height; img->rowstride = height * depth; } - return UFRAW_SUCCESS; } -static void ufraw_flip_orientation(ufraw_data *uf, int flip) +void ufraw_flip_orientation(ufraw_data *uf, int flip) { const char flipMatrix[8][8] = { { 0, 1, 2, 3, 4, 5, 6, 7 }, /* No flip */ @@ -1732,8 +1775,10 @@ uf->conf->rotationAngle = remainder(uf->conf->rotationAngle, 360.0); } -int ufraw_flip_image(ufraw_data *uf, int flip) +void ufraw_flip_image(ufraw_data *uf, int flip) { + if (flip == 0) + return; ufraw_flip_orientation(uf, flip); /* Usually orientation is applied before rotationAngle. * Here we are flipping after rotationAngle was applied. @@ -1744,26 +1789,16 @@ uf->conf->rotationAngle = -uf->conf->rotationAngle; ufraw_normalize_rotation(uf); } - ufraw_flip_image_buffer(&uf->Images[ufraw_first_phase], flip); -#ifdef HAVE_LENSFUN - if (uf->modifier && - (uf->modFlags & (UF_LF_ALL & ~LF_MODIFY_VIGNETTING))) - ufraw_flip_image_buffer(&uf->Images[ufraw_lensfun_phase], flip); -#endif /* HAVE_LENSFUN */ - ufraw_flip_image_buffer(&uf->Images[ufraw_develop_phase], flip); - if (uf->developer->working2displayTransform != NULL) - ufraw_flip_image_buffer(&uf->Images[ufraw_display_phase], flip); - - return UFRAW_SUCCESS; + UFRawPhase phase; + for (phase = ufraw_first_phase; phase < ufraw_phases_num; phase++) + ufraw_flip_image_buffer(&uf->Images[phase], flip); } void ufraw_invalidate_layer(ufraw_data *uf, UFRawPhase phase) { for (; phase < ufraw_phases_num; phase++) { -// if (uf->Images[phase].valid != 0) { - uf->Images[phase].valid = 0; - uf->Images[phase].invalidate_event = TRUE; -// } + uf->Images[phase].valid = 0; + uf->Images[phase].invalidate_event = TRUE; } } @@ -2176,127 +2211,3 @@ curve->m_numAnchors = j+1; } } - -void ufraw_rotate_row(ufraw_image_data *image, void *pixbuf, double angle, - int bitDepth, int row, int offset, int width) -{ - int col, ur, uc, i, j, in_image; - float r, c, fr, fc; - guint16 (*input)[3] = (guint16 (*)[3]) image->buffer; - guint16 (*iPix[2][2])[3]; - guint16 pixValue; - guint8 (*oPix8)[3] = (guint8 (*)[3]) pixbuf; - guint16 (*oPix16)[3] = (guint16 (*)[3]) pixbuf; - double rotationRadians = (angle * 2 * M_PI) / 360; - double sine = sin(rotationRadians); - double cosine = cos(rotationRadians); - guint16 bgcolor[3] = {0, 0, 0}; - - for (col = 0; col < width; col++) { - // Find co-ordinates of output pixel in input image: - // c, r are the ideal subpixel co-ordinates. - // uc, ur are the integer co-ordinates to the top and left of c, r. - uc = (int)floor(c = row*sine + (offset+col)*cosine - - image->height*sine*cosine); - ur = (int)floor(r = row*cosine -(offset+col)*sine - + image->height*sine*sine); - // Differences between the ideal and integer co-ordinates, for weighting. - fr = r - ur; - fc = c - uc; - // Whether this pixel is within the image at all. Set in next loop. - in_image = 0; - // Find pointers to the four pixels surrouding the ideal co-ordinate, - // either from the input image or the background color. - for (i = 0; i < 2; i++) - for (j = 0; j < 2; j++) - if (((uc+i) >= 0) && ((uc+i) <= image->width - 1) && - ((ur+j) >= 0) && ((ur+j) <= image->height - 1)) { - iPix[i][j] = &input[(ur+j)*image->width + uc+i]; - in_image = 1; - } else iPix[i][j] = &bgcolor; - // Write output pixel. - for (i = 0; i < 3; i++) { - if (in_image) - pixValue = (guint16)( - ((*iPix[0][0])[i]*(1-fc) + (*iPix[1][0])[i]*fc) * (1-fr) - + ((*iPix[0][1])[i]*(1-fc) + (*iPix[1][1])[i]*fc) * fr); - else - // Shortcut some floating point work if outside image. - pixValue = bgcolor[i]; - - if (bitDepth > 8) - oPix16[col][i] = pixValue; - else - oPix8[col][i] = pixValue >> 8; - } - } -} - -/* - * Rotate an 8 or 16 bits per color image 0-90 degrees. The output pixel is - * calculated as a weighted average of the 4 nearest input pixels. - */ -void ufraw_rotate_image_buffer(ufraw_image_data *img, double angle) -{ - double sine, cosine, movecol, moverow; - int oldwidth, oldheight, oldrowstride; - int width, height, depth, rowstride; - int col, row, uc, ur, i; - float c, r, fc, fr; - guint8 *in, *in_00, *in_01, *in_10, *in_11, *out; - - if (!angle) - return; - ufraw_image_format(NULL, NULL, img, "36", G_STRFUNC); - sine = sin(angle * 2 * M_PI / 360); - cosine = cos(angle * 2 * M_PI / 360); - depth = img->depth; - oldwidth = img->width; - oldheight = img->height; - oldrowstride = img->rowstride; - width = ceil((oldheight * sine) + (oldwidth * cosine)); - height = ceil((oldwidth * sine) + (oldheight * cosine)); - rowstride = width * depth; - in = img->buffer; - out = g_new0(guint8, height * rowstride); - img->buffer = out; - img->width = width; - img->height = height; - img->rowstride = rowstride; - movecol = -oldheight * sine * cosine; - moverow = oldheight * sine * sine; - for (row = 0; row < height; ++row) { - for (col = 0; col < width; col++) { - // (c,r) are the float input subpixel coordinates. fc,fr are the - // weighting factors for integer coordinates (uc,ur)..(uc+1,ur+1) - // around (c,r) - c = (col * cosine) + (row * sine) + movecol; - r = (row * cosine) - (col * sine) + moverow; - uc = (int)floor(c); - ur = (int)floor(r); - if (uc >= 0 && uc + 1 < oldwidth && ur >= 0 && ur + 1 < oldheight) { - fc = c - uc; - fr = r - ur; - in_00 = in + ((ur * oldwidth) + uc) * depth; // (uc,ur) - in_01 = in_00 + depth; // (uc+1,ur) - in_10 = in_00 + oldrowstride; // (uc,ur+1) - in_11 = in_10 + depth; // (uc+1,ur+1) - if (depth > 4) { - for (i = 0; i < 3; ++i) { - ((guint16 *)out)[i] = - (((guint16 *)in_00)[i] * (1 - fc) + ((guint16 *)in_01)[i] * fc) * (1 - fr) + - (((guint16 *)in_10)[i] * (1 - fc) + ((guint16 *)in_11)[i] * fc) * fr; - } - } else { - for (i = 0; i < 3; ++i) { - out[i] = - (in_00[i] * (1 - fc) + in_01[i] * fc) * (1 - fr) + - (in_10[i] * (1 - fc) + in_11[i] * fc) * fr; - } - } - } - out += depth; - } - } - g_free(in); -} Index: ufraw_preview.c =================================================================== RCS file: /cvsroot/ufraw/ufraw/ufraw_preview.c,v retrieving revision 1.307 retrieving revision 1.308 diff -u -d -r1.307 -r1.308 --- ufraw_preview.c 11 Nov 2009 02:20:57 -0000 1.307 +++ ufraw_preview.c 21 Nov 2009 05:51:59 -0000 1.308 @@ -36,9 +36,6 @@ void ufraw_chooser_toggle(GtkToggleButton *button, GtkFileChooser *filechooser); #endif -/* We do the rotate so we define the layer where it's done */ -#define ufraw_rotate_phase ufraw_first_phase - static void adjustment_update(GtkAdjustment *adj, double *valuep); static void button_update(GtkWidget *button, gpointer user_data); @@ -869,6 +866,7 @@ [CFG->profileIndex[display_profile]].productName); } ufraw_developer_prepare(data->UF, display_developer); + ufraw_convert_prepare_buffers(data->UF); /* The reset of the rendering can be triggered only after the call to * ufraw_developer_preare(). Otherwise error messages in this function @@ -1062,14 +1060,8 @@ if (data->FreezeDialog) return FALSE; - if (ufraw_invalidate_layer_event(data->UF, ufraw_first_phase)) { + if (ufraw_invalidate_layer_event(data->UF, ufraw_transform_phase)) { render_init(data); -#ifdef HAVE_LENSFUN - /* Vignetting is done in the first phase */ - ufraw_prepare_lensfun(data->UF, ufraw_lensfun_phase); - } else if (ufraw_invalidate_layer_event(data->UF, ufraw_lensfun_phase)) { - ufraw_prepare_lensfun(data->UF, ufraw_lensfun_phase); -#endif } #ifdef _OPENMP #pragma omp parallel shared(chosen,data) reduction(||:again) @@ -3012,9 +3004,20 @@ gboolean FullCrop = CFG->CropX1==0 && CFG->CropX2==data->UF->rotatedWidth && CFG->CropY1==0 && CFG->CropY2==data->UF->rotatedHeight; + int oldFlip = CFG->orientation; ufraw_unnormalize_rotation(data->UF); CFG->rotationAngle = gtk_adjustment_get_value(data->RotationAdjustment); ufraw_normalize_rotation(data->UF); + int newFlip = CFG->orientation; + int flip; + for (flip=0; flip<8; flip++) { + CFG->orientation = oldFlip; + ufraw_flip_orientation(data->UF, flip); + if (CFG->orientation == newFlip) + break; + } + CFG->orientation = oldFlip; + ufraw_flip_image(data->UF, flip); gtk_widget_set_sensitive(data->ResetRotationAdjustment, CFG->rotationAngle != 0 || CFG->orientation != CFG->CameraOrientation); @@ -3062,7 +3065,7 @@ data->SpotY1 = -1; data->SpotY2 = -1; } - ufraw_invalidate_layer(data->UF, ufraw_rotate_phase); + ufraw_invalidate_layer(data->UF, ufraw_transform_phase); /* render_init() will resize the pixbuf when it detects that the future * final image will get a different size. This is required for @@ -3086,6 +3089,8 @@ preview_data *data = get_preview_data(widget); (void)user_data; + int oldOrientation = CFG->orientation; + double oldAngle = CFG->rotationAngle; CFG->orientation = CFG->CameraOrientation; CFG->rotationAngle = 0; @@ -3094,6 +3099,8 @@ gtk_adjustment_set_value(data->RotationAdjustment, CFG->rotationAngle); ufraw_normalize_rotation(data->UF); data->FreezeDialog--; + CFG->orientation = oldOrientation; + CFG->rotationAngle = oldAngle; gtk_adjustment_value_changed(data->RotationAdjustment); } ------------------------------------------------------------------------------ Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july _______________________________________________ ufraw-cvs mailing list ufraw-cvs@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/ufraw-cvs